llvm-project
832 строки · 28.8 Кб
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
14stream = lldb.SBStream()15if not val.GetExpressionPath(stream):16return None17return 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
23if type.is_reference:24type = type.GetDereferencedType()25if not type.is_pointer:26type = type.GetPointerType()27return f"(({type}){addrValue.GetData().GetUnsignedInt64(lldb.SBError(), 0)})"28
29
30# ===----------------------------------------------------------------------=== #
31# Attributes and Types
32# ===----------------------------------------------------------------------=== #
33
34# This variable defines various mnemonic strings for use by the builtin
35# dialect attributes and types, which often have special formatting within
36# 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::Float8E5M2Type": '"f8E5M2"',54"mlir::Float8E4M3FNType": '"f8E4M3FN"',55"mlir::Float8E5M2FNUZType": '"f8E5M2FNUZ"',56"mlir::Float8E4M3FNUZType": '"f8E4M3FNUZ"',57"mlir::Float8E4M3B11FNUZType": '"f8E4M3B11FNUZ"',58"mlir::BFloat16Type": '"bf16"',59"mlir::Float16Type": '"f16"',60"mlir::FloatTF32Type": '"tf32"',61"mlir::Float32Type": '"f32"',62"mlir::Float64Type": '"f64"',63"mlir::Float80Type": '"f80"',64"mlir::Float128Type": '"f128"',65"mlir::FunctionType": '"(...) -> (...)"',66"mlir::IndexType": '"index"',67"mlir::IntegerType": '"iN"',68"mlir::NoneType": '"none"',69"mlir::TupleType": '"tuple<...>"',70"mlir::MemRefType": '"memref<...>"',71"mlir::UnrankedMemRef": '"memref<...>"',72"mlir::UnrankedTensorType": '"tensor<...>"',73"mlir::RankedTensorType": '"tensor<...>"',74"mlir::VectorType": '"vector<...>"',75}
76
77
78class ComputedTypeIDMap:79"""Compute a map of type ids to derived attributes, types, and locations.80
81This is necessary for determining the C++ type when holding a base class,
82where we really only have access to dynamic information.
83"""
84
85def __init__(self, target: lldb.SBTarget, internal_dict: dict):86self.resolved_typeids = {}87
88# Find all of the `id` variables, which are the name of TypeID variables89# defined within the TypeIDResolver.90type_ids = target.FindGlobalVariables("id", lldb.UINT32_MAX)91for type_id in type_ids:92# Strip out any matches that didn't come from a TypeID resolver. This93# also lets us extract the derived type name.94name = type_id.GetName()95match = re.search("^mlir::detail::TypeIDResolver<(.*), void>::id$", name)96if not match:97continue98type_name = match.group(1)99
100# Filter out types that we don't care about.101if not type_name.endswith(("Attr", "Loc", "Type")):102continue103
104# Find the LLDB type for the derived type.105type = None106for typeIt in target.FindTypes(type_name):107if not typeIt or not typeIt.IsValid():108continue109type = typeIt110break111if not type or not type.IsValid():112continue113
114# Map the raw address of the type id variable to the LLDB type.115self.resolved_typeids[type_id.AddressOf().GetValueAsUnsigned()] = type116
117# Resolve the type for the given TypeID address.118def resolve_type(self, typeIdAddr: lldb.SBValue):119try:120return self.resolved_typeids[typeIdAddr.GetValueAsUnsigned()]121except KeyError:122return None123
124
125def is_derived_attribute_or_type(sbtype: lldb.SBType, internal_dict):126"""Return if the given type is a derived attribute or type."""127
128# We only expect an AttrBase/TypeBase base class.129if sbtype.num_bases != 1:130return False131base_name = sbtype.GetDirectBaseClassAtIndex(0).GetName()132return base_name.startswith(("mlir::Attribute::AttrBase", "mlir::Type::TypeBase"))133
134
135def get_typeid_map(target: lldb.SBTarget, internal_dict: dict):136"""Get or construct a TypeID map for the given target."""137
138if "typeIdMap" not in internal_dict:139internal_dict["typeIdMap"] = ComputedTypeIDMap(target, internal_dict)140return internal_dict["typeIdMap"]141
142
143def is_attribute_or_type(sbtype: lldb.SBType, internal_dict):144"""Return if the given type is an attribute or type."""145
146num_bases = sbtype.GetNumberOfDirectBaseClasses()147typeName = sbtype.GetName()148
149# We bottom out at Attribute/Type/Location.150if num_bases == 0:151return typeName in ["mlir::Attribute", "mlir::Type", "mlir::Location"]152
153# Check the easy cases of AttrBase/TypeBase.154if typeName.startswith(("mlir::Attribute::AttrBase", "mlir::Type::TypeBase")):155return True156
157# Otherwise, recurse into the base class.158return is_attribute_or_type(159sbtype.GetDirectBaseClassAtIndex(0).GetType(), internal_dict160)161
162
163def resolve_attr_type_from_value(164valobj: lldb.SBValue, abstractVal: lldb.SBValue, internal_dict165):166"""Resolve the derived C++ type of an Attribute/Type value."""167
168# Derived attribute/types already have the desired type.169if is_derived_attribute_or_type(valobj.GetType(), internal_dict):170return valobj.GetType()171
172# Otherwise, we need to resolve the ImplTy from the TypeID. This is173# done dynamically, because we don't use C++ RTTI of any kind.174typeIdMap = get_typeid_map(valobj.GetTarget(), internal_dict)175return typeIdMap.resolve_type(176abstractVal.GetChildMemberWithName("typeID").GetChildMemberWithName("storage")177)178
179
180class AttrTypeSynthProvider:181"""Define an LLDB synthetic children provider for Attributes and Types."""182
183def __init__(self, valobj: lldb.SBValue, internal_dict):184self.valobj = valobj185
186# Grab the impl variable, which if this is a Location needs to be187# resolved through the LocationAttr impl variable.188impl: lldb.SBValue = self.valobj.GetChildMemberWithName("impl")189if self.valobj.GetTypeName() == "mlir::Location":190impl = impl.GetChildMemberWithName("impl")191self.abstractVal = impl.GetChildMemberWithName("abstractType")192if not self.abstractVal.IsValid():193self.abstractVal = impl.GetChildMemberWithName("abstractAttribute")194
195self.type = resolve_attr_type_from_value(196valobj, self.abstractVal, internal_dict197)198if not self.type:199self.impl_type = None200return201
202# Grab the ImplTy from the resolved type. This is the 3rd template203# argument of the base class.204self.impl_type = (205self.type.GetDirectBaseClassAtIndex(0).GetType().GetTemplateArgumentType(2)206)207self.impl_pointer_ty = self.impl_type.GetPointerType()208self.num_fields = self.impl_type.GetNumberOfFields()209
210# Optionally add a mnemonic field.211type_name = self.type.GetName()212if type_name in builtin_attr_type_mnemonics:213self.mnemonic = builtin_attr_type_mnemonics[type_name]214elif type_name.startswith("mlir::Dense"):215self.mnemonic = "dense<...>"216else:217self.mnemonic = self.valobj.CreateValueFromExpression(218"mnemonic", f"(llvm::StringRef){type_name}::getMnemonic()"219)220if not self.mnemonic.summary:221self.mnemonic = None222if self.mnemonic:223self.num_fields += 1224
225def num_children(self):226if not self.impl_type:227return 0228return self.num_fields229
230def get_child_index(self, name):231if not self.impl_type:232return None233if self.mnemonic and name == "[mnemonic]":234return self.impl_type.GetNumberOfFields()235for i in range(self.impl_type.GetNumberOfFields()):236if self.impl_type.GetFieldAtIndex(i).GetName() == name:237return i238return None239
240def get_child_at_index(self, index):241if not self.impl_type or index >= self.num_fields:242return None243
244impl: lldb.SBValue = self.valobj.GetChildMemberWithName("impl")245impl_ptr: lldb.SBValue = self.valobj.CreateValueFromData(246build_ptr_str_from_addr(impl, self.impl_pointer_ty),247impl.GetData(),248self.impl_pointer_ty,249)250
251# Check for the mnemonic field.252if index == self.impl_type.GetNumberOfFields():253return self.valobj.CreateValueFromExpression(254"[mnemonic]", self.get_mnemonic_string(impl_ptr)255)256
257# Otherwise, we expect the index to be a field.258field: lldb.SBTypeMember = self.impl_type.GetFieldAtIndex(index)259
260# Build the field access by resolving through the impl variable.261return impl_ptr.GetChildMemberWithName(field.GetName())262
263def get_mnemonic_string(self, impl_ptr: lldb.SBValue):264if isinstance(self.mnemonic, str):265return self.mnemonic266
267# If we don't already have the mnemonic in string form, compute268# it from the dialect name and the mnemonic.269dialect_name = self.abstractVal.GetChildMemberWithName(270"dialect"271).GetChildMemberWithName("name")272self.mnemonic = f'{dialect_name.summary}"."{self.mnemonic.summary}'273return self.mnemonic274
275
276def AttrTypeSummaryProvider(valobj: lldb.SBValue, internal_dict):277"""Define an LLDB summary provider for Attributes and Types."""278
279# Check for a value field.280value = valobj.GetChildMemberWithName("value")281if value and value.summary:282return value.summary283
284# Otherwise, try the mnemoic.285mnemonic: lldb.SBValue = valobj.GetChildMemberWithName("[mnemonic]")286if not mnemonic.summary:287return ""288mnemonicStr = mnemonic.summary.strip('"')289
290# Handle a few extremely common builtin attributes/types.291## IntegerType292if mnemonicStr == "iN":293signedness = valobj.GetChildMemberWithName("signedness").GetValueAsUnsigned()294prefix = "i"295if signedness == 1:296prefix = "si"297elif signedness == 2:298prefix = "ui"299return f"{prefix}{valobj.GetChildMemberWithName('width').GetValueAsUnsigned()}"300## IntegerAttr301if mnemonicStr == "integer":302value = valobj.GetChildMemberWithName("value")303bitwidth = value.GetChildMemberWithName("BitWidth").GetValueAsUnsigned()304if bitwidth <= 64:305intVal = (306value.GetChildMemberWithName("U")307.GetChildMemberWithName("VAL")308.GetValueAsUnsigned()309)310
311if bitwidth == 1:312return "true" if intVal else "false"313return f"{intVal} : i{bitwidth}"314
315return mnemonicStr316
317
318# ===----------------------------------------------------------------------=== #
319# mlir::Block
320# ===----------------------------------------------------------------------=== #
321
322
323class BlockSynthProvider:324"""Define an LLDB synthetic children provider for Blocks."""325
326def __init__(self, valobj, internal_dict):327self.valobj = valobj328
329def num_children(self):330return 3331
332def get_child_index(self, name):333if name == "parent":334return 0335if name == "operations":336return 1337if name == "arguments":338return 2339return None340
341def get_child_at_index(self, index):342if index >= 3:343return None344if index == 1:345return self.valobj.GetChildMemberWithName("operations")346if index == 2:347return self.valobj.GetChildMemberWithName("arguments")348
349expr_path = build_ptr_str_from_addr(self.valobj, self.valobj.GetType())350return self.valobj.CreateValueFromExpression(351"parent", f"{expr_path}->getParent()"352)353
354
355# ===----------------------------------------------------------------------=== #
356# mlir::Operation
357# ===----------------------------------------------------------------------=== #
358
359
360def is_op(sbtype: lldb.SBType, internal_dict):361"""Return if the given type is an operation."""362
363# Bottom out at OpState/Op.364typeName = sbtype.GetName()365if sbtype.GetNumberOfDirectBaseClasses() == 0:366return typeName == "mlir::OpState"367if typeName == "mlir::Operation" or typeName.startswith("mlir::Op<"):368return True369
370# Otherwise, recurse into the base class.371return is_op(sbtype.GetDirectBaseClassAtIndex(0).GetType(), internal_dict)372
373
374class OperationSynthProvider:375"""Define an LLDB synthetic children provider for Operations."""376
377def __init__(self, valobj, internal_dict):378self.valobj = valobj379self.fields = []380self.update()381
382def num_children(self):383return len(self.fields)384
385def get_child_index(self, name):386try:387return self.fields.index(name)388except ValueError:389return None390
391def get_child_at_index(self, index):392if index >= len(self.fields):393return None394name = self.fields[index]395if name == "name":396return self.opobj.GetChildMemberWithName("name")397if name == "parent":398return self.opobj.GetChildMemberWithName("block").Clone("parent")399if name == "location":400return self.opobj.GetChildMemberWithName("location")401if name == "attributes":402return self.opobj.GetChildMemberWithName("attrs")403
404expr_path = build_ptr_str_from_addr(self.opobj, self.opobj.GetType())405if name == "operands":406return self.opobj.CreateValueFromExpression(407"operands", f"{expr_path}->debug_getOperands()"408)409if name == "results":410return self.opobj.CreateValueFromExpression(411"results", f"{expr_path}->debug_getResults()"412)413if name == "successors":414return self.opobj.CreateValueFromExpression(415"successors", f"{expr_path}->debug_getSuccessors()"416)417if name == "regions":418return self.opobj.CreateValueFromExpression(419"regions", f"{expr_path}->debug_getRegions()"420)421return None422
423def update(self):424# If this is a derived operation, we need to resolve through the425# state field.426self.opobj = self.valobj427if "mlir::Operation" not in self.valobj.GetTypeName():428self.opobj = self.valobj.GetChildMemberWithName("state")429
430self.fields = ["parent", "name", "location", "attributes"]431if (432self.opobj.GetChildMemberWithName("hasOperandStorage").GetValueAsUnsigned(0)433!= 0434):435self.fields.append("operands")436if self.opobj.GetChildMemberWithName("numResults").GetValueAsUnsigned(0) != 0:437self.fields.append("results")438if self.opobj.GetChildMemberWithName("numSuccs").GetValueAsUnsigned(0) != 0:439self.fields.append("successors")440if self.opobj.GetChildMemberWithName("numRegions").GetValueAsUnsigned(0) != 0:441self.fields.append("regions")442
443
444def OperationSummaryProvider(valobj: lldb.SBValue, internal_dict):445"""Define an LLDB summary provider for Operations."""446
447name = valobj.GetChildMemberWithName("name")448if name and name.summary:449return name.summary450return ""451
452
453# ===----------------------------------------------------------------------=== #
454# Ranges
455# ===----------------------------------------------------------------------=== #
456
457
458class DirectRangeSynthProvider:459"""Define an LLDB synthetic children provider for direct ranges, i.e. those460with a base pointer that points to the type of element we want to display.
461"""
462
463def __init__(self, valobj, internal_dict):464self.valobj = valobj465self.update()466
467def num_children(self):468return self.length469
470def get_child_index(self, name):471try:472return int(name.lstrip("[").rstrip("]"))473except:474return None475
476def get_child_at_index(self, index):477if index >= self.num_children():478return None479offset = index * self.type_size480return self.data.CreateChildAtOffset(f"[{index}]", offset, self.data_type)481
482def update(self):483length_obj = self.valobj.GetChildMemberWithName("count")484self.length = length_obj.GetValueAsUnsigned(0)485
486self.data = self.valobj.GetChildMemberWithName("base")487self.data_type = self.data.GetType().GetPointeeType()488self.type_size = self.data_type.GetByteSize()489assert self.type_size != 0490
491
492class InDirectRangeSynthProvider:493"""Define an LLDB synthetic children provider for ranges494that transform the underlying base pointer, e.g. to convert
495it to a different type depending on various characteristics
496(e.g. mlir::ValueRange).
497"""
498
499def __init__(self, valobj, internal_dict):500self.valobj = valobj501self.update()502
503def num_children(self):504return self.length505
506def get_child_index(self, name):507try:508return int(name.lstrip("[").rstrip("]"))509except:510return None511
512def get_child_at_index(self, index):513if index >= self.num_children():514return None515expr_path = get_expression_path(self.valobj)516return self.valobj.CreateValueFromExpression(517f"[{index}]", f"{expr_path}[{index}]"518)519
520def update(self):521length_obj = self.valobj.GetChildMemberWithName("count")522self.length = length_obj.GetValueAsUnsigned(0)523
524
525class IPListRangeSynthProvider:526"""Define an LLDB synthetic children provider for an IPList."""527
528def __init__(self, valobj, internal_dict):529self.valobj = valobj530self.update()531
532def num_children(self):533sentinel = self.valobj.GetChildMemberWithName("Sentinel")534sentinel_addr = sentinel.AddressOf().GetValueAsUnsigned(0)535
536# Iterate the next pointers looking for the sentinel.537count = 0538current = sentinel.GetChildMemberWithName("Next")539while current.GetValueAsUnsigned(0) != sentinel_addr:540current = current.GetChildMemberWithName("Next")541count += 1542
543return count544
545def get_child_index(self, name):546try:547return int(name.lstrip("[").rstrip("]"))548except:549return None550
551def get_child_at_index(self, index):552if index >= self.num_children():553return None554
555# Start from the sentinel and grab the next pointer.556value: lldb.SBValue = self.valobj.GetChildMemberWithName("Sentinel")557it = 0558while it <= index:559value = value.GetChildMemberWithName("Next")560it += 1561
562return value.CreateValueFromExpression(563f"[{index}]",564f"(({self.value_type})({value.GetTypeName()}){value.GetValueAsUnsigned()})",565)566
567def update(self):568self.value_type = (569self.valobj.GetType().GetTemplateArgumentType(0).GetPointerType()570)571
572
573# ===----------------------------------------------------------------------=== #
574# mlir::Value
575# ===----------------------------------------------------------------------=== #
576
577
578class ValueSynthProvider:579"""Define an LLDB synthetic children provider for Values."""580
581def __init__(self, valobj, internal_dict):582self.valobj = valobj583self.update()584
585def num_children(self):586# 7: BlockArgument:587# index, type, owner, firstUse, location588if self.kind == 7:589return 5590
591# 0-6: OpResult:592# index, type, owner, firstUse593return 4594
595def get_child_index(self, name):596if name == "index":597return 0598if name == "type":599return 1600if name == "owner":601return 2602if name == "firstUse":603return 3604if name == "location":605return 4606return None607
608def get_child_at_index(self, index):609if index >= self.num_children():610return None611
612# Check if the current value is already an Impl struct.613if self.valobj.GetTypeName().endswith("Impl"):614impl_ptr_str = build_ptr_str_from_addr(615self.valobj.AddressOf(), self.valobj.GetType().GetPointerType()616)617else:618impl = self.valobj.GetChildMemberWithName("impl")619impl_ptr_str = build_ptr_str_from_addr(impl, impl.GetType())620
621# Cast to the derived Impl type.622if self.kind == 7:623derived_impl_str = f"((mlir::detail::BlockArgumentImpl *){impl_ptr_str})"624elif self.kind == 6:625derived_impl_str = f"((mlir::detail::OutOfLineOpResult *){impl_ptr_str})"626else:627derived_impl_str = f"((mlir::detail::InlineOpResult *){impl_ptr_str})"628
629# Handle the shared fields when possible.630if index == 1:631return self.valobj.CreateValueFromExpression(632"type", f"{derived_impl_str}->debug_getType()"633)634if index == 3:635return self.valobj.CreateValueFromExpression(636"firstUse", f"{derived_impl_str}->firstUse"637)638
639# Handle Block argument children.640if self.kind == 7:641impl = self.valobj.CreateValueFromExpression("impl", derived_impl_str)642if index == 0:643return impl.GetChildMemberWithName("index")644if index == 2:645return impl.GetChildMemberWithName("owner")646if index == 4:647return impl.GetChildMemberWithName("loc")648
649# Handle OpResult children.650if index == 0:651# Handle the out of line case.652if self.kind == 6:653return self.valobj.CreateValueFromExpression(654"index", f"{derived_impl_str}->outOfLineIndex + 6"655)656return self.valobj.CreateValueFromExpression("index", f"{self.kind}")657if index == 2:658return self.valobj.CreateValueFromExpression(659"owner", f"{derived_impl_str}->getOwner()"660)661return None662
663def update(self):664# Check if the current value is already an Impl struct.665if self.valobj.GetTypeName().endswith("Impl"):666impl_ptr_str = build_ptr_str_from_addr(667self.valobj, self.valobj.GetType().GetPointerType()668)669else:670impl = self.valobj.GetChildMemberWithName("impl")671impl_ptr_str = build_ptr_str_from_addr(impl, impl.GetType())672
673# Compute the kind of value we are dealing with.674self.kind = self.valobj.CreateValueFromExpression(675"kind", f"{impl_ptr_str}->debug_getKind()"676).GetValueAsUnsigned()677
678
679def ValueSummaryProvider(valobj: lldb.SBValue, internal_dict):680"""Define an LLDB summary provider for Values."""681
682index = valobj.GetChildMemberWithName("index").GetValueAsUnsigned()683# Check if this is a block argument or not (block arguments have locations).684if valobj.GetChildMemberWithName("location").IsValid():685summary = f"Block Argument {index}"686else:687owner_name = (688valobj.GetChildMemberWithName("owner")689.GetChildMemberWithName("name")690.summary691)692summary = f"{owner_name} Result {index}"693
694# Grab the type to help form the summary.695type = valobj.GetChildMemberWithName("type")696if type.summary:697summary += f": {type.summary}"698
699return summary700
701
702# ===----------------------------------------------------------------------=== #
703# Initialization
704# ===----------------------------------------------------------------------=== #
705
706
707def __lldb_init_module(debugger: lldb.SBDebugger, internal_dict):708cat: lldb.SBTypeCategory = debugger.CreateCategory("mlir")709cat.SetEnabled(True)710
711# Attributes and Types712cat.AddTypeSummary(713lldb.SBTypeNameSpecifier(714"mlirDataFormatters.is_attribute_or_type", lldb.eFormatterMatchCallback715),716lldb.SBTypeSummary.CreateWithFunctionName(717"mlirDataFormatters.AttrTypeSummaryProvider"718),719)720cat.AddTypeSynthetic(721lldb.SBTypeNameSpecifier(722"mlirDataFormatters.is_attribute_or_type", lldb.eFormatterMatchCallback723),724lldb.SBTypeSynthetic.CreateWithClassName(725"mlirDataFormatters.AttrTypeSynthProvider"726),727)728
729# Operation730cat.AddTypeSynthetic(731lldb.SBTypeNameSpecifier("mlir::Block", lldb.eFormatterMatchExact),732lldb.SBTypeSynthetic.CreateWithClassName(733"mlirDataFormatters.BlockSynthProvider"734),735)736
737# NamedAttribute738cat.AddTypeSummary(739lldb.SBTypeNameSpecifier("mlir::NamedAttribute", lldb.eFormatterMatchExact),740lldb.SBTypeSummary.CreateWithSummaryString("${var.name%S} = ${var.value%S}"),741)742
743# OperationName744cat.AddTypeSummary(745lldb.SBTypeNameSpecifier("mlir::OperationName", lldb.eFormatterMatchExact),746lldb.SBTypeSummary.CreateWithSummaryString("${var.impl->name%S}"),747)748
749# Operation750cat.AddTypeSummary(751lldb.SBTypeNameSpecifier(752"mlirDataFormatters.is_op", lldb.eFormatterMatchCallback753),754lldb.SBTypeSummary.CreateWithFunctionName(755"mlirDataFormatters.OperationSummaryProvider"756),757)758cat.AddTypeSynthetic(759lldb.SBTypeNameSpecifier(760"mlirDataFormatters.is_op", lldb.eFormatterMatchCallback761),762lldb.SBTypeSynthetic.CreateWithClassName(763"mlirDataFormatters.OperationSynthProvider"764),765)766
767# Ranges768def add_direct_range_summary_and_synth(name):769cat.AddTypeSummary(770lldb.SBTypeNameSpecifier(name, lldb.eFormatterMatchExact),771lldb.SBTypeSummary.CreateWithSummaryString("size=${svar%#}"),772)773cat.AddTypeSynthetic(774lldb.SBTypeNameSpecifier(name, lldb.eFormatterMatchExact),775lldb.SBTypeSynthetic.CreateWithClassName(776"mlirDataFormatters.DirectRangeSynthProvider"777),778)779
780def add_indirect_range_summary_and_synth(name):781cat.AddTypeSummary(782lldb.SBTypeNameSpecifier(name, lldb.eFormatterMatchExact),783lldb.SBTypeSummary.CreateWithSummaryString("size=${svar%#}"),784)785cat.AddTypeSynthetic(786lldb.SBTypeNameSpecifier(name, lldb.eFormatterMatchExact),787lldb.SBTypeSynthetic.CreateWithClassName(788"mlirDataFormatters.InDirectRangeSynthProvider"789),790)791
792def add_iplist_range_summary_and_synth(name):793cat.AddTypeSummary(794lldb.SBTypeNameSpecifier(name, lldb.eFormatterMatchExact),795lldb.SBTypeSummary.CreateWithSummaryString("size=${svar%#}"),796)797cat.AddTypeSynthetic(798lldb.SBTypeNameSpecifier(name, lldb.eFormatterMatchExact),799lldb.SBTypeSynthetic.CreateWithClassName(800"mlirDataFormatters.IPListRangeSynthProvider"801),802)803
804add_direct_range_summary_and_synth("mlir::Operation::operand_range")805add_direct_range_summary_and_synth("mlir::OperandRange")806add_direct_range_summary_and_synth("mlir::Operation::result_range")807add_direct_range_summary_and_synth("mlir::ResultRange")808add_direct_range_summary_and_synth("mlir::SuccessorRange")809add_indirect_range_summary_and_synth("mlir::ValueRange")810add_indirect_range_summary_and_synth("mlir::TypeRange")811add_iplist_range_summary_and_synth("mlir::Block::OpListType")812add_iplist_range_summary_and_synth("mlir::Region::BlockListType")813
814# Values815def add_value_summary_and_synth(name):816cat.AddTypeSummary(817lldb.SBTypeNameSpecifier(name, lldb.eFormatterMatchExact),818lldb.SBTypeSummary.CreateWithFunctionName(819"mlirDataFormatters.ValueSummaryProvider"820),821)822cat.AddTypeSynthetic(823lldb.SBTypeNameSpecifier(name, lldb.eFormatterMatchExact),824lldb.SBTypeSynthetic.CreateWithClassName(825"mlirDataFormatters.ValueSynthProvider"826),827)828
829add_value_summary_and_synth("mlir::BlockArgument")830add_value_summary_and_synth("mlir::Value")831add_value_summary_and_synth("mlir::OpResult")832add_value_summary_and_synth("mlir::detail::OpResultImpl")833