diff options
Diffstat (limited to 'libstdc++-v3/python/libstdcxx/v6/printers.py')
-rw-r--r-- | libstdc++-v3/python/libstdcxx/v6/printers.py | 111 |
1 files changed, 108 insertions, 3 deletions
diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py index f7a7f9961a7..0bd793c0897 100644 --- a/libstdc++-v3/python/libstdcxx/v6/printers.py +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py @@ -218,7 +218,7 @@ class SmartPtrIterator(Iterator): return ('get()', val) class SharedPointerPrinter: - "Print a shared_ptr or weak_ptr" + "Print a shared_ptr, weak_ptr, atomic<shared_ptr>, or atomic<weak_ptr>" def __init__ (self, typename, val): self.typename = strip_versioned_namespace(typename) @@ -228,9 +228,21 @@ class SharedPointerPrinter: def children (self): return SmartPtrIterator(self.pointer) + # Return the _Sp_counted_base<>* that holds the refcounts. + def _get_refcounts (self): + if self.typename == 'std::atomic': + # A tagged pointer is stored as uintptr_t. + ptr_val = self.val['_M_refcount']['_M_val']['_M_i'] + ptr_val = ptr_val - (ptr_val % 2) # clear lock bit + ptr_type = find_type(self.val['_M_refcount'].type, 'pointer') + return ptr_val.cast(ptr_type) + return self.val['_M_refcount']['_M_pi'] + def to_string (self): state = 'empty' - refcounts = self.val['_M_refcount']['_M_pi'] + refcounts = self._get_refcounts() + targ = self.val.type.template_argument(0) + if refcounts != 0: usecount = refcounts['_M_use_count'] weakcount = refcounts['_M_weak_count'] @@ -238,7 +250,7 @@ class SharedPointerPrinter: state = 'expired, weak count %d' % weakcount else: state = 'use count %d, weak count %d' % (usecount, weakcount - 1) - return '%s<%s> (%s)' % (self.typename, str(self.val.type.template_argument(0)), state) + return '%s<%s> (%s)' % (self.typename, str(targ), state) def _tuple_impl_get(val): "Return the tuple element stored in a _Tuple_impl<N, T> base class." @@ -1654,6 +1666,94 @@ class StdRegexStatePrinter: s = "{}, {}={}".format(s, v, self.val['_M_' + v]) return "{%s}" % (s) +class StdSpanPrinter: + "Print a std::span" + + class iterator(Iterator): + def __init__(self, begin, size): + self.count = 0 + self.begin = begin + self.size = size + + def __iter__ (self): + return self + + def __next__ (self): + if self.count == self.size: + raise StopIteration + + count = self.count + self.count = self.count + 1 + return '[%d]' % count, (self.begin + count).dereference() + + def __init__(self, typename, val): + self.typename = typename + self.val = val + if val.type.template_argument(1) == gdb.parse_and_eval('static_cast<std::size_t>(-1)'): + self.size = val['_M_extent']['_M_extent_value'] + else: + self.size = val.type.template_argument(1) + + def to_string(self): + return '%s of length %d' % (self.typename, self.size) + + def children(self): + return self.iterator(self.val['_M_ptr'], self.size) + + def display_hint(self): + return 'array' + +class StdInitializerListPrinter: + "Print a std::initializer_list" + + def __init__(self, typename, val): + self.typename = typename + self.val = val + self.size = val['_M_len'] + + def to_string(self): + return '%s of length %d' % (self.typename, self.size) + + def children(self): + return StdSpanPrinter.iterator(self.val['_M_array'], self.size) + + def display_hint(self): + return 'array' + +class StdAtomicPrinter: + "Print a std:atomic" + + def __init__(self, typename, val): + self.typename = typename + self.val = val + self.shptr_printer = None + self.value_type = self.val.type.template_argument(0) + if self.value_type.tag is not None: + typ = strip_versioned_namespace(self.value_type.tag) + if typ.startswith('std::shared_ptr<') or typ.startswith('std::weak_ptr<'): + impl = val['_M_impl'] + self.shptr_printer = SharedPointerPrinter(typename, impl) + self.children = self._shptr_children + + def _shptr_children(self): + return SmartPtrIterator(self.shptr_printer.pointer) + + def to_string(self): + if self.shptr_printer is not None: + return self.shptr_printer.to_string() + + if self.value_type.code == gdb.TYPE_CODE_INT: + val = self.val['_M_i'] + elif self.value_type.code == gdb.TYPE_CODE_FLT: + val = self.val['_M_fp'] + elif self.value_type.code == gdb.TYPE_CODE_PTR: + val = self.val['_M_b']['_M_p'] + elif self.value_type.code == gdb.TYPE_CODE_BOOL: + val = self.val['_M_base']['_M_i'] + else: + val = self.val['_M_i'] + return '%s<%s> = { %s }' % (self.typename, str(self.value_type), val) + # A "regular expression" printer which conforms to the # "SubPrettyPrinter" protocol from gdb.printing. class RxPrinter(object): @@ -2119,6 +2219,10 @@ def build_libstdcxx_dictionary (): libstdcxx_printer.add_version('std::tr1::', 'unordered_multiset', Tr1UnorderedSetPrinter) + libstdcxx_printer.add_version('std::', 'initializer_list', + StdInitializerListPrinter) + libstdcxx_printer.add_version('std::', 'atomic', StdAtomicPrinter) + # std::regex components libstdcxx_printer.add_version('std::__detail::', '_State', StdRegexStatePrinter) @@ -2170,6 +2274,7 @@ def build_libstdcxx_dictionary (): libstdcxx_printer.add_version('std::', 'partial_ordering', StdCmpCatPrinter) libstdcxx_printer.add_version('std::', 'weak_ordering', StdCmpCatPrinter) libstdcxx_printer.add_version('std::', 'strong_ordering', StdCmpCatPrinter) + libstdcxx_printer.add_version('std::', 'span', StdSpanPrinter) # Extensions. libstdcxx_printer.add_version('__gnu_cxx::', 'slist', StdSlistPrinter) |