diff --git a/debuginfo-tests/llvm-prettyprinters/gdb/prettyprinters.cpp b/debuginfo-tests/llvm-prettyprinters/gdb/prettyprinters.cpp --- a/debuginfo-tests/llvm-prettyprinters/gdb/prettyprinters.cpp +++ b/debuginfo-tests/llvm-prettyprinters/gdb/prettyprinters.cpp @@ -1,12 +1,15 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Optional.h" +#include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/Error.h" int Array[] = {1, 2, 3}; +auto IntPtr = reinterpret_cast(0xabc); llvm::ArrayRef ArrayRef(Array); llvm::MutableArrayRef MutableArrayRef(Array); @@ -19,7 +22,7 @@ llvm::SmallString<5> SmallString("foo"); llvm::StringRef StringRef = "bar"; llvm::Twine Twine = llvm::Twine(SmallString) + StringRef; +llvm::PointerIntPair PointerIntPair(IntPtr, 1); +llvm::PointerUnion PointerUnion(IntPtr); -int main() { - return 0; -} +int main() { return 0; } diff --git a/debuginfo-tests/llvm-prettyprinters/gdb/prettyprinters.gdb b/debuginfo-tests/llvm-prettyprinters/gdb/prettyprinters.gdb --- a/debuginfo-tests/llvm-prettyprinters/gdb/prettyprinters.gdb +++ b/debuginfo-tests/llvm-prettyprinters/gdb/prettyprinters.gdb @@ -39,3 +39,10 @@ # CHECK: "\"foo\"\"bar\"" p Twine +# CHECK: llvm::PointerIntPair = {pointer = 0xabc, value = 1} +p PointerIntPair + +# CHECK: llvm::PointerUnion containing int * = {pointer = 0xabc} +p PointerUnion + + diff --git a/llvm/include/llvm/ADT/PointerIntPair.h b/llvm/include/llvm/ADT/PointerIntPair.h --- a/llvm/include/llvm/ADT/PointerIntPair.h +++ b/llvm/include/llvm/ADT/PointerIntPair.h @@ -147,7 +147,7 @@ "cannot use a pointer type that has all bits free"); static_assert(IntBits <= PtrTraits::NumLowBitsAvailable, "PointerIntPair with integer size too large for pointer"); - enum : uintptr_t { + enum MaskAndShiftConstants : uintptr_t { /// PointerBitMask - The bits that come from the pointer. PointerBitMask = ~(uintptr_t)(((intptr_t)1 << PtrTraits::NumLowBitsAvailable) - 1), diff --git a/llvm/utils/gdb-scripts/prettyprinters.py b/llvm/utils/gdb-scripts/prettyprinters.py --- a/llvm/utils/gdb-scripts/prettyprinters.py +++ b/llvm/utils/gdb-scripts/prettyprinters.py @@ -2,6 +2,7 @@ import sys import gdb.printing +import gdb.types class Iterator: def __iter__(self): @@ -315,6 +316,42 @@ def to_string(self): return self.string_from_twine_object(self._val) +class PointerIntPairPrinter: + """Print an llvm::PointerIntPair object.""" + + def __init__(self, val): + pointer_type = val.type.template_argument(0) + int_type = val.type.template_argument(2) + info_name = val.type.template_argument(4).name + 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'] + self.pointer = (pair_union & ptr_mask).cast(pointer_type) + self.value = ((pair_union >> int_shift) & int_mask).cast(int_type) + + def children(self): + return [('pointer', self.pointer), ('value', self.value)] + + def to_string(self): + return 'llvm::PointerIntPair' + +class PointerUnionPrinter: + """Print an llvm::PointerUnion object.""" + + def __init__(self, val): + pair_printer = PointerIntPairPrinter(val['Val']) + pointer_type = val.type.template_argument(int(pair_printer.value)) + self.pointer = pair_printer.pointer.cast(pointer_type) + + def children(self): + return [('pointer', self.pointer)] + + def to_string(self): + return 'llvm::PointerUnion containing %s' % self.pointer.type + pp = gdb.printing.RegexpCollectionPrettyPrinter("LLVMSupport") pp.add_printer('llvm::SmallString', '^llvm::SmallString<.*>$', SmallStringPrinter) pp.add_printer('llvm::StringRef', '^llvm::StringRef$', StringRefPrinter) @@ -324,4 +361,6 @@ 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) +pp.add_printer('llvm::PointerIntPair', '^llvm::PointerIntPair<.*>$', PointerIntPairPrinter) +pp.add_printer('llvm::PointerUnion', '^llvm::PointerUnion<.*>$', PointerUnionPrinter) +gdb.printing.register_pretty_printer(gdb.current_objfile(), pp, True)