summaryrefslogtreecommitdiff
path: root/utils/gdb-scripts/prettyprinters.py
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2018-07-28 10:51:19 +0000
committerDimitry Andric <dim@FreeBSD.org>2018-07-28 10:51:19 +0000
commiteb11fae6d08f479c0799db45860a98af528fa6e7 (patch)
tree44d492a50c8c1a7eb8e2d17ea3360ec4d066f042 /utils/gdb-scripts/prettyprinters.py
parentb8a2042aa938069e862750553db0e4d82d25822c (diff)
Notes
Diffstat (limited to 'utils/gdb-scripts/prettyprinters.py')
-rw-r--r--utils/gdb-scripts/prettyprinters.py127
1 files changed, 66 insertions, 61 deletions
diff --git a/utils/gdb-scripts/prettyprinters.py b/utils/gdb-scripts/prettyprinters.py
index 1a549f875d44..918411db42fb 100644
--- a/utils/gdb-scripts/prettyprinters.py
+++ b/utils/gdb-scripts/prettyprinters.py
@@ -1,4 +1,19 @@
import gdb.printing
+
+class Iterator:
+ def __iter__(self):
+ return self
+
+ # Python 2 compatibility
+ def next(self):
+ return self.__next__()
+
+ def children(self):
+ return self
+
+def escape_bytes(val, l):
+ return '"' + val.string(encoding='Latin-1', length=l).encode('unicode_escape').decode() + '"'
+
class SmallStringPrinter:
"""Print an llvm::SmallString object."""
@@ -7,11 +22,7 @@ class SmallStringPrinter:
def to_string(self):
begin = self.val['BeginX']
- end = self.val['EndX']
- return begin.cast(gdb.lookup_type("char").pointer()).string(length = end - begin)
-
- def display_hint (self):
- return 'string'
+ return escape_bytes(begin.cast(gdb.lookup_type('char').pointer()), self.val['Size'])
class StringRefPrinter:
"""Print an llvm::StringRef object."""
@@ -20,49 +31,27 @@ class StringRefPrinter:
self.val = val
def to_string(self):
- return self.val['Data'].string(length = self.val['Length'])
-
- def display_hint (self):
- return 'string'
+ return escape_bytes(self.val['Data'], self.val['Length'])
-class SmallVectorPrinter:
+class SmallVectorPrinter(Iterator):
"""Print an llvm::SmallVector object."""
- class _iterator:
- def __init__(self, begin, end):
- self.cur = begin
- self.end = end
- self.count = 0
-
- def __iter__(self):
- return self
-
- def next(self):
- if self.cur == self.end:
- raise StopIteration
- count = self.count
- self.count = self.count + 1
- cur = self.cur
- self.cur = self.cur + 1
- return '[%d]' % count, cur.dereference()
-
- __next__ = next
-
def __init__(self, val):
self.val = val
-
- def children(self):
- t = self.val.type.template_argument(0).pointer()
- begin = self.val['BeginX'].cast(t)
- end = self.val['EndX'].cast(t)
- return self._iterator(begin, end)
+ t = val.type.template_argument(0).pointer()
+ self.begin = val['BeginX'].cast(t)
+ self.size = val['Size']
+ self.i = 0
+
+ def __next__(self):
+ if self.i == self.size:
+ raise StopIteration
+ ret = '[{}]'.format(self.i), (self.begin+self.i).dereference()
+ self.i += 1
+ return ret
def to_string(self):
- t = self.val.type.template_argument(0).pointer()
- begin = self.val['BeginX'].cast(t)
- end = self.val['EndX'].cast(t)
- capacity = self.val['CapacityX'].cast(t)
- return 'llvm::SmallVector of length %d, capacity %d' % (end - begin, capacity - begin)
+ return 'llvm::SmallVector of Size {}, Capacity {}'.format(self.size, self.val['Capacity'])
def display_hint (self):
return 'array'
@@ -93,6 +82,8 @@ class ArrayRefPrinter:
def __init__(self, val):
self.val = val
+ __next__ = next
+
def children(self):
data = self.val['Data']
return self._iterator(data, data + self.val['Length'])
@@ -103,33 +94,44 @@ class ArrayRefPrinter:
def display_hint (self):
return 'array'
-class OptionalPrinter:
- """Print an llvm::Optional object."""
+class ExpectedPrinter(Iterator):
+ """Print an llvm::Expected object."""
+
+ def __init__(self, val):
+ self.val = val
- def __init__(self, value):
- self.value = value
+ def __next__(self):
+ val = self.val
+ if val is None:
+ raise StopIteration
+ self.val = None
+ if val['HasError']:
+ return ('error', val['ErrorStorage'].address.cast(
+ gdb.lookup_type('llvm::ErrorInfoBase').pointer()).dereference())
+ return ('value', val['TStorage'].address.cast(
+ val.type.template_argument(0).pointer()).dereference())
- class _iterator:
- def __init__(self, member, empty):
- self.member = member
- self.done = empty
+ def to_string(self):
+ return 'llvm::Expected{}'.format(' is error' if self.val['HasError'] else '')
- def __iter__(self):
- return self
+class OptionalPrinter(Iterator):
+ """Print an llvm::Optional object."""
- def next(self):
- if self.done:
- raise StopIteration
- self.done = True
- return ('value', self.member.dereference())
+ def __init__(self, val):
+ self.val = val
- def children(self):
- if not self.value['hasVal']:
- return self._iterator('', True)
- return self._iterator(self.value['storage']['buffer'].address.cast(self.value.type.template_argument(0).pointer()), False)
+ def __next__(self):
+ val = self.val
+ if val is None:
+ raise StopIteration
+ self.val = None
+ if not val['Storage']['hasVal']:
+ raise StopIteration
+ return ('value', val['Storage']['storage']['buffer'].address.cast(
+ val.type.template_argument(0).pointer()).dereference())
def to_string(self):
- return 'llvm::Optional is %sinitialized' % ('' if self.value['hasVal'] else 'not ')
+ return 'llvm::Optional{}'.format('' if self.val['Storage']['hasVal'] else ' is not initialized')
class DenseMapPrinter:
"Print a DenseMap"
@@ -178,6 +180,8 @@ class DenseMapPrinter:
self.first = False
return 'x', v
+ __next__ = next
+
def __init__(self, val):
self.val = val
@@ -314,6 +318,7 @@ pp.add_printer('llvm::SmallString', '^llvm::SmallString<.*>$', SmallStringPrinte
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::Expected', '^llvm::Expected<.*>$', ExpectedPrinter)
pp.add_printer('llvm::Optional', '^llvm::Optional<.*>$', OptionalPrinter)
pp.add_printer('llvm::DenseMap', '^llvm::DenseMap<.*>$', DenseMapPrinter)
pp.add_printer('llvm::Twine', '^llvm::Twine$', TwinePrinter)