diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 10:51:19 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 10:51:19 +0000 |
commit | eb11fae6d08f479c0799db45860a98af528fa6e7 (patch) | |
tree | 44d492a50c8c1a7eb8e2d17ea3360ec4d066f042 /utils/gdb-scripts/prettyprinters.py | |
parent | b8a2042aa938069e862750553db0e4d82d25822c (diff) |
Notes
Diffstat (limited to 'utils/gdb-scripts/prettyprinters.py')
-rw-r--r-- | utils/gdb-scripts/prettyprinters.py | 127 |
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) |