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