Change to individual pretty printer classes, remove generic `make_printer`.
authorChristian Sigg <csigg@google.com>
Wed, 29 Jan 2020 08:57:54 +0000 (09:57 +0100)
committerChristian Sigg <csigg@google.com>
Wed, 11 Mar 2020 14:04:03 +0000 (15:04 +0100)
Summary: Follow-up from D72589.

Reviewers: dblaikie

Reviewed By: dblaikie

Subscribers: merge_guards_bot, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D73609

debuginfo-tests/llvm-prettyprinters/gdb/llvm-support.cpp
debuginfo-tests/llvm-prettyprinters/gdb/llvm-support.gdb
llvm/utils/gdb-scripts/prettyprinters.py

index 7e0f193..04c84cd 100644 (file)
@@ -24,7 +24,13 @@ llvm::SmallString<5> SmallString("foo");
 llvm::StringRef StringRef = "bar";
 llvm::Twine Twine = llvm::Twine(SmallString) + StringRef;
 llvm::PointerIntPair<int *, 1> PointerIntPair(IntPtr, 1);
-llvm::PointerUnion<float *, int *> PointerUnion(IntPtr);
+
+struct alignas(8) Z {};
+llvm::PointerUnion<Z *, int *> PointerUnion(IntPtr);
+
+// No members which instantiate PointerUnionUIntTraits<Z *> (e.g. get<T *>())
+// are called, and this instance will therefore be raw-printed.
+llvm::PointerUnion<Z *, float *> RawPrintingPointerUnion(nullptr);
 
 using IlistTag = llvm::ilist_tag<struct A>;
 using SimpleIlistTag = llvm::ilist_tag<struct B>;
index c02c03c..fa1e2aa 100644 (file)
@@ -1,4 +1,4 @@
-# RUN: gdb -q -batch -n -iex 'source %llvm_src_root/utils/gdb-scripts/prettyprinters.py' -x %s %llvm_tools_dir/check-gdb-llvm-support | FileCheck %s
+# RUN: gdb -q -batch -n -iex 'source %llvm_src_root/utils/gdb-scripts/prettyprinters.py' -x %s %llvm_tools_dir/check-gdb-llvm-support | FileCheck %s --dump-input-on-failure
 
 break main
 run
@@ -39,12 +39,15 @@ p StringRef
 # CHECK: "\"foo\"\"bar\""
 p Twine
 
-# CHECK: llvm::PointerIntPair<int *> = {pointer = 0xabc, value = 1}
+# CHECK: {pointer = 0xabc, value = 1}
 p PointerIntPair
 
-# CHECK: llvm::PointerUnion containing int * = {pointer = 0xabc}
+# CHECK: Containing int * = {pointer = 0xabc}
 p PointerUnion
 
+# CHECK: PointerUnionMembers<llvm::PointerUnion<Z*, float*>,
+p RawPrintingPointerUnion
+
 # Switch to print pretty adds newlines to the following statements.
 set print pretty
 
index 963be17..1a61321 100644 (file)
@@ -316,25 +316,12 @@ class TwinePrinter:
   def to_string(self):
     return self.string_from_twine_object(self._val)
 
-def make_printer(string = None, children = None, hint = None):
-  """Create a printer from the parameters."""
-  class Printer : pass
-  printer = Printer()
-  if string:
-    setattr(printer, 'to_string', lambda: string)
-  if children:
-    setattr(printer, 'children', lambda: children)
-  if hint:
-    setattr(printer, 'display_hint', lambda: hint)
-  return printer
-
 def get_pointer_int_pair(val):
   """Get tuple from llvm::PointerIntPair."""
   info_name = val.type.template_argument(4).strip_typedefs().name
-  try:
-    enum_type = gdb.lookup_type(info_name + '::MaskAndShiftConstants')
-  except gdb.error:
-    return (None, None)
+  # Note: this throws a gdb.error if the info type is not used (by means of a
+  # call to getPointer() or similar) in the current translation unit.
+  enum_type = gdb.lookup_type(info_name + '::MaskAndShiftConstants')
   enum_dict = gdb.types.make_enum_dict(enum_type)
   ptr_mask = enum_dict[info_name + '::PointerBitMask']
   int_shift = enum_dict[info_name + '::IntShift']
@@ -344,26 +331,48 @@ def get_pointer_int_pair(val):
   value = ((pair_union >> int_shift) & int_mask)
   return (pointer, value)
 
+class PointerIntPairPrinter:
+  """Print a PointerIntPair."""
+
+  def __init__(self, pointer, value):
+    self.pointer = pointer
+    self.value = value
+
+  def children(self):
+    yield ('pointer', self.pointer)
+    yield ('value', self.value)
+
 def make_pointer_int_pair_printer(val):
   """Factory for an llvm::PointerIntPair printer."""
-  pointer, value = get_pointer_int_pair(val)
-  if not pointer or not value:
-    return None
+  try:
+    pointer, value = get_pointer_int_pair(val)
+  except gdb.error:
+    return None  # If PointerIntPair cannot be analyzed, print as raw value.
   pointer_type = val.type.template_argument(0)
   value_type = val.type.template_argument(2)
-  string = 'llvm::PointerIntPair<%s>' % pointer_type
-  children = [('pointer', pointer.cast(pointer_type)),
-              ('value', value.cast(value_type))]
-  return make_printer(string, children)
+  return PointerIntPairPrinter(pointer.cast(pointer_type),
+                               value.cast(value_type))
+
+class PointerUnionPrinter:
+  """Print a PointerUnion."""
+
+  def __init__(self, pointer):
+    self.pointer = pointer
+
+  def children(self):
+    yield ('pointer', self.pointer)
+
+  def to_string(self):
+    return "Containing %s" % self.pointer.type
 
 def make_pointer_union_printer(val):
   """Factory for an llvm::PointerUnion printer."""
-  pointer, value = get_pointer_int_pair(val['Val'])
-  if not pointer or not value:
-    return None
+  try:
+    pointer, value = get_pointer_int_pair(val['Val'])
+  except gdb.error:
+    return None  # If PointerIntPair cannot be analyzed, print as raw value.
   pointer_type = val.type.template_argument(int(value))
-  string = 'llvm::PointerUnion containing %s' % pointer_type
-  return make_printer(string, [('pointer', pointer.cast(pointer_type))])
+  return PointerUnionPrinter(pointer.cast(pointer_type))
 
 class IlistNodePrinter:
   """Print an llvm::ilist_node object."""