Index: utils/gdb-scripts/prettyprinters.py =================================================================== --- utils/gdb-scripts/prettyprinters.py +++ utils/gdb-scripts/prettyprinters.py @@ -193,7 +193,96 @@ def display_hint(self): return 'map' +class TwinePrinter: + "Print a Twine" + def __init__(self, val): + self._val = val + + def display_hint(self): + return 'string' + + 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.''' + + pp = gdb.default_visualizer(val) + if pp: + s = pp.to_string() + else: + print(('No pretty printer for {} found. The resulting Twine ' + + 'representation will be incomplete.').format(val.type.name)) + s = '<{}>'.format(val.type.name) + + return s + + def string_from_child(self, child, kind): + '''Return the string representation of the Twine::Child child.''' + + s = '' + + if kind in ('llvm::Twine::EmptyKind', 'llvm::Twine::NullKind'): + pass + elif kind == 'llvm::Twine::TwineKind': + s = self.string_from_twine_object(child['twine'].dereference()) + elif kind == 'llvm::Twine::CStringKind': + s = child['cString'].string() + elif kind == 'llvm::Twine::StdStringKind': + val = child['stdString'].dereference() + s = self.string_from_pretty_printer_lookup(val).value().address.string() + elif kind == 'llvm::Twine::StringRefKind': + val = child['stringRef'].dereference() + pp = StringRefPrinter(val) + s = pp.to_string() + elif kind == 'llvm::Twine::SmallStringKind': + val = child['smallString'].dereference() + pp = SmallStringPrinter(val) + s = pp.to_string() + elif kind == 'llvm::Twine::CharKind': + s = chr(child['character']) + elif kind == 'llvm::Twine::DecUIKind': + s = str(child['decUI']) + elif kind == 'llvm::Twine::DecIKind': + s = str(child['decI']) + elif kind == 'llvm::Twine::DecULKind': + s = str(child['decUL'].dereference()) + elif kind == 'llvm::Twine::DecLKind': + s = str(child['decL'].dereference()) + elif kind == 'llvm::Twine::DecULLKind': + s = str(child['decULL'].dereference()) + elif kind == 'llvm::Twine::DecLLKind': + s = str(child['decLL'].dereference()) + elif kind == 'llvm::Twine::UHexKind': + val = child['uHex'].dereference() + s = hex(int(val)) + else: + print(('Unsupported NodeKind {} in Twine pretty-printer. The result will ' + 'be incomplete.').format(kind)) + s = '<{}>'.format(kind) + + return s + + def string_from_twine_object(self, twine): + '''Return the string representation of the Twine object twine.''' + + lhs_str = '' + rhs_str = '' + + lhs = twine['LHS'] + rhs = twine['RHS'] + 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) + + return lhs_str + rhs_str + + def to_string(self): + return self.string_from_twine_object(self._val) + pp = gdb.printing.RegexpCollectionPrettyPrinter("LLVMSupport") pp.add_printer('llvm::SmallString', '^llvm::SmallString<.*>$', SmallStringPrinter) pp.add_printer('llvm::StringRef', '^llvm::StringRef$', StringRefPrinter) @@ -201,4 +290,5 @@ pp.add_printer('llvm::ArrayRef', '^llvm::(Const)?ArrayRef<.*>$', ArrayRefPrinter) pp.add_printer('llvm::Optional', '^llvm::Optional<.*>$', OptionalPrinter) pp.add_printer('llvm::DenseMap', '^llvm::DenseMap<.*>$', DenseMapPrinter) +pp.add_printer('llvm::Twine', '^llvm::Twine$', TwinePrinter) gdb.printing.register_pretty_printer(gdb.current_objfile(), pp)