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
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))
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)
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'])
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
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)
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',
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)