[llvm] r290011 - GDB pretty printers: Basic DenseMap support

David Blaikie via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 16 15:53:15 PST 2016


Author: dblaikie
Date: Fri Dec 16 17:53:14 2016
New Revision: 290011

URL: http://llvm.org/viewvc/llvm-project?rev=290011&view=rev
Log:
GDB pretty printers: Basic DenseMap support

Still prints the empty/tombstone keys (which some people would prefer,
but I find pretty noisy) because I haven't yet found a reliable way to
skip them (it requires calling into the running process to do so, which
isn't ideal for a pretty printer (doesn't work on a core file, for
example) - and gdb's ability to do so (or my ability to figure out how
to get gdb to do so) is limited) left some breadcrumbs for the next
person who might try to address that.

Modified:
    llvm/trunk/utils/gdb-scripts/prettyprinters.py

Modified: llvm/trunk/utils/gdb-scripts/prettyprinters.py
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/gdb-scripts/prettyprinters.py?rev=290011&r1=290010&r2=290011&view=diff
==============================================================================
--- llvm/trunk/utils/gdb-scripts/prettyprinters.py (original)
+++ llvm/trunk/utils/gdb-scripts/prettyprinters.py Fri Dec 16 17:53:14 2016
@@ -131,10 +131,74 @@ class OptionalPrinter:
   def to_string(self):
     return 'llvm::Optional is %sinitialized' % ('' if self.value['hasVal'] else 'not ')
 
+class DenseMapPrinter:
+  "Print a DenseMap"
+
+  class _iterator:
+    def __init__(self, key_info_t, begin, end):
+      self.key_info_t = key_info_t
+      self.cur = begin
+      self.end = end
+      self.advancePastEmptyBuckets()
+      self.first = True
+
+    def __iter__(self):
+      return self
+
+    def advancePastEmptyBuckets(self):
+      # disabled until the comments below can be addressed
+      # keeping as notes/posterity/hints for future contributors
+      return
+      n = self.key_info_t.name
+      is_equal = gdb.parse_and_eval(n + '::isEqual')
+      empty = gdb.parse_and_eval(n + '::getEmptyKey()')
+      tombstone = gdb.parse_and_eval(n + '::getTombstoneKey()')
+      # the following is invalid, GDB fails with:
+      #   Python Exception <class 'gdb.error'> Attempt to take address of value
+      #   not located in memory.
+      # because isEqual took parameter (for the unsigned long key I was testing)
+      # by const ref, and GDB
+      # It's also not entirely general - we should be accessing the "getFirst()"
+      # member function, not the 'first' member variable, but I've yet to figure
+      # out how to find/call member functions (especially (const) overloaded
+      # ones) on a gdb.Value.
+      while self.cur != self.end and (is_equal(self.cur.dereference()['first'], empty) or is_equal(self.cur.dereference()['first'], tombstone)):
+        self.cur = self.cur + 1
+
+    def next(self):
+      if self.cur == self.end:
+        raise StopIteration
+      cur = self.cur
+      v = cur.dereference()['first' if self.first else 'second']
+      if not self.first:
+        self.cur = self.cur + 1
+        self.advancePastEmptyBuckets()
+        self.first = True
+      else:
+        self.first = False
+      return 'x', v
+
+  def __init__(self, val):
+    self.val = val
+
+  def children(self):
+    t = self.val.type.template_argument(3).pointer()
+    begin = self.val['Buckets'].cast(t)
+    end = (begin + self.val['NumBuckets']).cast(t)
+    return self._iterator(self.val.type.template_argument(2), begin, end)
+
+  def to_string(self):
+    return 'llvm::DenseMap with %d elements' % (self.val['NumEntries'])
+
+  def display_hint(self):
+    return 'map'
+
+
 pp = gdb.printing.RegexpCollectionPrettyPrinter("LLVMSupport")
 pp.add_printer('llvm::SmallString', '^llvm::SmallString<.*>$', SmallStringPrinter)
 pp.add_printer('llvm::StringRef', '^llvm::StringRef$', StringRefPrinter)
 pp.add_printer('llvm::SmallVectorImpl', '^llvm::SmallVector(Impl)?<.*>$', SmallVectorPrinter)
 pp.add_printer('llvm::ArrayRef', '^llvm::(Const)?ArrayRef<.*>$', ArrayRefPrinter)
 pp.add_printer('llvm::Optional', '^llvm::Optional<.*>$', OptionalPrinter)
+pp.add_printer('llvm::DenseMap', '^llvm::DenseMap<.*>$', DenseMapPrinter)
 gdb.printing.register_pretty_printer(gdb.current_objfile(), pp)




More information about the llvm-commits mailing list