From 0089537230ac9ec84dd102fd707a5f059c8f3577 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Sat, 17 Sep 2016 16:20:23 +0100 Subject: [PATCH] Define pretty printers for C++17 library components * python/libstdcxx/v6/printers.py (StdVariantPrinter): Define. (StdExpAnyPrinter, StdExpOptionalPrinter, StdExpStringViewPrinter): Register for C++17 components in namespace std. Strip inline namespace from typename. From-SVN: r240215 --- libstdc++-v3/ChangeLog | 7 +++ libstdc++-v3/python/libstdcxx/v6/printers.py | 66 +++++++++++++++++--- 2 files changed, 63 insertions(+), 10 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 765460b3f8b..70ff276beb4 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,10 @@ +2016-09-17 Jonathan Wakely + + * python/libstdcxx/v6/printers.py (StdVariantPrinter): Define. + (StdExpAnyPrinter, StdExpOptionalPrinter, StdExpStringViewPrinter): + Register for C++17 components in namespace std. Strip inline namespace + from typename. + 2016-09-16 Jonathan Wakely * doc/xml/manual/profile_mode.xml: Fix typo. diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py index 977e63fff47..8c29760e01c 100644 --- a/libstdc++-v3/python/libstdcxx/v6/printers.py +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py @@ -920,10 +920,10 @@ class SingleObjContainerPrinter(object): class StdExpAnyPrinter(SingleObjContainerPrinter): - "Print a std::experimental::any" + "Print a std::any or std::experimental::any" def __init__ (self, typename, val): - self.typename = 'std::experimental::any' + self.typename = re.sub('^std::experimental::fundamentals_v\d::', 'std::experimental::', typename, 1) self.val = val self.contained_type = None contained_value = None @@ -932,11 +932,11 @@ class StdExpAnyPrinter(SingleObjContainerPrinter): if mgr != 0: func = gdb.block_for_pc(int(mgr.cast(gdb.lookup_type('intptr_t')))) if not func: - raise ValueError("Invalid function pointer in std::experimental::any") + raise ValueError("Invalid function pointer in %s" % self.typename) rx = r"""({0}::_Manager_\w+<.*>)::_S_manage\({0}::_Op, {0} const\*, {0}::_Arg\*\)""".format(typename) m = re.match(rx, func.function.name) if not m: - raise ValueError("Unknown manager function in std::experimental::any") + raise ValueError("Unknown manager function in %s" % self.typename) # FIXME need to expand 'std::string' so that gdb.lookup_type works mgrname = re.sub("std::string(?!\w)", str(gdb.lookup_type('std::string').strip_typedefs()), m.group(1)) @@ -948,7 +948,7 @@ class StdExpAnyPrinter(SingleObjContainerPrinter): elif '::_Manager_external' in mgrname: valptr = self.val['_M_storage']['_M_ptr'] else: - raise ValueError("Unknown manager function in std::experimental::any") + raise ValueError("Unknown manager function in %s" % self.typename) contained_value = valptr.cast(self.contained_type.pointer()).dereference() visualizer = gdb.default_visualizer(contained_value) super(StdExpAnyPrinter, self).__init__ (contained_value, visualizer) @@ -963,11 +963,11 @@ class StdExpAnyPrinter(SingleObjContainerPrinter): return desc + valtype class StdExpOptionalPrinter(SingleObjContainerPrinter): - "Print a std::experimental::optional" + "Print a std::optional or std::experimental::optional" def __init__ (self, typename, val): valtype = self._recognize (val.type.template_argument(0)) - self.typename = "std::experimental::optional<%s>" % valtype + self.typename = re.sub('^std::(experimental::|)(fundamentals_v\d::|)(.*)', r'std::\1\3<%s>' % valtype, typename, 1) self.val = val contained_value = val['_M_payload'] if self.val['_M_engaged'] else None visualizer = gdb.default_visualizer (val['_M_payload']) @@ -980,8 +980,44 @@ class StdExpOptionalPrinter(SingleObjContainerPrinter): return self.typename + " containing " + self.visualizer.to_string () return self.typename +class StdVariantPrinter(SingleObjContainerPrinter): + "Print a std::variant" + + def __init__(self, typename, val): + alternatives = self._template_args(val) + self.alts = alternatives + self.typename = "%s<%s>" % (typename, ', '.join([self._recognize(alt) for alt in alternatives])) + self.index = val['_M_index'] + if self.index >= len(alternatives): + self.contained_type = None + contained_value = None + visualizer = None + else: + self.contained_type = alternatives[int(self.index)] + addr = val['_M_first']['_M_storage'].address + contained_value = addr.cast(self.contained_type.pointer()).dereference() + visualizer = gdb.default_visualizer(contained_value) + super (StdVariantPrinter, self).__init__(contained_value, visualizer) + + def _template_args(self, val): + n = 0 + args = () + while True: + try: + args += (val.type.template_argument(n),) + except: + return args + n += 1 + + def to_string(self): + if self.contained_value is None: + return "%s [no value]" % self.typename + if hasattr(self.visualizer, 'children'): + return "%s [alternative %d] %s" % (self.typename, self.index, self.visualizer.to_string()) + return self.typename + class StdExpStringViewPrinter: - "Print a std::experimental::basic_string_view" + "Print a std::basic_string_view or std::experimental::basic_string_view" def __init__ (self, typename, val): self.val = val @@ -1385,7 +1421,7 @@ def build_libstdcxx_dictionary (): libstdcxx_printer.add('std::__debug::unique_ptr', UniquePointerPrinter) libstdcxx_printer.add('std::__debug::vector', StdVectorPrinter) - # These are the TR1 and C++0x printers. + # These are the TR1 and C++11 printers. # For array - the default GDB pretty-printer seems reasonable. libstdcxx_printer.add_version('std::', 'shared_ptr', SharedPointerPrinter) libstdcxx_printer.add_version('std::', 'weak_ptr', SharedPointerPrinter) @@ -1411,7 +1447,7 @@ def build_libstdcxx_dictionary (): libstdcxx_printer.add_version('std::tr1::', 'unordered_multiset', Tr1UnorderedSetPrinter) - # These are the C++0x printer registrations for -D_GLIBCXX_DEBUG cases. + # These are the C++11 printer registrations for -D_GLIBCXX_DEBUG cases. # The tr1 namespace printers do not seem to have any debug # equivalents, so do no register them. libstdcxx_printer.add('std::__debug::unordered_map', @@ -1438,6 +1474,16 @@ def build_libstdcxx_dictionary (): libstdcxx_printer.add_version('std::experimental::filesystem::v1::__cxx11::', 'path', StdExpPathPrinter) + # C++17 components + libstdcxx_printer.add_version('std::', + 'any', StdExpAnyPrinter) + libstdcxx_printer.add_version('std::', + 'optional', StdExpOptionalPrinter) + libstdcxx_printer.add_version('std::', + 'basic_string_view', StdExpStringViewPrinter) + libstdcxx_printer.add_version('std::', + 'variant', StdVariantPrinter) + # Extensions. libstdcxx_printer.add_version('__gnu_cxx::', 'slist', StdSlistPrinter) -- 2.30.2