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:
parent
70428957af
commit
0089537230
@ -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>
|
2016-09-16 Jonathan Wakely <jwakely@redhat.com>
|
||||||
|
|
||||||
* doc/xml/manual/profile_mode.xml: Fix typo.
|
* doc/xml/manual/profile_mode.xml: Fix typo.
|
||||||
|
@ -920,10 +920,10 @@ class SingleObjContainerPrinter(object):
|
|||||||
|
|
||||||
|
|
||||||
class StdExpAnyPrinter(SingleObjContainerPrinter):
|
class StdExpAnyPrinter(SingleObjContainerPrinter):
|
||||||
"Print a std::experimental::any"
|
"Print a std::any or std::experimental::any"
|
||||||
|
|
||||||
def __init__ (self, typename, val):
|
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.val = val
|
||||||
self.contained_type = None
|
self.contained_type = None
|
||||||
contained_value = None
|
contained_value = None
|
||||||
@ -932,11 +932,11 @@ class StdExpAnyPrinter(SingleObjContainerPrinter):
|
|||||||
if mgr != 0:
|
if mgr != 0:
|
||||||
func = gdb.block_for_pc(int(mgr.cast(gdb.lookup_type('intptr_t'))))
|
func = gdb.block_for_pc(int(mgr.cast(gdb.lookup_type('intptr_t'))))
|
||||||
if not func:
|
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)
|
rx = r"""({0}::_Manager_\w+<.*>)::_S_manage\({0}::_Op, {0} const\*, {0}::_Arg\*\)""".format(typename)
|
||||||
m = re.match(rx, func.function.name)
|
m = re.match(rx, func.function.name)
|
||||||
if not m:
|
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
|
# 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))
|
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:
|
elif '::_Manager_external' in mgrname:
|
||||||
valptr = self.val['_M_storage']['_M_ptr']
|
valptr = self.val['_M_storage']['_M_ptr']
|
||||||
else:
|
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()
|
contained_value = valptr.cast(self.contained_type.pointer()).dereference()
|
||||||
visualizer = gdb.default_visualizer(contained_value)
|
visualizer = gdb.default_visualizer(contained_value)
|
||||||
super(StdExpAnyPrinter, self).__init__ (contained_value, visualizer)
|
super(StdExpAnyPrinter, self).__init__ (contained_value, visualizer)
|
||||||
@ -963,11 +963,11 @@ class StdExpAnyPrinter(SingleObjContainerPrinter):
|
|||||||
return desc + valtype
|
return desc + valtype
|
||||||
|
|
||||||
class StdExpOptionalPrinter(SingleObjContainerPrinter):
|
class StdExpOptionalPrinter(SingleObjContainerPrinter):
|
||||||
"Print a std::experimental::optional"
|
"Print a std::optional or std::experimental::optional"
|
||||||
|
|
||||||
def __init__ (self, typename, val):
|
def __init__ (self, typename, val):
|
||||||
valtype = self._recognize (val.type.template_argument(0))
|
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
|
self.val = val
|
||||||
contained_value = val['_M_payload'] if self.val['_M_engaged'] else None
|
contained_value = val['_M_payload'] if self.val['_M_engaged'] else None
|
||||||
visualizer = gdb.default_visualizer (val['_M_payload'])
|
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 + " containing " + self.visualizer.to_string ()
|
||||||
return self.typename
|
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:
|
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):
|
def __init__ (self, typename, val):
|
||||||
self.val = 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::unique_ptr', UniquePointerPrinter)
|
||||||
libstdcxx_printer.add('std::__debug::vector', StdVectorPrinter)
|
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.
|
# For array - the default GDB pretty-printer seems reasonable.
|
||||||
libstdcxx_printer.add_version('std::', 'shared_ptr', SharedPointerPrinter)
|
libstdcxx_printer.add_version('std::', 'shared_ptr', SharedPointerPrinter)
|
||||||
libstdcxx_printer.add_version('std::', 'weak_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',
|
libstdcxx_printer.add_version('std::tr1::', 'unordered_multiset',
|
||||||
Tr1UnorderedSetPrinter)
|
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
|
# The tr1 namespace printers do not seem to have any debug
|
||||||
# equivalents, so do no register them.
|
# equivalents, so do no register them.
|
||||||
libstdcxx_printer.add('std::__debug::unordered_map',
|
libstdcxx_printer.add('std::__debug::unordered_map',
|
||||||
@ -1438,6 +1474,16 @@ def build_libstdcxx_dictionary ():
|
|||||||
libstdcxx_printer.add_version('std::experimental::filesystem::v1::__cxx11::',
|
libstdcxx_printer.add_version('std::experimental::filesystem::v1::__cxx11::',
|
||||||
'path', StdExpPathPrinter)
|
'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.
|
# Extensions.
|
||||||
libstdcxx_printer.add_version('__gnu_cxx::', 'slist', StdSlistPrinter)
|
libstdcxx_printer.add_version('__gnu_cxx::', 'slist', StdSlistPrinter)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user