brintos

brintos / llvm-project-archived public Read only

0
0
Text · 29.0 KiB · 38e8278 Raw
839 lines · python
1"""2LLDB Formatters for MLIR data types.3 4Load into LLDB with 'command script import /path/to/mlirDataFormatters.py'5"""6 7import re8import lldb9 10 11def get_expression_path(val: lldb.SBValue):12    """Compute the expression path for the given value."""13 14    stream = lldb.SBStream()15    if not val.GetExpressionPath(stream):16        return None17    return stream.GetData()18 19 20def build_ptr_str_from_addr(addrValue: lldb.SBValue, type: lldb.SBType):21    """Build a string that computes a pointer using the given address value and type."""22 23    if type.is_reference:24        type = type.GetDereferencedType()25    if not type.is_pointer:26        type = type.GetPointerType()27    return f"(({type}){addrValue.GetData().GetUnsignedInt64(lldb.SBError(), 0)})"28 29 30# ===----------------------------------------------------------------------=== #31# Attributes and Types32# ===----------------------------------------------------------------------=== #33 34# This variable defines various mnemonic strings for use by the builtin35# dialect attributes and types, which often have special formatting within36# the parser/printer.37builtin_attr_type_mnemonics = {38    "mlir::AffineMapAttr": '"affine_map<...>"',39    "mlir::ArrayAttr": '"[...]"',40    "mlir::DenseArray": '"array<...>"',41    "mlir::DenseResourceElementsAttr": '"dense_resource<...>"',42    "mlir::DictionaryAttr": '"{...}"',43    "mlir::IntegerAttr": '"float"',44    "mlir::IntegerAttr": '"integer"',45    "mlir::IntegerSetAttr": '"affine_set<...>"',46    "mlir::SparseElementsAttr": '"sparse<...>"',47    "mlir::StringAttr": '""...""',48    "mlir::StridedLayout": '"strided_layout"',49    "mlir::UnitAttr": '"unit"',50    "mlir::CallSiteLoc": '"loc(callsite(...))"',51    "mlir::FusedLoc": '"loc(fused<...>[...])"',52    "mlir::UnknownLoc": '"loc(unknown)"',53    "mlir::Float4E2M1FNType": '"f4E2M1FN"',54    "mlir::Float6E2M3FNType": '"f6E2M3FN"',55    "mlir::Float6E3M2FNType": '"f6E3M2FN"',56    "mlir::Float8E5M2Type": '"f8E5M2"',57    "mlir::Float8E4M3Type": '"f8E4M3"',58    "mlir::Float8E4M3FNType": '"f8E4M3FN"',59    "mlir::Float8E5M2FNUZType": '"f8E5M2FNUZ"',60    "mlir::Float8E4M3FNUZType": '"f8E4M3FNUZ"',61    "mlir::Float8E4M3B11FNUZType": '"f8E4M3B11FNUZ"',62    "mlir::Float8E3M4Type": '"f8E3M4"',63    "mlir::Float8E8M0FNUType": '"f8E8M0FNU"',64    "mlir::BFloat16Type": '"bf16"',65    "mlir::Float16Type": '"f16"',66    "mlir::FloatTF32Type": '"tf32"',67    "mlir::Float32Type": '"f32"',68    "mlir::Float64Type": '"f64"',69    "mlir::Float80Type": '"f80"',70    "mlir::Float128Type": '"f128"',71    "mlir::FunctionType": '"(...) -> (...)"',72    "mlir::IndexType": '"index"',73    "mlir::IntegerType": '"iN"',74    "mlir::NoneType": '"none"',75    "mlir::TupleType": '"tuple<...>"',76    "mlir::MemRefType": '"memref<...>"',77    "mlir::UnrankedMemRef": '"memref<...>"',78    "mlir::UnrankedTensorType": '"tensor<...>"',79    "mlir::RankedTensorType": '"tensor<...>"',80    "mlir::VectorType": '"vector<...>"',81}82 83 84class ComputedTypeIDMap:85    """Compute a map of type ids to derived attributes, types, and locations.86 87    This is necessary for determining the C++ type when holding a base class,88    where we really only have access to dynamic information.89    """90 91    def __init__(self, target: lldb.SBTarget, internal_dict: dict):92        self.resolved_typeids = {}93 94        # Find all of the `id` variables, which are the name of TypeID variables95        # defined within the TypeIDResolver.96        type_ids = target.FindGlobalVariables("id", lldb.UINT32_MAX)97        for type_id in type_ids:98            # Strip out any matches that didn't come from a TypeID resolver. This99            # also lets us extract the derived type name.100            name = type_id.GetName()101            match = re.search("^mlir::detail::TypeIDResolver<(.*), void>::id$", name)102            if not match:103                continue104            type_name = match.group(1)105 106            # Filter out types that we don't care about.107            if not type_name.endswith(("Attr", "Loc", "Type")):108                continue109 110            # Find the LLDB type for the derived type.111            type = None112            for typeIt in target.FindTypes(type_name):113                if not typeIt or not typeIt.IsValid():114                    continue115                type = typeIt116                break117            if not type or not type.IsValid():118                continue119 120            # Map the raw address of the type id variable to the LLDB type.121            self.resolved_typeids[type_id.AddressOf().GetValueAsUnsigned()] = type122 123    # Resolve the type for the given TypeID address.124    def resolve_type(self, typeIdAddr: lldb.SBValue):125        try:126            return self.resolved_typeids[typeIdAddr.GetValueAsUnsigned()]127        except KeyError:128            return None129 130 131def is_derived_attribute_or_type(sbtype: lldb.SBType, internal_dict):132    """Return if the given type is a derived attribute or type."""133 134    # We only expect an AttrBase/TypeBase base class.135    if sbtype.num_bases != 1:136        return False137    base_name = sbtype.GetDirectBaseClassAtIndex(0).GetName()138    return base_name.startswith(("mlir::Attribute::AttrBase", "mlir::Type::TypeBase"))139 140 141def get_typeid_map(target: lldb.SBTarget, internal_dict: dict):142    """Get or construct a TypeID map for the given target."""143 144    if "typeIdMap" not in internal_dict:145        internal_dict["typeIdMap"] = ComputedTypeIDMap(target, internal_dict)146    return internal_dict["typeIdMap"]147 148 149def is_attribute_or_type(sbtype: lldb.SBType, internal_dict):150    """Return if the given type is an attribute or type."""151 152    num_bases = sbtype.GetNumberOfDirectBaseClasses()153    typeName = sbtype.GetName()154 155    # We bottom out at Attribute/Type/Location.156    if num_bases == 0:157        return typeName in ["mlir::Attribute", "mlir::Type", "mlir::Location"]158 159    # Check the easy cases of AttrBase/TypeBase.160    if typeName.startswith(("mlir::Attribute::AttrBase", "mlir::Type::TypeBase")):161        return True162 163    # Otherwise, recurse into the base class.164    return is_attribute_or_type(165        sbtype.GetDirectBaseClassAtIndex(0).GetType(), internal_dict166    )167 168 169def resolve_attr_type_from_value(170    valobj: lldb.SBValue, abstractVal: lldb.SBValue, internal_dict171):172    """Resolve the derived C++ type of an Attribute/Type value."""173 174    # Derived attribute/types already have the desired type.175    if is_derived_attribute_or_type(valobj.GetType(), internal_dict):176        return valobj.GetType()177 178    # Otherwise, we need to resolve the ImplTy from the TypeID. This is179    # done dynamically, because we don't use C++ RTTI of any kind.180    typeIdMap = get_typeid_map(valobj.GetTarget(), internal_dict)181    return typeIdMap.resolve_type(182        abstractVal.GetChildMemberWithName("typeID").GetChildMemberWithName("storage")183    )184 185 186class AttrTypeSynthProvider:187    """Define an LLDB synthetic children provider for Attributes and Types."""188 189    def __init__(self, valobj: lldb.SBValue, internal_dict):190        self.valobj = valobj191 192        # Grab the impl variable, which if this is a Location needs to be193        # resolved through the LocationAttr impl variable.194        impl: lldb.SBValue = self.valobj.GetChildMemberWithName("impl")195        if self.valobj.GetTypeName() == "mlir::Location":196            impl = impl.GetChildMemberWithName("impl")197        self.abstractVal = impl.GetChildMemberWithName("abstractType")198        if not self.abstractVal.IsValid():199            self.abstractVal = impl.GetChildMemberWithName("abstractAttribute")200 201        self.type = resolve_attr_type_from_value(202            valobj, self.abstractVal, internal_dict203        )204        if not self.type:205            self.impl_type = None206            return207 208        # Grab the ImplTy from the resolved type. This is the 3rd template209        # argument of the base class.210        self.impl_type = (211            self.type.GetDirectBaseClassAtIndex(0).GetType().GetTemplateArgumentType(2)212        )213        self.impl_pointer_ty = self.impl_type.GetPointerType()214        self.num_fields = self.impl_type.GetNumberOfFields()215 216        # Optionally add a mnemonic field.217        type_name = self.type.GetName()218        if type_name in builtin_attr_type_mnemonics:219            self.mnemonic = builtin_attr_type_mnemonics[type_name]220        elif type_name.startswith("mlir::Dense"):221            self.mnemonic = "dense<...>"222        else:223            self.mnemonic = self.valobj.CreateValueFromExpression(224                "mnemonic", f"(llvm::StringRef){type_name}::getMnemonic()"225            )226            if not self.mnemonic.summary:227                self.mnemonic = None228        if self.mnemonic:229            self.num_fields += 1230 231    def num_children(self):232        if not self.impl_type:233            return 0234        return self.num_fields235 236    def get_child_index(self, name):237        if not self.impl_type:238            return None239        if self.mnemonic and name == "[mnemonic]":240            return self.impl_type.GetNumberOfFields()241        for i in range(self.impl_type.GetNumberOfFields()):242            if self.impl_type.GetFieldAtIndex(i).GetName() == name:243                return i244        return None245 246    def get_child_at_index(self, index):247        if not self.impl_type or index >= self.num_fields:248            return None249 250        impl: lldb.SBValue = self.valobj.GetChildMemberWithName("impl")251        impl_ptr: lldb.SBValue = self.valobj.CreateValueFromData(252            build_ptr_str_from_addr(impl, self.impl_pointer_ty),253            impl.GetData(),254            self.impl_pointer_ty,255        )256 257        # Check for the mnemonic field.258        if index == self.impl_type.GetNumberOfFields():259            return self.valobj.CreateValueFromExpression(260                "[mnemonic]", self.get_mnemonic_string(impl_ptr)261            )262 263        # Otherwise, we expect the index to be a field.264        field: lldb.SBTypeMember = self.impl_type.GetFieldAtIndex(index)265 266        # Build the field access by resolving through the impl variable.267        return impl_ptr.GetChildMemberWithName(field.GetName())268 269    def get_mnemonic_string(self, impl_ptr: lldb.SBValue):270        if isinstance(self.mnemonic, str):271            return self.mnemonic272 273        # If we don't already have the mnemonic in string form, compute274        # it from the dialect name and the mnemonic.275        dialect_name = self.abstractVal.GetChildMemberWithName(276            "dialect"277        ).GetChildMemberWithName("name")278        self.mnemonic = f'{dialect_name.summary}"."{self.mnemonic.summary}'279        return self.mnemonic280 281 282def AttrTypeSummaryProvider(valobj: lldb.SBValue, internal_dict):283    """Define an LLDB summary provider for Attributes and Types."""284 285    # Check for a value field.286    value = valobj.GetChildMemberWithName("value")287    if value and value.summary:288        return value.summary289 290    # Otherwise, try the mnemoic.291    mnemonic: lldb.SBValue = valobj.GetChildMemberWithName("[mnemonic]")292    if not mnemonic.summary:293        return ""294    mnemonicStr = mnemonic.summary.strip('"')295 296    # Handle a few extremely common builtin attributes/types.297    ## IntegerType298    if mnemonicStr == "iN":299        signedness = valobj.GetChildMemberWithName("signedness").GetValueAsUnsigned()300        prefix = "i"301        if signedness == 1:302            prefix = "si"303        elif signedness == 2:304            prefix = "ui"305        return f"{prefix}{valobj.GetChildMemberWithName('width').GetValueAsUnsigned()}"306    ## IntegerAttr307    if mnemonicStr == "integer":308        value = valobj.GetChildMemberWithName("value")309        bitwidth = value.GetChildMemberWithName("BitWidth").GetValueAsUnsigned()310        if bitwidth <= 64:311            intVal = (312                value.GetChildMemberWithName("U")313                .GetChildMemberWithName("VAL")314                .GetValueAsUnsigned()315            )316 317            if bitwidth == 1:318                return "true" if intVal else "false"319            return f"{intVal} : i{bitwidth}"320 321    return mnemonicStr322 323 324# ===----------------------------------------------------------------------=== #325# mlir::Block326# ===----------------------------------------------------------------------=== #327 328 329class BlockSynthProvider:330    """Define an LLDB synthetic children provider for Blocks."""331 332    def __init__(self, valobj, internal_dict):333        self.valobj = valobj334 335    def num_children(self):336        return 3337 338    def get_child_index(self, name):339        if name == "parent":340            return 0341        if name == "operations":342            return 1343        if name == "arguments":344            return 2345        return None346 347    def get_child_at_index(self, index):348        if index >= 3:349            return None350        if index == 1:351            return self.valobj.GetChildMemberWithName("operations")352        if index == 2:353            return self.valobj.GetChildMemberWithName("arguments")354 355        expr_path = build_ptr_str_from_addr(self.valobj, self.valobj.GetType())356        return self.valobj.CreateValueFromExpression(357            "parent", f"{expr_path}->getParent()"358        )359 360 361# ===----------------------------------------------------------------------=== #362# mlir::Operation363# ===----------------------------------------------------------------------=== #364 365 366def is_op(sbtype: lldb.SBType, internal_dict):367    """Return if the given type is an operation."""368 369    # Bottom out at OpState/Op.370    typeName = sbtype.GetName()371    if sbtype.GetNumberOfDirectBaseClasses() == 0:372        return typeName == "mlir::OpState"373    if typeName == "mlir::Operation" or typeName.startswith("mlir::Op<"):374        return True375 376    # Otherwise, recurse into the base class.377    return is_op(sbtype.GetDirectBaseClassAtIndex(0).GetType(), internal_dict)378 379 380class OperationSynthProvider:381    """Define an LLDB synthetic children provider for Operations."""382 383    def __init__(self, valobj, internal_dict):384        self.valobj = valobj385        self.fields = []386        self.update()387 388    def num_children(self):389        return len(self.fields)390 391    def get_child_index(self, name):392        try:393            return self.fields.index(name)394        except ValueError:395            return None396 397    def get_child_at_index(self, index):398        if index >= len(self.fields):399            return None400        name = self.fields[index]401        if name == "name":402            return self.opobj.GetChildMemberWithName("name")403        if name == "parent":404            return self.opobj.GetChildMemberWithName("block").Clone("parent")405        if name == "location":406            return self.opobj.GetChildMemberWithName("location")407        if name == "attributes":408            return self.opobj.GetChildMemberWithName("attrs")409 410        expr_path = build_ptr_str_from_addr(self.opobj, self.opobj.GetType())411        if name == "operands":412            return self.opobj.CreateValueFromExpression(413                "operands", f"{expr_path}->debug_getOperands()"414            )415        if name == "results":416            return self.opobj.CreateValueFromExpression(417                "results", f"{expr_path}->debug_getResults()"418            )419        if name == "successors":420            return self.opobj.CreateValueFromExpression(421                "successors", f"{expr_path}->debug_getSuccessors()"422            )423        if name == "regions":424            return self.opobj.CreateValueFromExpression(425                "regions", f"{expr_path}->debug_getRegions()"426            )427        return None428 429    def update(self):430        # If this is a derived operation, we need to resolve through the431        # state field.432        self.opobj = self.valobj433        if "mlir::Operation" not in self.valobj.GetTypeName():434            self.opobj = self.valobj.GetChildMemberWithName("state")435 436        self.fields = ["parent", "name", "location", "attributes"]437        if (438            self.opobj.GetChildMemberWithName("hasOperandStorage").GetValueAsUnsigned(0)439            != 0440        ):441            self.fields.append("operands")442        if self.opobj.GetChildMemberWithName("numResults").GetValueAsUnsigned(0) != 0:443            self.fields.append("results")444        if self.opobj.GetChildMemberWithName("numSuccs").GetValueAsUnsigned(0) != 0:445            self.fields.append("successors")446        if self.opobj.GetChildMemberWithName("numRegions").GetValueAsUnsigned(0) != 0:447            self.fields.append("regions")448 449 450def OperationSummaryProvider(valobj: lldb.SBValue, internal_dict):451    """Define an LLDB summary provider for Operations."""452 453    name = valobj.GetChildMemberWithName("name")454    if name and name.summary:455        return name.summary456    return ""457 458 459# ===----------------------------------------------------------------------=== #460# Ranges461# ===----------------------------------------------------------------------=== #462 463 464class DirectRangeSynthProvider:465    """Define an LLDB synthetic children provider for direct ranges, i.e. those466    with a base pointer that points to the type of element we want to display.467    """468 469    def __init__(self, valobj, internal_dict):470        self.valobj = valobj471        self.update()472 473    def num_children(self):474        return self.length475 476    def get_child_index(self, name):477        try:478            return int(name.lstrip("[").rstrip("]"))479        except:480            return None481 482    def get_child_at_index(self, index):483        if index >= self.num_children():484            return None485        offset = index * self.type_size486        return self.data.CreateChildAtOffset(f"[{index}]", offset, self.data_type)487 488    def update(self):489        length_obj = self.valobj.GetChildMemberWithName("count")490        self.length = length_obj.GetValueAsUnsigned(0)491 492        self.data = self.valobj.GetChildMemberWithName("base")493        self.data_type = self.data.GetType().GetPointeeType()494        self.type_size = self.data_type.GetByteSize()495        assert self.type_size != 0496 497 498class InDirectRangeSynthProvider:499    """Define an LLDB synthetic children provider for ranges500    that transform the underlying base pointer, e.g. to convert501    it to a different type depending on various characteristics502    (e.g. mlir::ValueRange).503    """504 505    def __init__(self, valobj, internal_dict):506        self.valobj = valobj507        self.update()508 509    def num_children(self):510        return self.length511 512    def get_child_index(self, name):513        try:514            return int(name.lstrip("[").rstrip("]"))515        except:516            return None517 518    def get_child_at_index(self, index):519        if index >= self.num_children():520            return None521        expr_path = get_expression_path(self.valobj)522        return self.valobj.CreateValueFromExpression(523            f"[{index}]", f"{expr_path}[{index}]"524        )525 526    def update(self):527        length_obj = self.valobj.GetChildMemberWithName("count")528        self.length = length_obj.GetValueAsUnsigned(0)529 530 531class IPListRangeSynthProvider:532    """Define an LLDB synthetic children provider for an IPList."""533 534    def __init__(self, valobj, internal_dict):535        self.valobj = valobj536        self.update()537 538    def num_children(self):539        sentinel = self.valobj.GetChildMemberWithName("Sentinel")540        sentinel_addr = sentinel.AddressOf().GetValueAsUnsigned(0)541 542        # Iterate the next pointers looking for the sentinel.543        count = 0544        current = sentinel.GetChildMemberWithName("Next")545        while current.GetValueAsUnsigned(0) != sentinel_addr:546            current = current.GetChildMemberWithName("Next")547            count += 1548 549        return count550 551    def get_child_index(self, name):552        try:553            return int(name.lstrip("[").rstrip("]"))554        except:555            return None556 557    def get_child_at_index(self, index):558        if index >= self.num_children():559            return None560 561        # Start from the sentinel and grab the next pointer.562        value: lldb.SBValue = self.valobj.GetChildMemberWithName("Sentinel")563        it = 0564        while it <= index:565            value = value.GetChildMemberWithName("Next")566            it += 1567 568        return value.CreateValueFromExpression(569            f"[{index}]",570            f"(({self.value_type})({value.GetTypeName()}){value.GetValueAsUnsigned()})",571        )572 573    def update(self):574        self.value_type = (575            self.valobj.GetType().GetTemplateArgumentType(0).GetPointerType()576        )577 578 579# ===----------------------------------------------------------------------=== #580# mlir::Value581# ===----------------------------------------------------------------------=== #582 583 584class ValueSynthProvider:585    """Define an LLDB synthetic children provider for Values."""586 587    def __init__(self, valobj, internal_dict):588        self.valobj = valobj589        self.update()590 591    def num_children(self):592        # 7: BlockArgument:593        #  index, type, owner, firstUse, location594        if self.kind == 7:595            return 5596 597        # 0-6: OpResult:598        #  index, type, owner, firstUse599        return 4600 601    def get_child_index(self, name):602        if name == "index":603            return 0604        if name == "type":605            return 1606        if name == "owner":607            return 2608        if name == "firstUse":609            return 3610        if name == "location":611            return 4612        return None613 614    def get_child_at_index(self, index):615        if index >= self.num_children():616            return None617 618        # Check if the current value is already an Impl struct.619        if self.valobj.GetTypeName().endswith("Impl"):620            impl_ptr_str = build_ptr_str_from_addr(621                self.valobj.AddressOf(), self.valobj.GetType().GetPointerType()622            )623        else:624            impl = self.valobj.GetChildMemberWithName("impl")625            impl_ptr_str = build_ptr_str_from_addr(impl, impl.GetType())626 627        # Cast to the derived Impl type.628        if self.kind == 7:629            derived_impl_str = f"((mlir::detail::BlockArgumentImpl *){impl_ptr_str})"630        elif self.kind == 6:631            derived_impl_str = f"((mlir::detail::OutOfLineOpResult *){impl_ptr_str})"632        else:633            derived_impl_str = f"((mlir::detail::InlineOpResult *){impl_ptr_str})"634 635        # Handle the shared fields when possible.636        if index == 1:637            return self.valobj.CreateValueFromExpression(638                "type", f"{derived_impl_str}->debug_getType()"639            )640        if index == 3:641            return self.valobj.CreateValueFromExpression(642                "firstUse", f"{derived_impl_str}->firstUse"643            )644 645        # Handle Block argument children.646        if self.kind == 7:647            impl = self.valobj.CreateValueFromExpression("impl", derived_impl_str)648            if index == 0:649                return impl.GetChildMemberWithName("index")650            if index == 2:651                return impl.GetChildMemberWithName("owner")652            if index == 4:653                return impl.GetChildMemberWithName("loc")654 655        # Handle OpResult children.656        if index == 0:657            # Handle the out of line case.658            if self.kind == 6:659                return self.valobj.CreateValueFromExpression(660                    "index", f"{derived_impl_str}->outOfLineIndex + 6"661                )662            return self.valobj.CreateValueFromExpression("index", f"{self.kind}")663        if index == 2:664            return self.valobj.CreateValueFromExpression(665                "owner", f"{derived_impl_str}->getOwner()"666            )667        return None668 669    def update(self):670        # Check if the current value is already an Impl struct.671        if self.valobj.GetTypeName().endswith("Impl"):672            impl_ptr_str = build_ptr_str_from_addr(673                self.valobj, self.valobj.GetType().GetPointerType()674            )675        else:676            impl = self.valobj.GetChildMemberWithName("impl")677            impl_ptr_str = build_ptr_str_from_addr(impl, impl.GetType())678 679        # Compute the kind of value we are dealing with.680        self.kind = self.valobj.CreateValueFromExpression(681            "kind", f"{impl_ptr_str}->debug_getKind()"682        ).GetValueAsUnsigned()683 684 685def ValueSummaryProvider(valobj: lldb.SBValue, internal_dict):686    """Define an LLDB summary provider for Values."""687 688    index = valobj.GetChildMemberWithName("index").GetValueAsUnsigned()689    # Check if this is a block argument or not (block arguments have locations).690    if valobj.GetChildMemberWithName("location").IsValid():691        summary = f"Block Argument {index}"692    else:693        owner_name = (694            valobj.GetChildMemberWithName("owner")695            .GetChildMemberWithName("name")696            .summary697        )698        summary = f"{owner_name} Result {index}"699 700    # Grab the type to help form the summary.701    type = valobj.GetChildMemberWithName("type")702    if type.summary:703        summary += f": {type.summary}"704 705    return summary706 707 708# ===----------------------------------------------------------------------=== #709# Initialization710# ===----------------------------------------------------------------------=== #711 712 713def __lldb_init_module(debugger: lldb.SBDebugger, internal_dict):714    cat: lldb.SBTypeCategory = debugger.CreateCategory("mlir")715    cat.SetEnabled(True)716 717    # Attributes and Types718    cat.AddTypeSummary(719        lldb.SBTypeNameSpecifier(720            "mlirDataFormatters.is_attribute_or_type", lldb.eFormatterMatchCallback721        ),722        lldb.SBTypeSummary.CreateWithFunctionName(723            "mlirDataFormatters.AttrTypeSummaryProvider"724        ),725    )726    cat.AddTypeSynthetic(727        lldb.SBTypeNameSpecifier(728            "mlirDataFormatters.is_attribute_or_type", lldb.eFormatterMatchCallback729        ),730        lldb.SBTypeSynthetic.CreateWithClassName(731            "mlirDataFormatters.AttrTypeSynthProvider"732        ),733    )734 735    # Operation736    cat.AddTypeSynthetic(737        lldb.SBTypeNameSpecifier("mlir::Block", lldb.eFormatterMatchExact),738        lldb.SBTypeSynthetic.CreateWithClassName(739            "mlirDataFormatters.BlockSynthProvider"740        ),741    )742 743    # NamedAttribute744    cat.AddTypeSummary(745        lldb.SBTypeNameSpecifier("mlir::NamedAttribute", lldb.eFormatterMatchExact),746        lldb.SBTypeSummary.CreateWithSummaryString("${var.name%S} = ${var.value%S}"),747    )748 749    # OperationName750    cat.AddTypeSummary(751        lldb.SBTypeNameSpecifier("mlir::OperationName", lldb.eFormatterMatchExact),752        lldb.SBTypeSummary.CreateWithSummaryString("${var.impl->name%S}"),753    )754 755    # Operation756    cat.AddTypeSummary(757        lldb.SBTypeNameSpecifier(758            "mlirDataFormatters.is_op", lldb.eFormatterMatchCallback759        ),760        lldb.SBTypeSummary.CreateWithFunctionName(761            "mlirDataFormatters.OperationSummaryProvider"762        ),763    )764    cat.AddTypeSynthetic(765        lldb.SBTypeNameSpecifier(766            "mlirDataFormatters.is_op", lldb.eFormatterMatchCallback767        ),768        lldb.SBTypeSynthetic.CreateWithClassName(769            "mlirDataFormatters.OperationSynthProvider"770        ),771    )772 773    # Ranges774    def add_direct_range_summary_and_synth(name):775        cat.AddTypeSummary(776            lldb.SBTypeNameSpecifier(name, lldb.eFormatterMatchExact),777            lldb.SBTypeSummary.CreateWithSummaryString("size=${svar%#}"),778        )779        cat.AddTypeSynthetic(780            lldb.SBTypeNameSpecifier(name, lldb.eFormatterMatchExact),781            lldb.SBTypeSynthetic.CreateWithClassName(782                "mlirDataFormatters.DirectRangeSynthProvider"783            ),784        )785 786    def add_indirect_range_summary_and_synth(name):787        cat.AddTypeSummary(788            lldb.SBTypeNameSpecifier(name, lldb.eFormatterMatchExact),789            lldb.SBTypeSummary.CreateWithSummaryString("size=${svar%#}"),790        )791        cat.AddTypeSynthetic(792            lldb.SBTypeNameSpecifier(name, lldb.eFormatterMatchExact),793            lldb.SBTypeSynthetic.CreateWithClassName(794                "mlirDataFormatters.InDirectRangeSynthProvider"795            ),796        )797 798    def add_iplist_range_summary_and_synth(name):799        cat.AddTypeSummary(800            lldb.SBTypeNameSpecifier(name, lldb.eFormatterMatchExact),801            lldb.SBTypeSummary.CreateWithSummaryString("size=${svar%#}"),802        )803        cat.AddTypeSynthetic(804            lldb.SBTypeNameSpecifier(name, lldb.eFormatterMatchExact),805            lldb.SBTypeSynthetic.CreateWithClassName(806                "mlirDataFormatters.IPListRangeSynthProvider"807            ),808        )809 810    add_direct_range_summary_and_synth("mlir::Operation::operand_range")811    add_direct_range_summary_and_synth("mlir::OperandRange")812    add_direct_range_summary_and_synth("mlir::Operation::result_range")813    add_direct_range_summary_and_synth("mlir::ResultRange")814    add_direct_range_summary_and_synth("mlir::SuccessorRange")815    add_indirect_range_summary_and_synth("mlir::ValueRange")816    add_indirect_range_summary_and_synth("mlir::TypeRange")817    add_iplist_range_summary_and_synth("mlir::Block::OpListType")818    add_iplist_range_summary_and_synth("mlir::Region::BlockListType")819 820    # Values821    def add_value_summary_and_synth(name):822        cat.AddTypeSummary(823            lldb.SBTypeNameSpecifier(name, lldb.eFormatterMatchExact),824            lldb.SBTypeSummary.CreateWithFunctionName(825                "mlirDataFormatters.ValueSummaryProvider"826            ),827        )828        cat.AddTypeSynthetic(829            lldb.SBTypeNameSpecifier(name, lldb.eFormatterMatchExact),830            lldb.SBTypeSynthetic.CreateWithClassName(831                "mlirDataFormatters.ValueSynthProvider"832            ),833        )834 835    add_value_summary_and_synth("mlir::BlockArgument")836    add_value_summary_and_synth("mlir::Value")837    add_value_summary_and_synth("mlir::OpResult")838    add_value_summary_and_synth("mlir::detail::OpResultImpl")839