diff --git a/debuginfo-tests/llvm-prettyprinters/gdb/llvm-support.cpp b/debuginfo-tests/llvm-prettyprinters/gdb/llvm-support.cpp --- a/debuginfo-tests/llvm-prettyprinters/gdb/llvm-support.cpp +++ b/debuginfo-tests/llvm-prettyprinters/gdb/llvm-support.cpp @@ -5,6 +5,7 @@ #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/Twine.h" #include "llvm/ADT/ilist.h" #include "llvm/Support/Error.h" @@ -15,6 +16,7 @@ llvm::ArrayRef ArrayRef(Array); llvm::MutableArrayRef MutableArrayRef(Array); llvm::DenseMap DenseMap = {{4, 5}, {6, 7}}; +llvm::StringMap StringMap = {{"foo", 123}, {"bar", 456}}; llvm::Expected ExpectedValue(8); llvm::Expected ExpectedError(llvm::createStringError({}, "")); llvm::Optional OptionalValue(9); diff --git a/debuginfo-tests/llvm-prettyprinters/gdb/llvm-support.gdb b/debuginfo-tests/llvm-prettyprinters/gdb/llvm-support.gdb --- a/debuginfo-tests/llvm-prettyprinters/gdb/llvm-support.gdb +++ b/debuginfo-tests/llvm-prettyprinters/gdb/llvm-support.gdb @@ -40,6 +40,9 @@ # CHECK: "\"foo\"\"bar\"" p Twine +# CHECK: llvm::StringMap with 2 elements = {["foo"] = 123, ["bar"] = 456} +p StringMap + # CHECK: {pointer = 0xabc, value = 1} p PointerIntPair diff --git a/llvm/include/llvm/ADT/StringMap.h b/llvm/include/llvm/ADT/StringMap.h --- a/llvm/include/llvm/ADT/StringMap.h +++ b/llvm/include/llvm/ADT/StringMap.h @@ -78,10 +78,12 @@ void init(unsigned Size); public: + static constexpr uintptr_t TombstoneIntVal = + static_cast(-1) + << PointerLikeTypeTraits::NumLowBitsAvailable; + static StringMapEntryBase *getTombstoneVal() { - uintptr_t Val = static_cast(-1); - Val <<= PointerLikeTypeTraits::NumLowBitsAvailable; - return reinterpret_cast(Val); + return reinterpret_cast(TombstoneIntVal); } unsigned getNumBuckets() const { return NumBuckets; } 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 @@ -1,4 +1,5 @@ from __future__ import print_function +import struct import sys import gdb.printing @@ -200,6 +201,44 @@ def display_hint(self): return 'map' +class StringMapPrinter: + "Print a StringMap" + + 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_ty = gdb.lookup_type('llvm::StringMapEntry<{}>'.format(value_ty.name)) + 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 + + entry_ptr = it_deref.cast(entry_ty.pointer()) + entry = entry_ptr.dereference() + + str_len = entry['keyLength'] + str_data = (entry_ptr + 1).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 = entry['second'] + yield 'value', value + + it = it + 1 + + def to_string(self): + return 'llvm::StringMap with %d elements' % (self.val['NumItems']) + + def display_hint(self): + return 'map' + class TwinePrinter: "Print a Twine" @@ -442,6 +481,7 @@ 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)