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/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 = ((1 << (64 - 3)) - 1) << 3 + + 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)