import gdb.printing
+
+class Iterator:
+ def __iter__(self):
+ return self
+
+ # Python 2 compatibility
+ def next(self):
+ return self.__next__()
+
+ def children(self):
+ return self
+
+
class SmallStringPrinter:
"""Print an llvm::SmallString object."""
def display_hint (self):
return 'array'
-class OptionalPrinter:
- """Print an llvm::Optional object."""
+class ExpectedPrinter(Iterator):
+ """Print an llvm::Expected object."""
- def __init__(self, value):
- self.value = value
+ def __init__(self, val):
+ self.val = val
- class _iterator:
- def __init__(self, member, empty):
- self.member = member
- self.done = empty
+ 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())
- def __iter__(self):
- return self
+ def to_string(self):
+ return 'llvm::Expected{}'.format(' is error' if self.val['HasError'] else '')
- def next(self):
- if self.done:
- raise StopIteration
- self.done = True
- return ('value', self.member.dereference())
+class OptionalPrinter(Iterator):
+ """Print an llvm::Optional object."""
- def children(self):
- if not self.value['Storage']['hasVal']:
- return self._iterator('', True)
- return self._iterator(self.value['Storage']['storage']['buffer'].address.cast(
- self.value.type.template_argument(0).pointer()), False)
+ def __init__(self, val):
+ self.val = val
+
+ 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['Storage']['hasVal'] else 'not ')
+ return 'llvm::Optional{}'.format('' if self.val['Storage']['hasVal'] else ' is not initialized')
class DenseMapPrinter:
"Print a DenseMap"
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)