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,6 +1,8 @@ #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" @@ -19,7 +21,7 @@ llvm::SmallString<5> SmallString("foo"); llvm::StringRef StringRef = "bar"; llvm::Twine Twine = llvm::Twine(SmallString) + StringRef; +llvm::PointerIntPair PointerIntPair(Array, 1); +llvm::PointerUnion PointerUnion(Array); -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 = {{.*}}, value = 1} +p PointerIntPair + +# CHECK: llvm::PointerUnion containing int * = {pointer = {{.*}}} +p PointerUnion + + 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 @@ -315,6 +315,43 @@ 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) + try: + name = val.type.template_argument(3).name + '::NumLowBitsAvailable' + bits_available = gdb.parse_and_eval(name) + except: + # Above fails if NumLowBitsAvailable is an enum or is optimized away. + bits_available = pointer_type.target().alignof.bit_length() - 1 + value_mask = (1 << bits_available) - 1 + value_shift = bits_available - val.type.template_argument(1) + value = val['Value'] + self.pointer = (value & ~value_mask).cast(pointer_type) + self.value = (value & value_mask) >> value_shift + + 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) +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)