Mercurial > hg > CbC > CbC_llvm
diff llvm/utils/gdb-scripts/prettyprinters.py @ 252:1f2b6ac9f198 llvm-original
LLVM16-1
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 18 Aug 2023 09:04:13 +0900 |
parents | c4bab56944e8 |
children |
line wrap: on
line diff
--- a/llvm/utils/gdb-scripts/prettyprinters.py Wed Nov 09 17:47:54 2022 +0900 +++ b/llvm/utils/gdb-scripts/prettyprinters.py Fri Aug 18 09:04:13 2023 +0900 @@ -5,495 +5,550 @@ import gdb.printing import gdb.types + class Iterator: - def __iter__(self): - return self + def __iter__(self): + return self + + if sys.version_info.major == 2: - if sys.version_info.major == 2: - def next(self): - return self.__next__() + def next(self): + return self.__next__() - def children(self): - return self + def children(self): + return self + class SmallStringPrinter: - """Print an llvm::SmallString object.""" + """Print an llvm::SmallString object.""" - def __init__(self, val): - self.val = val + def __init__(self, val): + self.val = val - def to_string(self): - data = self.val['BeginX'].cast(gdb.lookup_type('char').pointer()) - length = self.val['Size'] - return data.lazy_string(length=length) + def to_string(self): + data = self.val["BeginX"].cast(gdb.lookup_type("char").pointer()) + length = self.val["Size"] + return data.lazy_string(length=length) - def display_hint (self): - return 'string' + def display_hint(self): + return "string" + class StringRefPrinter: - """Print an llvm::StringRef object.""" + """Print an llvm::StringRef object.""" - def __init__(self, val): - self.val = val + def __init__(self, val): + self.val = val - def to_string(self): - data = self.val['Data'] - length = self.val['Length'] - return data.lazy_string(length=length) + def to_string(self): + data = self.val["Data"] + length = self.val["Length"] + return data.lazy_string(length=length) - def display_hint(self): - return 'string' + def display_hint(self): + return "string" + class SmallVectorPrinter(Iterator): - """Print an llvm::SmallVector object.""" + """Print an llvm::SmallVector object.""" - def __init__(self, val): - self.val = val - t = val.type.template_argument(0).pointer() - self.begin = val['BeginX'].cast(t) - self.size = val['Size'] - self.i = 0 + def __init__(self, val): + self.val = val + t = val.type.template_argument(0).pointer() + self.begin = val["BeginX"].cast(t) + self.size = val["Size"] + self.i = 0 - def __next__(self): - if self.i == self.size: - raise StopIteration - ret = '[{}]'.format(self.i), (self.begin+self.i).dereference() - self.i += 1 - return ret + def __next__(self): + if self.i == self.size: + raise StopIteration + ret = "[{}]".format(self.i), (self.begin + self.i).dereference() + self.i += 1 + return ret - def to_string(self): - return 'llvm::SmallVector of Size {}, Capacity {}'.format(self.size, self.val['Capacity']) + def to_string(self): + return "llvm::SmallVector of Size {}, Capacity {}".format( + self.size, self.val["Capacity"] + ) - def display_hint (self): - return 'array' + def display_hint(self): + return "array" + class ArrayRefPrinter: - """Print an llvm::ArrayRef object.""" + """Print an llvm::ArrayRef object.""" - class _iterator: - def __init__(self, begin, end): - self.cur = begin - self.end = end - self.count = 0 + class _iterator: + def __init__(self, begin, end): + self.cur = begin + self.end = end + self.count = 0 - def __iter__(self): - return self + def __iter__(self): + return self - def __next__(self): - if self.cur == self.end: - raise StopIteration - count = self.count - self.count = self.count + 1 - cur = self.cur - self.cur = self.cur + 1 - return '[%d]' % count, cur.dereference() + def __next__(self): + if self.cur == self.end: + raise StopIteration + count = self.count + self.count = self.count + 1 + cur = self.cur + self.cur = self.cur + 1 + return "[%d]" % count, cur.dereference() - if sys.version_info.major == 2: - next = __next__ + if sys.version_info.major == 2: + next = __next__ - def __init__(self, val): - self.val = val + def __init__(self, val): + self.val = val + + def children(self): + data = self.val["Data"] + return self._iterator(data, data + self.val["Length"]) - def children(self): - data = self.val['Data'] - return self._iterator(data, data + self.val['Length']) + def to_string(self): + return "llvm::ArrayRef of length %d" % (self.val["Length"]) - def to_string(self): - return 'llvm::ArrayRef of length %d' % (self.val['Length']) + def display_hint(self): + return "array" - def display_hint (self): - return 'array' class ExpectedPrinter(Iterator): - """Print an llvm::Expected object.""" + """Print an llvm::Expected object.""" - def __init__(self, val): - self.val = val + def __init__(self, val): + self.val = val - def __next__(self): - val = self.val - if val is None: - raise StopIteration - self.val = None - if val['HasError']: - return ('error', val['ErrorStorage'].address.cast( - gdb.lookup_type('llvm::ErrorInfoBase').pointer()).dereference()) - return ('value', val['TStorage'].address.cast( - val.type.template_argument(0).pointer()).dereference()) + def __next__(self): + val = self.val + if val is None: + raise StopIteration + self.val = None + if val["HasError"]: + return ( + "error", + val["ErrorStorage"] + .address.cast(gdb.lookup_type("llvm::ErrorInfoBase").pointer()) + .dereference(), + ) + return ( + "value", + val["TStorage"] + .address.cast(val.type.template_argument(0).pointer()) + .dereference(), + ) - def to_string(self): - return 'llvm::Expected{}'.format(' is error' if self.val['HasError'] else '') + def to_string(self): + return "llvm::Expected{}".format(" is error" if self.val["HasError"] else "") + class OptionalPrinter(Iterator): - """Print an llvm::Optional object.""" + """Print an llvm::Optional object.""" - def __init__(self, val): - self.val = val + def __init__(self, val): + self.val = val - def __next__(self): - val = self.val - if val is None: - raise StopIteration - self.val = None - if not val['Storage']['hasVal']: - raise StopIteration - return ('value', val['Storage']['val']) + def __next__(self): + val = self.val + if val is None: + raise StopIteration + self.val = None + if not val["Storage"]["hasVal"]: + raise StopIteration + return ("value", val["Storage"]["val"]) - def to_string(self): - return 'llvm::Optional{}'.format('' if self.val['Storage']['hasVal'] else ' is not initialized') + def to_string(self): + return "llvm::Optional{}".format( + "" if self.val["Storage"]["hasVal"] else " is not initialized" + ) + class DenseMapPrinter: - "Print a DenseMap" + "Print a DenseMap" - class _iterator: - def __init__(self, key_info_t, begin, end): - self.key_info_t = key_info_t - self.cur = begin - self.end = end - self.advancePastEmptyBuckets() - self.first = True + class _iterator: + def __init__(self, key_info_t, begin, end): + self.key_info_t = key_info_t + self.cur = begin + self.end = end + self.advancePastEmptyBuckets() + self.first = True - def __iter__(self): - return self + def __iter__(self): + return self - def advancePastEmptyBuckets(self): - # disabled until the comments below can be addressed - # keeping as notes/posterity/hints for future contributors - return - n = self.key_info_t.name - is_equal = gdb.parse_and_eval(n + '::isEqual') - empty = gdb.parse_and_eval(n + '::getEmptyKey()') - tombstone = gdb.parse_and_eval(n + '::getTombstoneKey()') - # the following is invalid, GDB fails with: - # Python Exception <class 'gdb.error'> Attempt to take address of value - # not located in memory. - # because isEqual took parameter (for the unsigned long key I was testing) - # by const ref, and GDB - # It's also not entirely general - we should be accessing the "getFirst()" - # member function, not the 'first' member variable, but I've yet to figure - # out how to find/call member functions (especially (const) overloaded - # ones) on a gdb.Value. - while self.cur != self.end and (is_equal(self.cur.dereference()['first'], empty) or is_equal(self.cur.dereference()['first'], tombstone)): - self.cur = self.cur + 1 + def advancePastEmptyBuckets(self): + # disabled until the comments below can be addressed + # keeping as notes/posterity/hints for future contributors + return + n = self.key_info_t.name + is_equal = gdb.parse_and_eval(n + "::isEqual") + empty = gdb.parse_and_eval(n + "::getEmptyKey()") + tombstone = gdb.parse_and_eval(n + "::getTombstoneKey()") + # the following is invalid, GDB fails with: + # Python Exception <class 'gdb.error'> Attempt to take address of value + # not located in memory. + # because isEqual took parameter (for the unsigned long key I was testing) + # by const ref, and GDB + # It's also not entirely general - we should be accessing the "getFirst()" + # member function, not the 'first' member variable, but I've yet to figure + # out how to find/call member functions (especially (const) overloaded + # ones) on a gdb.Value. + while self.cur != self.end and ( + is_equal(self.cur.dereference()["first"], empty) + or is_equal(self.cur.dereference()["first"], tombstone) + ): + self.cur = self.cur + 1 - def __next__(self): - if self.cur == self.end: - raise StopIteration - cur = self.cur - v = cur.dereference()['first' if self.first else 'second'] - if not self.first: - self.cur = self.cur + 1 - self.advancePastEmptyBuckets() - self.first = True - else: - self.first = False - return 'x', v + def __next__(self): + if self.cur == self.end: + raise StopIteration + cur = self.cur + v = cur.dereference()["first" if self.first else "second"] + if not self.first: + self.cur = self.cur + 1 + self.advancePastEmptyBuckets() + self.first = True + else: + self.first = False + return "x", v + + if sys.version_info.major == 2: + next = __next__ - if sys.version_info.major == 2: - next = __next__ - - def __init__(self, val): - self.val = val + def __init__(self, val): + self.val = val - def children(self): - t = self.val.type.template_argument(3).pointer() - begin = self.val['Buckets'].cast(t) - end = (begin + self.val['NumBuckets']).cast(t) - return self._iterator(self.val.type.template_argument(2), begin, end) + def children(self): + t = self.val.type.template_argument(3).pointer() + begin = self.val["Buckets"].cast(t) + end = (begin + self.val["NumBuckets"]).cast(t) + return self._iterator(self.val.type.template_argument(2), begin, end) - def to_string(self): - return 'llvm::DenseMap with %d elements' % (self.val['NumEntries']) + def to_string(self): + return "llvm::DenseMap with %d elements" % (self.val["NumEntries"]) - def display_hint(self): - return 'map' + def display_hint(self): + return "map" + class StringMapPrinter: - "Print a StringMap" + "Print a StringMap" - def __init__(self, val): - self.val = val + def __init__(self, val): + self.val = val - def children(self): - it = self.val['TheTable'] - end = (it + self.val['NumBuckets']) - value_ty = self.val.type.template_argument(0) - entry_base_ty = gdb.lookup_type('llvm::StringMapEntryBase') - tombstone = gdb.parse_and_eval('llvm::StringMapImpl::TombstoneIntVal'); + def children(self): + it = self.val["TheTable"] + end = it + self.val["NumBuckets"] + value_ty = self.val.type.template_argument(0) + entry_base_ty = gdb.lookup_type("llvm::StringMapEntryBase") + tombstone = gdb.parse_and_eval("llvm::StringMapImpl::TombstoneIntVal") - while it != end: - it_deref = it.dereference() - if it_deref == 0 or it_deref == tombstone: - it = it + 1 - continue + while it != end: + it_deref = it.dereference() + if it_deref == 0 or it_deref == tombstone: + it = it + 1 + continue + + entry_ptr = it_deref.cast(entry_base_ty.pointer()) + entry = entry_ptr.dereference() - entry_ptr = it_deref.cast(entry_base_ty.pointer()) - entry = entry_ptr.dereference() - - str_len = entry['keyLength'] - value_ptr = (entry_ptr + 1).cast(value_ty.pointer()) - str_data = (entry_ptr + 1).cast(gdb.lookup_type('uintptr_t')) + max(value_ty.sizeof, entry_base_ty.alignof) - str_data = str_data.cast(gdb.lookup_type('char').const().pointer()) - string_ref = gdb.Value(struct.pack('PN', int(str_data), int(str_len)), gdb.lookup_type('llvm::StringRef')) - yield 'key', string_ref + str_len = entry["keyLength"] + value_ptr = (entry_ptr + 1).cast(value_ty.pointer()) + str_data = (entry_ptr + 1).cast(gdb.lookup_type("uintptr_t")) + max( + value_ty.sizeof, entry_base_ty.alignof + ) + str_data = str_data.cast(gdb.lookup_type("char").const().pointer()) + string_ref = gdb.Value( + struct.pack("PN", int(str_data), int(str_len)), + gdb.lookup_type("llvm::StringRef"), + ) + yield "key", string_ref - value = value_ptr.dereference() - yield 'value', value + value = value_ptr.dereference() + yield "value", value - it = it + 1 + it = it + 1 - def to_string(self): - return 'llvm::StringMap with %d elements' % (self.val['NumItems']) + def to_string(self): + return "llvm::StringMap with %d elements" % (self.val["NumItems"]) - def display_hint(self): - return 'map' + def display_hint(self): + return "map" + class TwinePrinter: - "Print a Twine" + "Print a Twine" - def __init__(self, val): - self._val = val + def __init__(self, val): + self._val = val - def display_hint(self): - return 'string' + def display_hint(self): + return "string" - def string_from_pretty_printer_lookup(self, val): - '''Lookup the default pretty-printer for val and use it. + def string_from_pretty_printer_lookup(self, val): + """Lookup the default pretty-printer for val and use it. - If no pretty-printer is defined for the type of val, print an error and - return a placeholder string.''' + If no pretty-printer is defined for the type of val, print an error and + return a placeholder string.""" - pp = gdb.default_visualizer(val) - if pp: - s = pp.to_string() + pp = gdb.default_visualizer(val) + if pp: + s = pp.to_string() - # The pretty-printer may return a LazyString instead of an actual Python - # string. Convert it to a Python string. However, GDB doesn't seem to - # register the LazyString type, so we can't check - # "type(s) == gdb.LazyString". - if 'LazyString' in type(s).__name__: - s = s.value().string() + # The pretty-printer may return a LazyString instead of an actual Python + # string. Convert it to a Python string. However, GDB doesn't seem to + # register the LazyString type, so we can't check + # "type(s) == gdb.LazyString". + if "LazyString" in type(s).__name__: + s = s.value().string() - else: - print(('No pretty printer for {} found. The resulting Twine ' + - 'representation will be incomplete.').format(val.type.name)) - s = '(missing {})'.format(val.type.name) - - return s + else: + print( + ( + "No pretty printer for {} found. The resulting Twine " + + "representation will be incomplete." + ).format(val.type.name) + ) + s = "(missing {})".format(val.type.name) - def is_twine_kind(self, kind, expected): - if not kind.endswith(expected): - return False - # apparently some GDB versions add the NodeKind:: namespace - # (happens for me on GDB 7.11) - return kind in ('llvm::Twine::' + expected, - 'llvm::Twine::NodeKind::' + expected) + return s - def string_from_child(self, child, kind): - '''Return the string representation of the Twine::Child child.''' - - if self.is_twine_kind(kind, 'EmptyKind') or self.is_twine_kind(kind, 'NullKind'): - return '' + def is_twine_kind(self, kind, expected): + if not kind.endswith(expected): + return False + # apparently some GDB versions add the NodeKind:: namespace + # (happens for me on GDB 7.11) + return kind in ( + "llvm::Twine::" + expected, + "llvm::Twine::NodeKind::" + expected, + ) - if self.is_twine_kind(kind, 'TwineKind'): - return self.string_from_twine_object(child['twine'].dereference()) + def string_from_child(self, child, kind): + """Return the string representation of the Twine::Child child.""" - if self.is_twine_kind(kind, 'CStringKind'): - return child['cString'].string() + if self.is_twine_kind(kind, "EmptyKind") or self.is_twine_kind( + kind, "NullKind" + ): + return "" - if self.is_twine_kind(kind, 'StdStringKind'): - val = child['stdString'].dereference() - return self.string_from_pretty_printer_lookup(val) + if self.is_twine_kind(kind, "TwineKind"): + return self.string_from_twine_object(child["twine"].dereference()) + + if self.is_twine_kind(kind, "CStringKind"): + return child["cString"].string() - if self.is_twine_kind(kind, 'PtrAndLengthKind'): - val = child['ptrAndLength'] - data = val['ptr'] - length = val['length'] - return data.string(length=length) + if self.is_twine_kind(kind, "StdStringKind"): + val = child["stdString"].dereference() + return self.string_from_pretty_printer_lookup(val) - if self.is_twine_kind(kind, 'CharKind'): - return chr(child['character']) + if self.is_twine_kind(kind, "PtrAndLengthKind"): + val = child["ptrAndLength"] + data = val["ptr"] + length = val["length"] + return data.string(length=length) - if self.is_twine_kind(kind, 'DecUIKind'): - return str(child['decUI']) + if self.is_twine_kind(kind, "CharKind"): + return chr(child["character"]) - if self.is_twine_kind(kind, 'DecIKind'): - return str(child['decI']) + if self.is_twine_kind(kind, "DecUIKind"): + return str(child["decUI"]) - if self.is_twine_kind(kind, 'DecULKind'): - return str(child['decUL'].dereference()) + if self.is_twine_kind(kind, "DecIKind"): + return str(child["decI"]) + + if self.is_twine_kind(kind, "DecULKind"): + return str(child["decUL"].dereference()) - if self.is_twine_kind(kind, 'DecLKind'): - return str(child['decL'].dereference()) + if self.is_twine_kind(kind, "DecLKind"): + return str(child["decL"].dereference()) - if self.is_twine_kind(kind, 'DecULLKind'): - return str(child['decULL'].dereference()) + if self.is_twine_kind(kind, "DecULLKind"): + return str(child["decULL"].dereference()) - if self.is_twine_kind(kind, 'DecLLKind'): - return str(child['decLL'].dereference()) + if self.is_twine_kind(kind, "DecLLKind"): + return str(child["decLL"].dereference()) - if self.is_twine_kind(kind, 'UHexKind'): - val = child['uHex'].dereference() - return hex(int(val)) + if self.is_twine_kind(kind, "UHexKind"): + val = child["uHex"].dereference() + return hex(int(val)) - print(('Unhandled NodeKind {} in Twine pretty-printer. The result will be ' - 'incomplete.').format(kind)) + print( + ( + "Unhandled NodeKind {} in Twine pretty-printer. The result will be " + "incomplete." + ).format(kind) + ) - return '(unhandled {})'.format(kind) + return "(unhandled {})".format(kind) - def string_from_twine_object(self, twine): - '''Return the string representation of the Twine object twine.''' + def string_from_twine_object(self, twine): + """Return the string representation of the Twine object twine.""" - lhs = twine['LHS'] - rhs = twine['RHS'] + lhs = twine["LHS"] + rhs = twine["RHS"] - lhs_kind = str(twine['LHSKind']) - rhs_kind = str(twine['RHSKind']) + lhs_kind = str(twine["LHSKind"]) + rhs_kind = str(twine["RHSKind"]) + + lhs_str = self.string_from_child(lhs, lhs_kind) + rhs_str = self.string_from_child(rhs, rhs_kind) - lhs_str = self.string_from_child(lhs, lhs_kind) - rhs_str = self.string_from_child(rhs, rhs_kind) - - return lhs_str + rhs_str + return lhs_str + rhs_str - def to_string(self): - return self.string_from_twine_object(self._val) + def to_string(self): + return self.string_from_twine_object(self._val) - def display_hint(self): - return 'string' + def display_hint(self): + return "string" + def get_pointer_int_pair(val): - """Get tuple from llvm::PointerIntPair.""" - info_name = val.type.template_argument(4).strip_typedefs().name - # Note: this throws a gdb.error if the info type is not used (by means of a - # call to getPointer() or similar) in the current translation unit. - enum_type = gdb.lookup_type(info_name + '::MaskAndShiftConstants') - enum_dict = gdb.types.make_enum_dict(enum_type) - ptr_mask = enum_dict[info_name + '::PointerBitMask'] - int_shift = enum_dict[info_name + '::IntShift'] - int_mask = enum_dict[info_name + '::IntMask'] - pair_union = val['Value'] - pointer = (pair_union & ptr_mask) - value = ((pair_union >> int_shift) & int_mask) - return (pointer, value) + """Get tuple from llvm::PointerIntPair.""" + info_name = val.type.template_argument(4).strip_typedefs().name + # Note: this throws a gdb.error if the info type is not used (by means of a + # call to getPointer() or similar) in the current translation unit. + enum_type = gdb.lookup_type(info_name + "::MaskAndShiftConstants") + enum_dict = gdb.types.make_enum_dict(enum_type) + ptr_mask = enum_dict[info_name + "::PointerBitMask"] + int_shift = enum_dict[info_name + "::IntShift"] + int_mask = enum_dict[info_name + "::IntMask"] + pair_union = val["Value"] + pointer = pair_union & ptr_mask + value = (pair_union >> int_shift) & int_mask + return (pointer, value) + class PointerIntPairPrinter: - """Print a PointerIntPair.""" + """Print a PointerIntPair.""" - def __init__(self, pointer, value): - self.pointer = pointer - self.value = value + def __init__(self, pointer, value): + self.pointer = pointer + self.value = value - def children(self): - yield ('pointer', self.pointer) - yield ('value', self.value) + def children(self): + yield ("pointer", self.pointer) + yield ("value", self.value) - def to_string(self): - return '(%s, %s)' % (self.pointer.type, self.value.type) + def to_string(self): + return "(%s, %s)" % (self.pointer.type, self.value.type) + def make_pointer_int_pair_printer(val): - """Factory for an llvm::PointerIntPair printer.""" - try: - pointer, value = get_pointer_int_pair(val) - except gdb.error: - return None # If PointerIntPair cannot be analyzed, print as raw value. - pointer_type = val.type.template_argument(0) - value_type = val.type.template_argument(2) - return PointerIntPairPrinter(pointer.cast(pointer_type), - value.cast(value_type)) + """Factory for an llvm::PointerIntPair printer.""" + try: + pointer, value = get_pointer_int_pair(val) + except gdb.error: + return None # If PointerIntPair cannot be analyzed, print as raw value. + pointer_type = val.type.template_argument(0) + value_type = val.type.template_argument(2) + return PointerIntPairPrinter(pointer.cast(pointer_type), value.cast(value_type)) + class PointerUnionPrinter: - """Print a PointerUnion.""" + """Print a PointerUnion.""" - def __init__(self, pointer): - self.pointer = pointer + def __init__(self, pointer): + self.pointer = pointer - def children(self): - yield ('pointer', self.pointer) + def children(self): + yield ("pointer", self.pointer) - def to_string(self): - return "Containing %s" % self.pointer.type + def to_string(self): + return "Containing %s" % self.pointer.type + def make_pointer_union_printer(val): - """Factory for an llvm::PointerUnion printer.""" - try: - pointer, value = get_pointer_int_pair(val['Val']) - except gdb.error: - return None # If PointerIntPair cannot be analyzed, print as raw value. - pointer_type = val.type.template_argument(int(value)) - return PointerUnionPrinter(pointer.cast(pointer_type)) + """Factory for an llvm::PointerUnion printer.""" + try: + pointer, value = get_pointer_int_pair(val["Val"]) + except gdb.error: + return None # If PointerIntPair cannot be analyzed, print as raw value. + pointer_type = val.type.template_argument(int(value)) + return PointerUnionPrinter(pointer.cast(pointer_type)) + class IlistNodePrinter: - """Print an llvm::ilist_node object.""" + """Print an llvm::ilist_node object.""" - def __init__(self, val): - impl_type = val.type.fields()[0].type - base_type = impl_type.fields()[0].type - derived_type = val.type.template_argument(0) + def __init__(self, val): + impl_type = val.type.fields()[0].type + base_type = impl_type.fields()[0].type + derived_type = val.type.template_argument(0) - def get_prev_and_sentinel(base): - # One of Prev and PrevAndSentinel exists. Depending on #defines used to - # compile LLVM, the base_type's template argument is either true of false. - if base_type.template_argument(0): - return get_pointer_int_pair(base['PrevAndSentinel']) - return base['Prev'], None + def get_prev_and_sentinel(base): + # One of Prev and PrevAndSentinel exists. Depending on #defines used to + # compile LLVM, the base_type's template argument is either true of false. + if base_type.template_argument(0): + return get_pointer_int_pair(base["PrevAndSentinel"]) + return base["Prev"], None - # Casts a base_type pointer to the appropriate derived type. - def cast_pointer(pointer): - sentinel = get_prev_and_sentinel(pointer.dereference())[1] - pointer = pointer.cast(impl_type.pointer()) - if sentinel: - return pointer - return pointer.cast(derived_type.pointer()) + # Casts a base_type pointer to the appropriate derived type. + def cast_pointer(pointer): + sentinel = get_prev_and_sentinel(pointer.dereference())[1] + pointer = pointer.cast(impl_type.pointer()) + if sentinel: + return pointer + return pointer.cast(derived_type.pointer()) - # Repeated cast becaue val.type's base_type is ambiguous when using tags. - base = val.cast(impl_type).cast(base_type) - (prev, sentinel) = get_prev_and_sentinel(base) - prev = prev.cast(base_type.pointer()) - self.prev = cast_pointer(prev) - self.next = cast_pointer(val['Next']) - self.sentinel = sentinel + # Repeated cast becaue val.type's base_type is ambiguous when using tags. + base = val.cast(impl_type).cast(base_type) + (prev, sentinel) = get_prev_and_sentinel(base) + prev = prev.cast(base_type.pointer()) + self.prev = cast_pointer(prev) + self.next = cast_pointer(val["Next"]) + self.sentinel = sentinel - def children(self): - if self.sentinel: - yield 'sentinel', 'yes' - yield 'prev', self.prev - yield 'next', self.next + def children(self): + if self.sentinel: + yield "sentinel", "yes" + yield "prev", self.prev + yield "next", self.next + class IlistPrinter: - """Print an llvm::simple_ilist or llvm::iplist object.""" + """Print an llvm::simple_ilist or llvm::iplist object.""" - def __init__(self, val): - self.node_type = val.type.template_argument(0) - sentinel = val['Sentinel'] - # First field is common base type of sentinel and ilist_node. - base_type = sentinel.type.fields()[0].type - self.sentinel = sentinel.address.cast(base_type.pointer()) + def __init__(self, val): + self.node_type = val.type.template_argument(0) + sentinel = val["Sentinel"] + # First field is common base type of sentinel and ilist_node. + base_type = sentinel.type.fields()[0].type + self.sentinel = sentinel.address.cast(base_type.pointer()) - def _pointers(self): - pointer = self.sentinel - while True: - pointer = pointer['Next'].cast(pointer.type) - if pointer == self.sentinel: - return - yield pointer.cast(self.node_type.pointer()) + def _pointers(self): + pointer = self.sentinel + while True: + pointer = pointer["Next"].cast(pointer.type) + if pointer == self.sentinel: + return + yield pointer.cast(self.node_type.pointer()) - def children(self): - for k, v in enumerate(self._pointers()): - yield ('[%d]' % k, v.dereference()) + def children(self): + for k, v in enumerate(self._pointers()): + yield ("[%d]" % k, v.dereference()) pp = gdb.printing.RegexpCollectionPrettyPrinter("LLVMSupport") -pp.add_printer('llvm::SmallString', '^llvm::SmallString<.*>$', SmallStringPrinter) -pp.add_printer('llvm::StringRef', '^llvm::StringRef$', StringRefPrinter) -pp.add_printer('llvm::SmallVectorImpl', '^llvm::SmallVector(Impl)?<.*>$', SmallVectorPrinter) -pp.add_printer('llvm::ArrayRef', '^llvm::(Mutable)?ArrayRef<.*>$', ArrayRefPrinter) -pp.add_printer('llvm::Expected', '^llvm::Expected<.*>$', ExpectedPrinter) -pp.add_printer('llvm::Optional', '^llvm::Optional<.*>$', OptionalPrinter) -pp.add_printer('llvm::DenseMap', '^llvm::DenseMap<.*>$', DenseMapPrinter) -pp.add_printer('llvm::StringMap', '^llvm::StringMap<.*>$', StringMapPrinter) -pp.add_printer('llvm::Twine', '^llvm::Twine$', TwinePrinter) -pp.add_printer('llvm::PointerIntPair', '^llvm::PointerIntPair<.*>$', make_pointer_int_pair_printer) -pp.add_printer('llvm::PointerUnion', '^llvm::PointerUnion<.*>$', make_pointer_union_printer) -pp.add_printer('llvm::ilist_node', '^llvm::ilist_node<.*>$', IlistNodePrinter) -pp.add_printer('llvm::iplist', '^llvm::iplist<.*>$', IlistPrinter) -pp.add_printer('llvm::simple_ilist', '^llvm::simple_ilist<.*>$', IlistPrinter) +pp.add_printer("llvm::SmallString", "^llvm::SmallString<.*>$", SmallStringPrinter) +pp.add_printer("llvm::StringRef", "^llvm::StringRef$", StringRefPrinter) +pp.add_printer( + "llvm::SmallVectorImpl", "^llvm::SmallVector(Impl)?<.*>$", SmallVectorPrinter +) +pp.add_printer("llvm::ArrayRef", "^llvm::(Mutable)?ArrayRef<.*>$", ArrayRefPrinter) +pp.add_printer("llvm::Expected", "^llvm::Expected<.*>$", ExpectedPrinter) +pp.add_printer("llvm::Optional", "^llvm::Optional<.*>$", OptionalPrinter) +pp.add_printer("llvm::DenseMap", "^llvm::DenseMap<.*>$", DenseMapPrinter) +pp.add_printer("llvm::StringMap", "^llvm::StringMap<.*>$", StringMapPrinter) +pp.add_printer("llvm::Twine", "^llvm::Twine$", TwinePrinter) +pp.add_printer( + "llvm::PointerIntPair", "^llvm::PointerIntPair<.*>$", make_pointer_int_pair_printer +) +pp.add_printer( + "llvm::PointerUnion", "^llvm::PointerUnion<.*>$", make_pointer_union_printer +) +pp.add_printer("llvm::ilist_node", "^llvm::ilist_node<.*>$", IlistNodePrinter) +pp.add_printer("llvm::iplist", "^llvm::iplist<.*>$", IlistPrinter) +pp.add_printer("llvm::simple_ilist", "^llvm::simple_ilist<.*>$", IlistPrinter) gdb.printing.register_pretty_printer(gdb.current_objfile(), pp)