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/Support/PointerLikeTypeTraits.h b/llvm/include/llvm/Support/PointerLikeTypeTraits.h --- a/llvm/include/llvm/Support/PointerLikeTypeTraits.h +++ b/llvm/include/llvm/Support/PointerLikeTypeTraits.h @@ -56,7 +56,7 @@ static inline void *getAsVoidPointer(T *P) { return P; } static inline T *getFromVoidPointer(void *P) { return static_cast(P); } - enum { NumLowBitsAvailable = detail::ConstantLog2::value }; + static const int NumLowBitsAvailable = detail::ConstantLog2::value; }; template <> struct PointerLikeTypeTraits { @@ -70,7 +70,7 @@ /// /// All clients should use assertions to do a run-time check to ensure that /// this is actually true. - enum { NumLowBitsAvailable = 2 }; + static const int NumLowBitsAvailable = 2; }; // Provide PointerLikeTypeTraits for const things. @@ -83,7 +83,7 @@ static inline const T getFromVoidPointer(const void *P) { return NonConst::getFromVoidPointer(const_cast(P)); } - enum { NumLowBitsAvailable = NonConst::NumLowBitsAvailable }; + static const int NumLowBitsAvailable = NonConst::NumLowBitsAvailable; }; // Provide PointerLikeTypeTraits for const pointers. @@ -96,7 +96,7 @@ static inline const T *getFromVoidPointer(const void *P) { return NonConst::getFromVoidPointer(const_cast(P)); } - enum { NumLowBitsAvailable = NonConst::NumLowBitsAvailable }; + static const int NumLowBitsAvailable = NonConst::NumLowBitsAvailable; }; // Provide PointerLikeTypeTraits for uintptr_t. @@ -108,7 +108,7 @@ return reinterpret_cast(P); } // No bits are available! - enum { NumLowBitsAvailable = 0 }; + static const int NumLowBitsAvailable = 0; }; /// Provide suitable custom traits struct for function pointers. @@ -121,7 +121,7 @@ /// potentially use alignment attributes on functions to satisfy that. template struct FunctionPointerLikeTypeTraits { - enum { NumLowBitsAvailable = detail::ConstantLog2::value }; + static const int NumLowBitsAvailable = detail::ConstantLog2::value; static inline void *getAsVoidPointer(FunctionPointerT P) { assert((reinterpret_cast(P) & ~((uintptr_t)-1 << NumLowBitsAvailable)) == 0 && 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,40 @@ 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) + name = val.type.template_argument(3).name + '::NumLowBitsAvailable' + bits_available = int(gdb.lookup_symbol(name)[0].value()) + int_mask = (1 << bits_available) - 1 + int_shift = bits_available - val.type.template_argument(1) + pair_union = val['Value'] + self.pointer = (pair_union & ~int_mask).cast(pointer_type) + self.value = ((pair_union & int_mask) >> int_shift).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 +358,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)