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,60 @@ def display_hint(self): return 'map' +class StringMapPrinter: + "Print a StringMap" + + class _iterator: + def __init__(self, entry_ty, begin, end): + self.entry_ty = entry_ty + self.cur = begin + self.end = end + self.advancePastEmptyBuckets() + self.first = True + + def __iter__(self): + return self + + def advancePastEmptyBuckets(self): + tombstone = ((1 << (64 - 3)) - 1) << 3 + while self.cur != self.end and (self.cur.dereference() == 0 or self.cur.dereference() == tombstone): + self.cur = self.cur + 1 + + def __next__(self): + if self.cur == self.end: + raise StopIteration + entry_ptr = self.cur.dereference().cast(self.entry_ty.pointer()) + entry = entry_ptr.dereference() + if self.first: + 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')) + value = string_ref + else: + value = entry['second'] + self.cur = self.cur + 1 + self.advancePastEmptyBuckets() + + self.first = not self.first + + return 'x', value + + def __init__(self, val): + self.val = val + + def children(self): + begin = self.val['TheTable'] + end = (begin + self.val['NumBuckets']) + value_ty = self.val.type.template_argument(0) + entry_ty = gdb.lookup_type('llvm::StringMapEntry<{}>'.format(value_ty.name)) + return self._iterator(entry_ty, begin, end) + + 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 +497,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)