xref: /llvm-project/mlir/utils/lldb-scripts/mlirDataFormatters.py (revision 3f9cabae0029bcbe88835aaa4c417ce41e584fb1)
162fec084SRiver Riddle"""
262fec084SRiver RiddleLLDB Formatters for MLIR data types.
362fec084SRiver Riddle
462fec084SRiver RiddleLoad into LLDB with 'command script import /path/to/mlirDataFormatters.py'
562fec084SRiver Riddle"""
662fec084SRiver Riddle
762fec084SRiver Riddleimport re
862fec084SRiver Riddleimport lldb
962fec084SRiver Riddle
1062fec084SRiver Riddle
1162fec084SRiver Riddledef get_expression_path(val: lldb.SBValue):
1262fec084SRiver Riddle    """Compute the expression path for the given value."""
1362fec084SRiver Riddle
1462fec084SRiver Riddle    stream = lldb.SBStream()
1562fec084SRiver Riddle    if not val.GetExpressionPath(stream):
1662fec084SRiver Riddle        return None
1762fec084SRiver Riddle    return stream.GetData()
1862fec084SRiver Riddle
1962fec084SRiver Riddle
2062fec084SRiver Riddledef build_ptr_str_from_addr(addrValue: lldb.SBValue, type: lldb.SBType):
2162fec084SRiver Riddle    """Build a string that computes a pointer using the given address value and type."""
2262fec084SRiver Riddle
2362fec084SRiver Riddle    if type.is_reference:
2462fec084SRiver Riddle        type = type.GetDereferencedType()
2562fec084SRiver Riddle    if not type.is_pointer:
2662fec084SRiver Riddle        type = type.GetPointerType()
2762fec084SRiver Riddle    return f"(({type}){addrValue.GetData().GetUnsignedInt64(lldb.SBError(), 0)})"
2862fec084SRiver Riddle
2962fec084SRiver Riddle
3062fec084SRiver Riddle# ===----------------------------------------------------------------------=== #
3162fec084SRiver Riddle# Attributes and Types
3262fec084SRiver Riddle# ===----------------------------------------------------------------------=== #
3362fec084SRiver Riddle
3462fec084SRiver Riddle# This variable defines various mnemonic strings for use by the builtin
3562fec084SRiver Riddle# dialect attributes and types, which often have special formatting within
3662fec084SRiver Riddle# the parser/printer.
3762fec084SRiver Riddlebuiltin_attr_type_mnemonics = {
3862fec084SRiver Riddle    "mlir::AffineMapAttr": '"affine_map<...>"',
3962fec084SRiver Riddle    "mlir::ArrayAttr": '"[...]"',
4062fec084SRiver Riddle    "mlir::DenseArray": '"array<...>"',
4162fec084SRiver Riddle    "mlir::DenseResourceElementsAttr": '"dense_resource<...>"',
4262fec084SRiver Riddle    "mlir::DictionaryAttr": '"{...}"',
4362fec084SRiver Riddle    "mlir::IntegerAttr": '"float"',
4462fec084SRiver Riddle    "mlir::IntegerAttr": '"integer"',
4562fec084SRiver Riddle    "mlir::IntegerSetAttr": '"affine_set<...>"',
4662fec084SRiver Riddle    "mlir::SparseElementsAttr": '"sparse<...>"',
4762fec084SRiver Riddle    "mlir::StringAttr": '""...""',
4862fec084SRiver Riddle    "mlir::StridedLayout": '"strided_layout"',
4962fec084SRiver Riddle    "mlir::UnitAttr": '"unit"',
5062fec084SRiver Riddle    "mlir::CallSiteLoc": '"loc(callsite(...))"',
5162fec084SRiver Riddle    "mlir::FusedLoc": '"loc(fused<...>[...])"',
5262fec084SRiver Riddle    "mlir::UnknownLoc": '"loc(unknown)"',
532c580634SSergey Kozub    "mlir::Float4E2M1FNType": '"f4E2M1FN"',
5473d83f20SSergey Kozub    "mlir::Float6E2M3FNType": '"f6E2M3FN"',
55918222baSSergey Kozub    "mlir::Float6E3M2FNType": '"f6E3M2FN"',
5662fec084SRiver Riddle    "mlir::Float8E5M2Type": '"f8E5M2"',
57019136e3SAlexander Pivovarov    "mlir::Float8E4M3Type": '"f8E4M3"',
5862fec084SRiver Riddle    "mlir::Float8E4M3FNType": '"f8E4M3FN"',
5996267b6bSJake Hall    "mlir::Float8E5M2FNUZType": '"f8E5M2FNUZ"',
6096267b6bSJake Hall    "mlir::Float8E4M3FNUZType": '"f8E4M3FNUZ"',
612f086f26SDavid Majnemer    "mlir::Float8E4M3B11FNUZType": '"f8E4M3B11FNUZ"',
62eef1d7e3SAlexander Pivovarov    "mlir::Float8E3M4Type": '"f8E3M4"',
63*3f9cabaeSSergey Kozub    "mlir::Float8E8M0FNUType": '"f8E8M0FNU"',
6462fec084SRiver Riddle    "mlir::BFloat16Type": '"bf16"',
6562fec084SRiver Riddle    "mlir::Float16Type": '"f16"',
666685fd82SJeremy Furtek    "mlir::FloatTF32Type": '"tf32"',
6762fec084SRiver Riddle    "mlir::Float32Type": '"f32"',
6862fec084SRiver Riddle    "mlir::Float64Type": '"f64"',
6962fec084SRiver Riddle    "mlir::Float80Type": '"f80"',
7062fec084SRiver Riddle    "mlir::Float128Type": '"f128"',
7162fec084SRiver Riddle    "mlir::FunctionType": '"(...) -> (...)"',
7262fec084SRiver Riddle    "mlir::IndexType": '"index"',
7362fec084SRiver Riddle    "mlir::IntegerType": '"iN"',
7462fec084SRiver Riddle    "mlir::NoneType": '"none"',
7562fec084SRiver Riddle    "mlir::TupleType": '"tuple<...>"',
7662fec084SRiver Riddle    "mlir::MemRefType": '"memref<...>"',
7762fec084SRiver Riddle    "mlir::UnrankedMemRef": '"memref<...>"',
7862fec084SRiver Riddle    "mlir::UnrankedTensorType": '"tensor<...>"',
7962fec084SRiver Riddle    "mlir::RankedTensorType": '"tensor<...>"',
8062fec084SRiver Riddle    "mlir::VectorType": '"vector<...>"',
8162fec084SRiver Riddle}
8262fec084SRiver Riddle
8362fec084SRiver Riddle
8462fec084SRiver Riddleclass ComputedTypeIDMap:
8562fec084SRiver Riddle    """Compute a map of type ids to derived attributes, types, and locations.
8662fec084SRiver Riddle
8762fec084SRiver Riddle    This is necessary for determining the C++ type when holding a base class,
8862fec084SRiver Riddle    where we really only have access to dynamic information.
8962fec084SRiver Riddle    """
9062fec084SRiver Riddle
9162fec084SRiver Riddle    def __init__(self, target: lldb.SBTarget, internal_dict: dict):
9262fec084SRiver Riddle        self.resolved_typeids = {}
9362fec084SRiver Riddle
9462fec084SRiver Riddle        # Find all of the `id` variables, which are the name of TypeID variables
9562fec084SRiver Riddle        # defined within the TypeIDResolver.
9662fec084SRiver Riddle        type_ids = target.FindGlobalVariables("id", lldb.UINT32_MAX)
9762fec084SRiver Riddle        for type_id in type_ids:
9862fec084SRiver Riddle            # Strip out any matches that didn't come from a TypeID resolver. This
9962fec084SRiver Riddle            # also lets us extract the derived type name.
10062fec084SRiver Riddle            name = type_id.GetName()
10162fec084SRiver Riddle            match = re.search("^mlir::detail::TypeIDResolver<(.*), void>::id$", name)
10262fec084SRiver Riddle            if not match:
10362fec084SRiver Riddle                continue
10462fec084SRiver Riddle            type_name = match.group(1)
10562fec084SRiver Riddle
10662fec084SRiver Riddle            # Filter out types that we don't care about.
10762fec084SRiver Riddle            if not type_name.endswith(("Attr", "Loc", "Type")):
10862fec084SRiver Riddle                continue
10962fec084SRiver Riddle
11062fec084SRiver Riddle            # Find the LLDB type for the derived type.
11162fec084SRiver Riddle            type = None
11262fec084SRiver Riddle            for typeIt in target.FindTypes(type_name):
11362fec084SRiver Riddle                if not typeIt or not typeIt.IsValid():
11462fec084SRiver Riddle                    continue
11562fec084SRiver Riddle                type = typeIt
11662fec084SRiver Riddle                break
11762fec084SRiver Riddle            if not type or not type.IsValid():
11862fec084SRiver Riddle                continue
11962fec084SRiver Riddle
12062fec084SRiver Riddle            # Map the raw address of the type id variable to the LLDB type.
12162fec084SRiver Riddle            self.resolved_typeids[type_id.AddressOf().GetValueAsUnsigned()] = type
12262fec084SRiver Riddle
12362fec084SRiver Riddle    # Resolve the type for the given TypeID address.
12462fec084SRiver Riddle    def resolve_type(self, typeIdAddr: lldb.SBValue):
12562fec084SRiver Riddle        try:
12662fec084SRiver Riddle            return self.resolved_typeids[typeIdAddr.GetValueAsUnsigned()]
12762fec084SRiver Riddle        except KeyError:
12862fec084SRiver Riddle            return None
12962fec084SRiver Riddle
13062fec084SRiver Riddle
13162fec084SRiver Riddledef is_derived_attribute_or_type(sbtype: lldb.SBType, internal_dict):
13262fec084SRiver Riddle    """Return if the given type is a derived attribute or type."""
13362fec084SRiver Riddle
13462fec084SRiver Riddle    # We only expect an AttrBase/TypeBase base class.
13562fec084SRiver Riddle    if sbtype.num_bases != 1:
13662fec084SRiver Riddle        return False
13762fec084SRiver Riddle    base_name = sbtype.GetDirectBaseClassAtIndex(0).GetName()
13862fec084SRiver Riddle    return base_name.startswith(("mlir::Attribute::AttrBase", "mlir::Type::TypeBase"))
13962fec084SRiver Riddle
14062fec084SRiver Riddle
14162fec084SRiver Riddledef get_typeid_map(target: lldb.SBTarget, internal_dict: dict):
14262fec084SRiver Riddle    """Get or construct a TypeID map for the given target."""
14362fec084SRiver Riddle
14462fec084SRiver Riddle    if "typeIdMap" not in internal_dict:
14562fec084SRiver Riddle        internal_dict["typeIdMap"] = ComputedTypeIDMap(target, internal_dict)
14662fec084SRiver Riddle    return internal_dict["typeIdMap"]
14762fec084SRiver Riddle
14862fec084SRiver Riddle
14962fec084SRiver Riddledef is_attribute_or_type(sbtype: lldb.SBType, internal_dict):
15062fec084SRiver Riddle    """Return if the given type is an attribute or type."""
15162fec084SRiver Riddle
15262fec084SRiver Riddle    num_bases = sbtype.GetNumberOfDirectBaseClasses()
15362fec084SRiver Riddle    typeName = sbtype.GetName()
15462fec084SRiver Riddle
15562fec084SRiver Riddle    # We bottom out at Attribute/Type/Location.
15662fec084SRiver Riddle    if num_bases == 0:
15762fec084SRiver Riddle        return typeName in ["mlir::Attribute", "mlir::Type", "mlir::Location"]
15862fec084SRiver Riddle
15962fec084SRiver Riddle    # Check the easy cases of AttrBase/TypeBase.
16062fec084SRiver Riddle    if typeName.startswith(("mlir::Attribute::AttrBase", "mlir::Type::TypeBase")):
16162fec084SRiver Riddle        return True
16262fec084SRiver Riddle
16362fec084SRiver Riddle    # Otherwise, recurse into the base class.
16462fec084SRiver Riddle    return is_attribute_or_type(
16562fec084SRiver Riddle        sbtype.GetDirectBaseClassAtIndex(0).GetType(), internal_dict
16662fec084SRiver Riddle    )
16762fec084SRiver Riddle
16862fec084SRiver Riddle
16962fec084SRiver Riddledef resolve_attr_type_from_value(
17062fec084SRiver Riddle    valobj: lldb.SBValue, abstractVal: lldb.SBValue, internal_dict
17162fec084SRiver Riddle):
17262fec084SRiver Riddle    """Resolve the derived C++ type of an Attribute/Type value."""
17362fec084SRiver Riddle
17462fec084SRiver Riddle    # Derived attribute/types already have the desired type.
17562fec084SRiver Riddle    if is_derived_attribute_or_type(valobj.GetType(), internal_dict):
17662fec084SRiver Riddle        return valobj.GetType()
17762fec084SRiver Riddle
17862fec084SRiver Riddle    # Otherwise, we need to resolve the ImplTy from the TypeID. This is
17962fec084SRiver Riddle    # done dynamically, because we don't use C++ RTTI of any kind.
18062fec084SRiver Riddle    typeIdMap = get_typeid_map(valobj.GetTarget(), internal_dict)
18162fec084SRiver Riddle    return typeIdMap.resolve_type(
18262fec084SRiver Riddle        abstractVal.GetChildMemberWithName("typeID").GetChildMemberWithName("storage")
18362fec084SRiver Riddle    )
18462fec084SRiver Riddle
18562fec084SRiver Riddle
18662fec084SRiver Riddleclass AttrTypeSynthProvider:
18762fec084SRiver Riddle    """Define an LLDB synthetic children provider for Attributes and Types."""
18862fec084SRiver Riddle
18962fec084SRiver Riddle    def __init__(self, valobj: lldb.SBValue, internal_dict):
19062fec084SRiver Riddle        self.valobj = valobj
19162fec084SRiver Riddle
19262fec084SRiver Riddle        # Grab the impl variable, which if this is a Location needs to be
19362fec084SRiver Riddle        # resolved through the LocationAttr impl variable.
19462fec084SRiver Riddle        impl: lldb.SBValue = self.valobj.GetChildMemberWithName("impl")
19562fec084SRiver Riddle        if self.valobj.GetTypeName() == "mlir::Location":
19662fec084SRiver Riddle            impl = impl.GetChildMemberWithName("impl")
19762fec084SRiver Riddle        self.abstractVal = impl.GetChildMemberWithName("abstractType")
19862fec084SRiver Riddle        if not self.abstractVal.IsValid():
19962fec084SRiver Riddle            self.abstractVal = impl.GetChildMemberWithName("abstractAttribute")
20062fec084SRiver Riddle
20162fec084SRiver Riddle        self.type = resolve_attr_type_from_value(
20262fec084SRiver Riddle            valobj, self.abstractVal, internal_dict
20362fec084SRiver Riddle        )
20462fec084SRiver Riddle        if not self.type:
2059d106364SWalter Erquinigo            self.impl_type = None
20662fec084SRiver Riddle            return
20762fec084SRiver Riddle
20862fec084SRiver Riddle        # Grab the ImplTy from the resolved type. This is the 3rd template
20962fec084SRiver Riddle        # argument of the base class.
21062fec084SRiver Riddle        self.impl_type = (
21162fec084SRiver Riddle            self.type.GetDirectBaseClassAtIndex(0).GetType().GetTemplateArgumentType(2)
21262fec084SRiver Riddle        )
21362fec084SRiver Riddle        self.impl_pointer_ty = self.impl_type.GetPointerType()
21462fec084SRiver Riddle        self.num_fields = self.impl_type.GetNumberOfFields()
21562fec084SRiver Riddle
21662fec084SRiver Riddle        # Optionally add a mnemonic field.
21762fec084SRiver Riddle        type_name = self.type.GetName()
21862fec084SRiver Riddle        if type_name in builtin_attr_type_mnemonics:
21962fec084SRiver Riddle            self.mnemonic = builtin_attr_type_mnemonics[type_name]
22062fec084SRiver Riddle        elif type_name.startswith("mlir::Dense"):
22162fec084SRiver Riddle            self.mnemonic = "dense<...>"
22262fec084SRiver Riddle        else:
22362fec084SRiver Riddle            self.mnemonic = self.valobj.CreateValueFromExpression(
22462fec084SRiver Riddle                "mnemonic", f"(llvm::StringRef){type_name}::getMnemonic()"
22562fec084SRiver Riddle            )
22662fec084SRiver Riddle            if not self.mnemonic.summary:
22762fec084SRiver Riddle                self.mnemonic = None
22862fec084SRiver Riddle        if self.mnemonic:
22962fec084SRiver Riddle            self.num_fields += 1
23062fec084SRiver Riddle
23162fec084SRiver Riddle    def num_children(self):
23262fec084SRiver Riddle        if not self.impl_type:
23362fec084SRiver Riddle            return 0
23462fec084SRiver Riddle        return self.num_fields
23562fec084SRiver Riddle
23662fec084SRiver Riddle    def get_child_index(self, name):
23762fec084SRiver Riddle        if not self.impl_type:
23862fec084SRiver Riddle            return None
23962fec084SRiver Riddle        if self.mnemonic and name == "[mnemonic]":
24062fec084SRiver Riddle            return self.impl_type.GetNumberOfFields()
24162fec084SRiver Riddle        for i in range(self.impl_type.GetNumberOfFields()):
24262fec084SRiver Riddle            if self.impl_type.GetFieldAtIndex(i).GetName() == name:
24362fec084SRiver Riddle                return i
24462fec084SRiver Riddle        return None
24562fec084SRiver Riddle
24662fec084SRiver Riddle    def get_child_at_index(self, index):
24762fec084SRiver Riddle        if not self.impl_type or index >= self.num_fields:
24862fec084SRiver Riddle            return None
24962fec084SRiver Riddle
25062fec084SRiver Riddle        impl: lldb.SBValue = self.valobj.GetChildMemberWithName("impl")
25162fec084SRiver Riddle        impl_ptr: lldb.SBValue = self.valobj.CreateValueFromData(
25262fec084SRiver Riddle            build_ptr_str_from_addr(impl, self.impl_pointer_ty),
25362fec084SRiver Riddle            impl.GetData(),
25462fec084SRiver Riddle            self.impl_pointer_ty,
25562fec084SRiver Riddle        )
25662fec084SRiver Riddle
25762fec084SRiver Riddle        # Check for the mnemonic field.
25862fec084SRiver Riddle        if index == self.impl_type.GetNumberOfFields():
25962fec084SRiver Riddle            return self.valobj.CreateValueFromExpression(
26062fec084SRiver Riddle                "[mnemonic]", self.get_mnemonic_string(impl_ptr)
26162fec084SRiver Riddle            )
26262fec084SRiver Riddle
26362fec084SRiver Riddle        # Otherwise, we expect the index to be a field.
26462fec084SRiver Riddle        field: lldb.SBTypeMember = self.impl_type.GetFieldAtIndex(index)
26562fec084SRiver Riddle
26662fec084SRiver Riddle        # Build the field access by resolving through the impl variable.
26762fec084SRiver Riddle        return impl_ptr.GetChildMemberWithName(field.GetName())
26862fec084SRiver Riddle
26962fec084SRiver Riddle    def get_mnemonic_string(self, impl_ptr: lldb.SBValue):
27062fec084SRiver Riddle        if isinstance(self.mnemonic, str):
27162fec084SRiver Riddle            return self.mnemonic
27262fec084SRiver Riddle
27362fec084SRiver Riddle        # If we don't already have the mnemonic in string form, compute
27462fec084SRiver Riddle        # it from the dialect name and the mnemonic.
27562fec084SRiver Riddle        dialect_name = self.abstractVal.GetChildMemberWithName(
27662fec084SRiver Riddle            "dialect"
27762fec084SRiver Riddle        ).GetChildMemberWithName("name")
27862fec084SRiver Riddle        self.mnemonic = f'{dialect_name.summary}"."{self.mnemonic.summary}'
27962fec084SRiver Riddle        return self.mnemonic
28062fec084SRiver Riddle
28162fec084SRiver Riddle
28262fec084SRiver Riddledef AttrTypeSummaryProvider(valobj: lldb.SBValue, internal_dict):
28362fec084SRiver Riddle    """Define an LLDB summary provider for Attributes and Types."""
28462fec084SRiver Riddle
28562fec084SRiver Riddle    # Check for a value field.
28662fec084SRiver Riddle    value = valobj.GetChildMemberWithName("value")
28762fec084SRiver Riddle    if value and value.summary:
28862fec084SRiver Riddle        return value.summary
28962fec084SRiver Riddle
29062fec084SRiver Riddle    # Otherwise, try the mnemoic.
29162fec084SRiver Riddle    mnemonic: lldb.SBValue = valobj.GetChildMemberWithName("[mnemonic]")
29262fec084SRiver Riddle    if not mnemonic.summary:
29362fec084SRiver Riddle        return ""
29462fec084SRiver Riddle    mnemonicStr = mnemonic.summary.strip('"')
29562fec084SRiver Riddle
29662fec084SRiver Riddle    # Handle a few extremely common builtin attributes/types.
29762fec084SRiver Riddle    ## IntegerType
29862fec084SRiver Riddle    if mnemonicStr == "iN":
29962fec084SRiver Riddle        signedness = valobj.GetChildMemberWithName("signedness").GetValueAsUnsigned()
30062fec084SRiver Riddle        prefix = "i"
30162fec084SRiver Riddle        if signedness == 1:
30262fec084SRiver Riddle            prefix = "si"
30362fec084SRiver Riddle        elif signedness == 2:
30462fec084SRiver Riddle            prefix = "ui"
30562fec084SRiver Riddle        return f"{prefix}{valobj.GetChildMemberWithName('width').GetValueAsUnsigned()}"
30662fec084SRiver Riddle    ## IntegerAttr
30762fec084SRiver Riddle    if mnemonicStr == "integer":
30862fec084SRiver Riddle        value = valobj.GetChildMemberWithName("value")
30962fec084SRiver Riddle        bitwidth = value.GetChildMemberWithName("BitWidth").GetValueAsUnsigned()
31062fec084SRiver Riddle        if bitwidth <= 64:
31162fec084SRiver Riddle            intVal = (
31262fec084SRiver Riddle                value.GetChildMemberWithName("U")
31362fec084SRiver Riddle                .GetChildMemberWithName("VAL")
31462fec084SRiver Riddle                .GetValueAsUnsigned()
31562fec084SRiver Riddle            )
31662fec084SRiver Riddle
31762fec084SRiver Riddle            if bitwidth == 1:
31862fec084SRiver Riddle                return "true" if intVal else "false"
31962fec084SRiver Riddle            return f"{intVal} : i{bitwidth}"
32062fec084SRiver Riddle
32162fec084SRiver Riddle    return mnemonicStr
32262fec084SRiver Riddle
32362fec084SRiver Riddle
32462fec084SRiver Riddle# ===----------------------------------------------------------------------=== #
32562fec084SRiver Riddle# mlir::Block
32662fec084SRiver Riddle# ===----------------------------------------------------------------------=== #
32762fec084SRiver Riddle
32862fec084SRiver Riddle
32962fec084SRiver Riddleclass BlockSynthProvider:
33062fec084SRiver Riddle    """Define an LLDB synthetic children provider for Blocks."""
33162fec084SRiver Riddle
33262fec084SRiver Riddle    def __init__(self, valobj, internal_dict):
33362fec084SRiver Riddle        self.valobj = valobj
33462fec084SRiver Riddle
33562fec084SRiver Riddle    def num_children(self):
33662fec084SRiver Riddle        return 3
33762fec084SRiver Riddle
33862fec084SRiver Riddle    def get_child_index(self, name):
33962fec084SRiver Riddle        if name == "parent":
34062fec084SRiver Riddle            return 0
34162fec084SRiver Riddle        if name == "operations":
34262fec084SRiver Riddle            return 1
34362fec084SRiver Riddle        if name == "arguments":
34462fec084SRiver Riddle            return 2
34562fec084SRiver Riddle        return None
34662fec084SRiver Riddle
34762fec084SRiver Riddle    def get_child_at_index(self, index):
34862fec084SRiver Riddle        if index >= 3:
34962fec084SRiver Riddle            return None
35062fec084SRiver Riddle        if index == 1:
35162fec084SRiver Riddle            return self.valobj.GetChildMemberWithName("operations")
35262fec084SRiver Riddle        if index == 2:
35362fec084SRiver Riddle            return self.valobj.GetChildMemberWithName("arguments")
35462fec084SRiver Riddle
35562fec084SRiver Riddle        expr_path = build_ptr_str_from_addr(self.valobj, self.valobj.GetType())
35662fec084SRiver Riddle        return self.valobj.CreateValueFromExpression(
35762fec084SRiver Riddle            "parent", f"{expr_path}->getParent()"
35862fec084SRiver Riddle        )
35962fec084SRiver Riddle
36062fec084SRiver Riddle
36162fec084SRiver Riddle# ===----------------------------------------------------------------------=== #
36262fec084SRiver Riddle# mlir::Operation
36362fec084SRiver Riddle# ===----------------------------------------------------------------------=== #
36462fec084SRiver Riddle
36562fec084SRiver Riddle
36662fec084SRiver Riddledef is_op(sbtype: lldb.SBType, internal_dict):
36762fec084SRiver Riddle    """Return if the given type is an operation."""
36862fec084SRiver Riddle
36962fec084SRiver Riddle    # Bottom out at OpState/Op.
37062fec084SRiver Riddle    typeName = sbtype.GetName()
37162fec084SRiver Riddle    if sbtype.GetNumberOfDirectBaseClasses() == 0:
37262fec084SRiver Riddle        return typeName == "mlir::OpState"
37362fec084SRiver Riddle    if typeName == "mlir::Operation" or typeName.startswith("mlir::Op<"):
37462fec084SRiver Riddle        return True
37562fec084SRiver Riddle
37662fec084SRiver Riddle    # Otherwise, recurse into the base class.
37762fec084SRiver Riddle    return is_op(sbtype.GetDirectBaseClassAtIndex(0).GetType(), internal_dict)
37862fec084SRiver Riddle
37962fec084SRiver Riddle
38062fec084SRiver Riddleclass OperationSynthProvider:
38162fec084SRiver Riddle    """Define an LLDB synthetic children provider for Operations."""
38262fec084SRiver Riddle
38362fec084SRiver Riddle    def __init__(self, valobj, internal_dict):
38462fec084SRiver Riddle        self.valobj = valobj
38562fec084SRiver Riddle        self.fields = []
38662fec084SRiver Riddle        self.update()
38762fec084SRiver Riddle
38862fec084SRiver Riddle    def num_children(self):
38962fec084SRiver Riddle        return len(self.fields)
39062fec084SRiver Riddle
39162fec084SRiver Riddle    def get_child_index(self, name):
39262fec084SRiver Riddle        try:
39362fec084SRiver Riddle            return self.fields.index(name)
39462fec084SRiver Riddle        except ValueError:
39562fec084SRiver Riddle            return None
39662fec084SRiver Riddle
39762fec084SRiver Riddle    def get_child_at_index(self, index):
39862fec084SRiver Riddle        if index >= len(self.fields):
39962fec084SRiver Riddle            return None
40062fec084SRiver Riddle        name = self.fields[index]
40162fec084SRiver Riddle        if name == "name":
40262fec084SRiver Riddle            return self.opobj.GetChildMemberWithName("name")
40362fec084SRiver Riddle        if name == "parent":
40462fec084SRiver Riddle            return self.opobj.GetChildMemberWithName("block").Clone("parent")
40562fec084SRiver Riddle        if name == "location":
40662fec084SRiver Riddle            return self.opobj.GetChildMemberWithName("location")
40762fec084SRiver Riddle        if name == "attributes":
40862fec084SRiver Riddle            return self.opobj.GetChildMemberWithName("attrs")
40962fec084SRiver Riddle
41062fec084SRiver Riddle        expr_path = build_ptr_str_from_addr(self.opobj, self.opobj.GetType())
41162fec084SRiver Riddle        if name == "operands":
41262fec084SRiver Riddle            return self.opobj.CreateValueFromExpression(
41362fec084SRiver Riddle                "operands", f"{expr_path}->debug_getOperands()"
41462fec084SRiver Riddle            )
41562fec084SRiver Riddle        if name == "results":
41662fec084SRiver Riddle            return self.opobj.CreateValueFromExpression(
41762fec084SRiver Riddle                "results", f"{expr_path}->debug_getResults()"
41862fec084SRiver Riddle            )
41962fec084SRiver Riddle        if name == "successors":
42062fec084SRiver Riddle            return self.opobj.CreateValueFromExpression(
42162fec084SRiver Riddle                "successors", f"{expr_path}->debug_getSuccessors()"
42262fec084SRiver Riddle            )
42362fec084SRiver Riddle        if name == "regions":
42462fec084SRiver Riddle            return self.opobj.CreateValueFromExpression(
42562fec084SRiver Riddle                "regions", f"{expr_path}->debug_getRegions()"
42662fec084SRiver Riddle            )
42762fec084SRiver Riddle        return None
42862fec084SRiver Riddle
42962fec084SRiver Riddle    def update(self):
43062fec084SRiver Riddle        # If this is a derived operation, we need to resolve through the
43162fec084SRiver Riddle        # state field.
43262fec084SRiver Riddle        self.opobj = self.valobj
43362fec084SRiver Riddle        if "mlir::Operation" not in self.valobj.GetTypeName():
43462fec084SRiver Riddle            self.opobj = self.valobj.GetChildMemberWithName("state")
43562fec084SRiver Riddle
43662fec084SRiver Riddle        self.fields = ["parent", "name", "location", "attributes"]
43762fec084SRiver Riddle        if (
43862fec084SRiver Riddle            self.opobj.GetChildMemberWithName("hasOperandStorage").GetValueAsUnsigned(0)
43962fec084SRiver Riddle            != 0
44062fec084SRiver Riddle        ):
44162fec084SRiver Riddle            self.fields.append("operands")
44262fec084SRiver Riddle        if self.opobj.GetChildMemberWithName("numResults").GetValueAsUnsigned(0) != 0:
44362fec084SRiver Riddle            self.fields.append("results")
44462fec084SRiver Riddle        if self.opobj.GetChildMemberWithName("numSuccs").GetValueAsUnsigned(0) != 0:
44562fec084SRiver Riddle            self.fields.append("successors")
44662fec084SRiver Riddle        if self.opobj.GetChildMemberWithName("numRegions").GetValueAsUnsigned(0) != 0:
44762fec084SRiver Riddle            self.fields.append("regions")
44862fec084SRiver Riddle
44962fec084SRiver Riddle
45062fec084SRiver Riddledef OperationSummaryProvider(valobj: lldb.SBValue, internal_dict):
45162fec084SRiver Riddle    """Define an LLDB summary provider for Operations."""
45262fec084SRiver Riddle
45362fec084SRiver Riddle    name = valobj.GetChildMemberWithName("name")
45462fec084SRiver Riddle    if name and name.summary:
45562fec084SRiver Riddle        return name.summary
45662fec084SRiver Riddle    return ""
45762fec084SRiver Riddle
45862fec084SRiver Riddle
45962fec084SRiver Riddle# ===----------------------------------------------------------------------=== #
46062fec084SRiver Riddle# Ranges
46162fec084SRiver Riddle# ===----------------------------------------------------------------------=== #
46262fec084SRiver Riddle
46362fec084SRiver Riddle
46462fec084SRiver Riddleclass DirectRangeSynthProvider:
46562fec084SRiver Riddle    """Define an LLDB synthetic children provider for direct ranges, i.e. those
46662fec084SRiver Riddle    with a base pointer that points to the type of element we want to display.
46762fec084SRiver Riddle    """
46862fec084SRiver Riddle
46962fec084SRiver Riddle    def __init__(self, valobj, internal_dict):
47062fec084SRiver Riddle        self.valobj = valobj
47162fec084SRiver Riddle        self.update()
47262fec084SRiver Riddle
47362fec084SRiver Riddle    def num_children(self):
47462fec084SRiver Riddle        return self.length
47562fec084SRiver Riddle
47662fec084SRiver Riddle    def get_child_index(self, name):
47762fec084SRiver Riddle        try:
47862fec084SRiver Riddle            return int(name.lstrip("[").rstrip("]"))
47962fec084SRiver Riddle        except:
48062fec084SRiver Riddle            return None
48162fec084SRiver Riddle
48262fec084SRiver Riddle    def get_child_at_index(self, index):
48362fec084SRiver Riddle        if index >= self.num_children():
48462fec084SRiver Riddle            return None
48562fec084SRiver Riddle        offset = index * self.type_size
48662fec084SRiver Riddle        return self.data.CreateChildAtOffset(f"[{index}]", offset, self.data_type)
48762fec084SRiver Riddle
48862fec084SRiver Riddle    def update(self):
48962fec084SRiver Riddle        length_obj = self.valobj.GetChildMemberWithName("count")
49062fec084SRiver Riddle        self.length = length_obj.GetValueAsUnsigned(0)
49162fec084SRiver Riddle
49262fec084SRiver Riddle        self.data = self.valobj.GetChildMemberWithName("base")
49362fec084SRiver Riddle        self.data_type = self.data.GetType().GetPointeeType()
49462fec084SRiver Riddle        self.type_size = self.data_type.GetByteSize()
49562fec084SRiver Riddle        assert self.type_size != 0
49662fec084SRiver Riddle
49762fec084SRiver Riddle
49862fec084SRiver Riddleclass InDirectRangeSynthProvider:
49962fec084SRiver Riddle    """Define an LLDB synthetic children provider for ranges
50062fec084SRiver Riddle    that transform the underlying base pointer, e.g. to convert
50162fec084SRiver Riddle    it to a different type depending on various characteristics
50262fec084SRiver Riddle    (e.g. mlir::ValueRange).
50362fec084SRiver Riddle    """
50462fec084SRiver Riddle
50562fec084SRiver Riddle    def __init__(self, valobj, internal_dict):
50662fec084SRiver Riddle        self.valobj = valobj
50762fec084SRiver Riddle        self.update()
50862fec084SRiver Riddle
50962fec084SRiver Riddle    def num_children(self):
51062fec084SRiver Riddle        return self.length
51162fec084SRiver Riddle
51262fec084SRiver Riddle    def get_child_index(self, name):
51362fec084SRiver Riddle        try:
51462fec084SRiver Riddle            return int(name.lstrip("[").rstrip("]"))
51562fec084SRiver Riddle        except:
51662fec084SRiver Riddle            return None
51762fec084SRiver Riddle
51862fec084SRiver Riddle    def get_child_at_index(self, index):
51962fec084SRiver Riddle        if index >= self.num_children():
52062fec084SRiver Riddle            return None
52162fec084SRiver Riddle        expr_path = get_expression_path(self.valobj)
52262fec084SRiver Riddle        return self.valobj.CreateValueFromExpression(
52362fec084SRiver Riddle            f"[{index}]", f"{expr_path}[{index}]"
52462fec084SRiver Riddle        )
52562fec084SRiver Riddle
52662fec084SRiver Riddle    def update(self):
52762fec084SRiver Riddle        length_obj = self.valobj.GetChildMemberWithName("count")
52862fec084SRiver Riddle        self.length = length_obj.GetValueAsUnsigned(0)
52962fec084SRiver Riddle
53062fec084SRiver Riddle
53162fec084SRiver Riddleclass IPListRangeSynthProvider:
532f9008e63STobias Hieta    """Define an LLDB synthetic children provider for an IPList."""
53362fec084SRiver Riddle
53462fec084SRiver Riddle    def __init__(self, valobj, internal_dict):
53562fec084SRiver Riddle        self.valobj = valobj
53662fec084SRiver Riddle        self.update()
53762fec084SRiver Riddle
53862fec084SRiver Riddle    def num_children(self):
53962fec084SRiver Riddle        sentinel = self.valobj.GetChildMemberWithName("Sentinel")
54062fec084SRiver Riddle        sentinel_addr = sentinel.AddressOf().GetValueAsUnsigned(0)
54162fec084SRiver Riddle
54262fec084SRiver Riddle        # Iterate the next pointers looking for the sentinel.
54362fec084SRiver Riddle        count = 0
54462fec084SRiver Riddle        current = sentinel.GetChildMemberWithName("Next")
54562fec084SRiver Riddle        while current.GetValueAsUnsigned(0) != sentinel_addr:
54662fec084SRiver Riddle            current = current.GetChildMemberWithName("Next")
54762fec084SRiver Riddle            count += 1
54862fec084SRiver Riddle
54962fec084SRiver Riddle        return count
55062fec084SRiver Riddle
55162fec084SRiver Riddle    def get_child_index(self, name):
55262fec084SRiver Riddle        try:
55362fec084SRiver Riddle            return int(name.lstrip("[").rstrip("]"))
55462fec084SRiver Riddle        except:
55562fec084SRiver Riddle            return None
55662fec084SRiver Riddle
55762fec084SRiver Riddle    def get_child_at_index(self, index):
55862fec084SRiver Riddle        if index >= self.num_children():
55962fec084SRiver Riddle            return None
56062fec084SRiver Riddle
56162fec084SRiver Riddle        # Start from the sentinel and grab the next pointer.
56262fec084SRiver Riddle        value: lldb.SBValue = self.valobj.GetChildMemberWithName("Sentinel")
56362fec084SRiver Riddle        it = 0
56462fec084SRiver Riddle        while it <= index:
56562fec084SRiver Riddle            value = value.GetChildMemberWithName("Next")
56662fec084SRiver Riddle            it += 1
56762fec084SRiver Riddle
56862fec084SRiver Riddle        return value.CreateValueFromExpression(
56962fec084SRiver Riddle            f"[{index}]",
57062fec084SRiver Riddle            f"(({self.value_type})({value.GetTypeName()}){value.GetValueAsUnsigned()})",
57162fec084SRiver Riddle        )
57262fec084SRiver Riddle
57362fec084SRiver Riddle    def update(self):
57462fec084SRiver Riddle        self.value_type = (
57562fec084SRiver Riddle            self.valobj.GetType().GetTemplateArgumentType(0).GetPointerType()
57662fec084SRiver Riddle        )
57762fec084SRiver Riddle
57862fec084SRiver Riddle
57962fec084SRiver Riddle# ===----------------------------------------------------------------------=== #
58062fec084SRiver Riddle# mlir::Value
58162fec084SRiver Riddle# ===----------------------------------------------------------------------=== #
58262fec084SRiver Riddle
58362fec084SRiver Riddle
58462fec084SRiver Riddleclass ValueSynthProvider:
585f9008e63STobias Hieta    """Define an LLDB synthetic children provider for Values."""
58662fec084SRiver Riddle
58762fec084SRiver Riddle    def __init__(self, valobj, internal_dict):
58862fec084SRiver Riddle        self.valobj = valobj
58962fec084SRiver Riddle        self.update()
59062fec084SRiver Riddle
59162fec084SRiver Riddle    def num_children(self):
59262fec084SRiver Riddle        # 7: BlockArgument:
59362fec084SRiver Riddle        #  index, type, owner, firstUse, location
59462fec084SRiver Riddle        if self.kind == 7:
59562fec084SRiver Riddle            return 5
59662fec084SRiver Riddle
59762fec084SRiver Riddle        # 0-6: OpResult:
59862fec084SRiver Riddle        #  index, type, owner, firstUse
59962fec084SRiver Riddle        return 4
60062fec084SRiver Riddle
60162fec084SRiver Riddle    def get_child_index(self, name):
60262fec084SRiver Riddle        if name == "index":
60362fec084SRiver Riddle            return 0
60462fec084SRiver Riddle        if name == "type":
60562fec084SRiver Riddle            return 1
60662fec084SRiver Riddle        if name == "owner":
60762fec084SRiver Riddle            return 2
60862fec084SRiver Riddle        if name == "firstUse":
60962fec084SRiver Riddle            return 3
61062fec084SRiver Riddle        if name == "location":
61162fec084SRiver Riddle            return 4
61262fec084SRiver Riddle        return None
61362fec084SRiver Riddle
61462fec084SRiver Riddle    def get_child_at_index(self, index):
61562fec084SRiver Riddle        if index >= self.num_children():
61662fec084SRiver Riddle            return None
61762fec084SRiver Riddle
61862fec084SRiver Riddle        # Check if the current value is already an Impl struct.
61962fec084SRiver Riddle        if self.valobj.GetTypeName().endswith("Impl"):
62062fec084SRiver Riddle            impl_ptr_str = build_ptr_str_from_addr(
62162fec084SRiver Riddle                self.valobj.AddressOf(), self.valobj.GetType().GetPointerType()
62262fec084SRiver Riddle            )
62362fec084SRiver Riddle        else:
62462fec084SRiver Riddle            impl = self.valobj.GetChildMemberWithName("impl")
62562fec084SRiver Riddle            impl_ptr_str = build_ptr_str_from_addr(impl, impl.GetType())
62662fec084SRiver Riddle
62762fec084SRiver Riddle        # Cast to the derived Impl type.
62862fec084SRiver Riddle        if self.kind == 7:
62962fec084SRiver Riddle            derived_impl_str = f"((mlir::detail::BlockArgumentImpl *){impl_ptr_str})"
63062fec084SRiver Riddle        elif self.kind == 6:
63162fec084SRiver Riddle            derived_impl_str = f"((mlir::detail::OutOfLineOpResult *){impl_ptr_str})"
63262fec084SRiver Riddle        else:
63362fec084SRiver Riddle            derived_impl_str = f"((mlir::detail::InlineOpResult *){impl_ptr_str})"
63462fec084SRiver Riddle
63562fec084SRiver Riddle        # Handle the shared fields when possible.
63662fec084SRiver Riddle        if index == 1:
63762fec084SRiver Riddle            return self.valobj.CreateValueFromExpression(
63862fec084SRiver Riddle                "type", f"{derived_impl_str}->debug_getType()"
63962fec084SRiver Riddle            )
64062fec084SRiver Riddle        if index == 3:
64162fec084SRiver Riddle            return self.valobj.CreateValueFromExpression(
64262fec084SRiver Riddle                "firstUse", f"{derived_impl_str}->firstUse"
64362fec084SRiver Riddle            )
64462fec084SRiver Riddle
64562fec084SRiver Riddle        # Handle Block argument children.
64662fec084SRiver Riddle        if self.kind == 7:
64762fec084SRiver Riddle            impl = self.valobj.CreateValueFromExpression("impl", derived_impl_str)
64862fec084SRiver Riddle            if index == 0:
64962fec084SRiver Riddle                return impl.GetChildMemberWithName("index")
65062fec084SRiver Riddle            if index == 2:
65162fec084SRiver Riddle                return impl.GetChildMemberWithName("owner")
65262fec084SRiver Riddle            if index == 4:
65362fec084SRiver Riddle                return impl.GetChildMemberWithName("loc")
65462fec084SRiver Riddle
65562fec084SRiver Riddle        # Handle OpResult children.
65662fec084SRiver Riddle        if index == 0:
65762fec084SRiver Riddle            # Handle the out of line case.
65862fec084SRiver Riddle            if self.kind == 6:
65962fec084SRiver Riddle                return self.valobj.CreateValueFromExpression(
66062fec084SRiver Riddle                    "index", f"{derived_impl_str}->outOfLineIndex + 6"
66162fec084SRiver Riddle                )
66262fec084SRiver Riddle            return self.valobj.CreateValueFromExpression("index", f"{self.kind}")
66362fec084SRiver Riddle        if index == 2:
66462fec084SRiver Riddle            return self.valobj.CreateValueFromExpression(
66562fec084SRiver Riddle                "owner", f"{derived_impl_str}->getOwner()"
66662fec084SRiver Riddle            )
66762fec084SRiver Riddle        return None
66862fec084SRiver Riddle
66962fec084SRiver Riddle    def update(self):
67062fec084SRiver Riddle        # Check if the current value is already an Impl struct.
67162fec084SRiver Riddle        if self.valobj.GetTypeName().endswith("Impl"):
67262fec084SRiver Riddle            impl_ptr_str = build_ptr_str_from_addr(
67362fec084SRiver Riddle                self.valobj, self.valobj.GetType().GetPointerType()
67462fec084SRiver Riddle            )
67562fec084SRiver Riddle        else:
67662fec084SRiver Riddle            impl = self.valobj.GetChildMemberWithName("impl")
67762fec084SRiver Riddle            impl_ptr_str = build_ptr_str_from_addr(impl, impl.GetType())
67862fec084SRiver Riddle
67962fec084SRiver Riddle        # Compute the kind of value we are dealing with.
68062fec084SRiver Riddle        self.kind = self.valobj.CreateValueFromExpression(
68162fec084SRiver Riddle            "kind", f"{impl_ptr_str}->debug_getKind()"
68262fec084SRiver Riddle        ).GetValueAsUnsigned()
68362fec084SRiver Riddle
68462fec084SRiver Riddle
68562fec084SRiver Riddledef ValueSummaryProvider(valobj: lldb.SBValue, internal_dict):
686f9008e63STobias Hieta    """Define an LLDB summary provider for Values."""
68762fec084SRiver Riddle
68862fec084SRiver Riddle    index = valobj.GetChildMemberWithName("index").GetValueAsUnsigned()
68962fec084SRiver Riddle    # Check if this is a block argument or not (block arguments have locations).
69062fec084SRiver Riddle    if valobj.GetChildMemberWithName("location").IsValid():
69162fec084SRiver Riddle        summary = f"Block Argument {index}"
69262fec084SRiver Riddle    else:
69362fec084SRiver Riddle        owner_name = (
69462fec084SRiver Riddle            valobj.GetChildMemberWithName("owner")
69562fec084SRiver Riddle            .GetChildMemberWithName("name")
69662fec084SRiver Riddle            .summary
69762fec084SRiver Riddle        )
69862fec084SRiver Riddle        summary = f"{owner_name} Result {index}"
69962fec084SRiver Riddle
70062fec084SRiver Riddle    # Grab the type to help form the summary.
70162fec084SRiver Riddle    type = valobj.GetChildMemberWithName("type")
70262fec084SRiver Riddle    if type.summary:
70362fec084SRiver Riddle        summary += f": {type.summary}"
70462fec084SRiver Riddle
70562fec084SRiver Riddle    return summary
70662fec084SRiver Riddle
70762fec084SRiver Riddle
70862fec084SRiver Riddle# ===----------------------------------------------------------------------=== #
70962fec084SRiver Riddle# Initialization
71062fec084SRiver Riddle# ===----------------------------------------------------------------------=== #
71162fec084SRiver Riddle
71262fec084SRiver Riddle
71362fec084SRiver Riddledef __lldb_init_module(debugger: lldb.SBDebugger, internal_dict):
71462fec084SRiver Riddle    cat: lldb.SBTypeCategory = debugger.CreateCategory("mlir")
71562fec084SRiver Riddle    cat.SetEnabled(True)
71662fec084SRiver Riddle
71762fec084SRiver Riddle    # Attributes and Types
71862fec084SRiver Riddle    cat.AddTypeSummary(
71962fec084SRiver Riddle        lldb.SBTypeNameSpecifier(
72062fec084SRiver Riddle            "mlirDataFormatters.is_attribute_or_type", lldb.eFormatterMatchCallback
72162fec084SRiver Riddle        ),
72262fec084SRiver Riddle        lldb.SBTypeSummary.CreateWithFunctionName(
72362fec084SRiver Riddle            "mlirDataFormatters.AttrTypeSummaryProvider"
72462fec084SRiver Riddle        ),
72562fec084SRiver Riddle    )
72662fec084SRiver Riddle    cat.AddTypeSynthetic(
72762fec084SRiver Riddle        lldb.SBTypeNameSpecifier(
72862fec084SRiver Riddle            "mlirDataFormatters.is_attribute_or_type", lldb.eFormatterMatchCallback
72962fec084SRiver Riddle        ),
73062fec084SRiver Riddle        lldb.SBTypeSynthetic.CreateWithClassName(
73162fec084SRiver Riddle            "mlirDataFormatters.AttrTypeSynthProvider"
73262fec084SRiver Riddle        ),
73362fec084SRiver Riddle    )
73462fec084SRiver Riddle
73562fec084SRiver Riddle    # Operation
73662fec084SRiver Riddle    cat.AddTypeSynthetic(
73762fec084SRiver Riddle        lldb.SBTypeNameSpecifier("mlir::Block", lldb.eFormatterMatchExact),
73862fec084SRiver Riddle        lldb.SBTypeSynthetic.CreateWithClassName(
73962fec084SRiver Riddle            "mlirDataFormatters.BlockSynthProvider"
74062fec084SRiver Riddle        ),
74162fec084SRiver Riddle    )
74262fec084SRiver Riddle
74362fec084SRiver Riddle    # NamedAttribute
74462fec084SRiver Riddle    cat.AddTypeSummary(
74562fec084SRiver Riddle        lldb.SBTypeNameSpecifier("mlir::NamedAttribute", lldb.eFormatterMatchExact),
74662fec084SRiver Riddle        lldb.SBTypeSummary.CreateWithSummaryString("${var.name%S} = ${var.value%S}"),
74762fec084SRiver Riddle    )
74862fec084SRiver Riddle
74962fec084SRiver Riddle    # OperationName
75062fec084SRiver Riddle    cat.AddTypeSummary(
75162fec084SRiver Riddle        lldb.SBTypeNameSpecifier("mlir::OperationName", lldb.eFormatterMatchExact),
75262fec084SRiver Riddle        lldb.SBTypeSummary.CreateWithSummaryString("${var.impl->name%S}"),
75362fec084SRiver Riddle    )
75462fec084SRiver Riddle
75562fec084SRiver Riddle    # Operation
75662fec084SRiver Riddle    cat.AddTypeSummary(
75762fec084SRiver Riddle        lldb.SBTypeNameSpecifier(
75862fec084SRiver Riddle            "mlirDataFormatters.is_op", lldb.eFormatterMatchCallback
75962fec084SRiver Riddle        ),
76062fec084SRiver Riddle        lldb.SBTypeSummary.CreateWithFunctionName(
76162fec084SRiver Riddle            "mlirDataFormatters.OperationSummaryProvider"
76262fec084SRiver Riddle        ),
76362fec084SRiver Riddle    )
76462fec084SRiver Riddle    cat.AddTypeSynthetic(
76562fec084SRiver Riddle        lldb.SBTypeNameSpecifier(
76662fec084SRiver Riddle            "mlirDataFormatters.is_op", lldb.eFormatterMatchCallback
76762fec084SRiver Riddle        ),
76862fec084SRiver Riddle        lldb.SBTypeSynthetic.CreateWithClassName(
76962fec084SRiver Riddle            "mlirDataFormatters.OperationSynthProvider"
77062fec084SRiver Riddle        ),
77162fec084SRiver Riddle    )
77262fec084SRiver Riddle
77362fec084SRiver Riddle    # Ranges
77462fec084SRiver Riddle    def add_direct_range_summary_and_synth(name):
77562fec084SRiver Riddle        cat.AddTypeSummary(
77662fec084SRiver Riddle            lldb.SBTypeNameSpecifier(name, lldb.eFormatterMatchExact),
77762fec084SRiver Riddle            lldb.SBTypeSummary.CreateWithSummaryString("size=${svar%#}"),
77862fec084SRiver Riddle        )
77962fec084SRiver Riddle        cat.AddTypeSynthetic(
78062fec084SRiver Riddle            lldb.SBTypeNameSpecifier(name, lldb.eFormatterMatchExact),
78162fec084SRiver Riddle            lldb.SBTypeSynthetic.CreateWithClassName(
78262fec084SRiver Riddle                "mlirDataFormatters.DirectRangeSynthProvider"
78362fec084SRiver Riddle            ),
78462fec084SRiver Riddle        )
78562fec084SRiver Riddle
78662fec084SRiver Riddle    def add_indirect_range_summary_and_synth(name):
78762fec084SRiver Riddle        cat.AddTypeSummary(
78862fec084SRiver Riddle            lldb.SBTypeNameSpecifier(name, lldb.eFormatterMatchExact),
78962fec084SRiver Riddle            lldb.SBTypeSummary.CreateWithSummaryString("size=${svar%#}"),
79062fec084SRiver Riddle        )
79162fec084SRiver Riddle        cat.AddTypeSynthetic(
79262fec084SRiver Riddle            lldb.SBTypeNameSpecifier(name, lldb.eFormatterMatchExact),
79362fec084SRiver Riddle            lldb.SBTypeSynthetic.CreateWithClassName(
79462fec084SRiver Riddle                "mlirDataFormatters.InDirectRangeSynthProvider"
79562fec084SRiver Riddle            ),
79662fec084SRiver Riddle        )
79762fec084SRiver Riddle
79862fec084SRiver Riddle    def add_iplist_range_summary_and_synth(name):
79962fec084SRiver Riddle        cat.AddTypeSummary(
80062fec084SRiver Riddle            lldb.SBTypeNameSpecifier(name, lldb.eFormatterMatchExact),
80162fec084SRiver Riddle            lldb.SBTypeSummary.CreateWithSummaryString("size=${svar%#}"),
80262fec084SRiver Riddle        )
80362fec084SRiver Riddle        cat.AddTypeSynthetic(
80462fec084SRiver Riddle            lldb.SBTypeNameSpecifier(name, lldb.eFormatterMatchExact),
80562fec084SRiver Riddle            lldb.SBTypeSynthetic.CreateWithClassName(
80662fec084SRiver Riddle                "mlirDataFormatters.IPListRangeSynthProvider"
80762fec084SRiver Riddle            ),
80862fec084SRiver Riddle        )
80962fec084SRiver Riddle
81062fec084SRiver Riddle    add_direct_range_summary_and_synth("mlir::Operation::operand_range")
81162fec084SRiver Riddle    add_direct_range_summary_and_synth("mlir::OperandRange")
81262fec084SRiver Riddle    add_direct_range_summary_and_synth("mlir::Operation::result_range")
81362fec084SRiver Riddle    add_direct_range_summary_and_synth("mlir::ResultRange")
81462fec084SRiver Riddle    add_direct_range_summary_and_synth("mlir::SuccessorRange")
81562fec084SRiver Riddle    add_indirect_range_summary_and_synth("mlir::ValueRange")
81662fec084SRiver Riddle    add_indirect_range_summary_and_synth("mlir::TypeRange")
81762fec084SRiver Riddle    add_iplist_range_summary_and_synth("mlir::Block::OpListType")
81862fec084SRiver Riddle    add_iplist_range_summary_and_synth("mlir::Region::BlockListType")
81962fec084SRiver Riddle
82062fec084SRiver Riddle    # Values
82162fec084SRiver Riddle    def add_value_summary_and_synth(name):
82262fec084SRiver Riddle        cat.AddTypeSummary(
82362fec084SRiver Riddle            lldb.SBTypeNameSpecifier(name, lldb.eFormatterMatchExact),
82462fec084SRiver Riddle            lldb.SBTypeSummary.CreateWithFunctionName(
82562fec084SRiver Riddle                "mlirDataFormatters.ValueSummaryProvider"
82662fec084SRiver Riddle            ),
82762fec084SRiver Riddle        )
82862fec084SRiver Riddle        cat.AddTypeSynthetic(
82962fec084SRiver Riddle            lldb.SBTypeNameSpecifier(name, lldb.eFormatterMatchExact),
83062fec084SRiver Riddle            lldb.SBTypeSynthetic.CreateWithClassName(
83162fec084SRiver Riddle                "mlirDataFormatters.ValueSynthProvider"
83262fec084SRiver Riddle            ),
83362fec084SRiver Riddle        )
83462fec084SRiver Riddle
83562fec084SRiver Riddle    add_value_summary_and_synth("mlir::BlockArgument")
83662fec084SRiver Riddle    add_value_summary_and_synth("mlir::Value")
83762fec084SRiver Riddle    add_value_summary_and_synth("mlir::OpResult")
83862fec084SRiver Riddle    add_value_summary_and_synth("mlir::detail::OpResultImpl")
839