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
This commit is contained in:
Jonathan Wakely 2016-09-17 16:20:23 +01:00 committed by Jonathan Wakely
parent 70428957af
commit 0089537230
2 changed files with 63 additions and 10 deletions

View File

@ -1,3 +1,10 @@
2016-09-17 Jonathan Wakely <jwakely@redhat.com>
* 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 <jwakely@redhat.com>
* doc/xml/manual/profile_mode.xml: Fix typo.

View File

@ -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)