This tweaks the existing printers for Fundamentals TS components to
work for the C++17 versions, and adds a printer for std::variant.

        * python/libstdcxx/v6/printers.py (StdVariantPrinter): Define.
        (StdExpAnyPrinter, StdExpOptionalPrinter, StdExpStringViewPrinter):
        Register for C++17 components in namespace std. Strip inline namespace
        from typename.

Tested x86_64-linux, committed to trunk.

commit 2cff0a92fabf0baf847e10609083ce950af0281e
Author: Jonathan Wakely <jwak...@redhat.com>
Date:   Sat Sep 17 15:07:04 2016 +0100

    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.

diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py 
b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 977e63f..8c29760 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)
 

Reply via email to