Commit f9a27859 by François Dumont Committed by Jonathan Wakely

Make Python printers and xmethods work with versioned namespace

2017-01-10  François Dumont  <fdumont@gcc.gnu.org>
	    Jonathan Wakely  <jwakely@redhat.com>

	* python/libstdcxx/v6/printers.py (_versioned_namespace): Define.
	(is_specialization, strip_versioned_namespace): New helpers functions
	to work with symbols in the versioned namespace.
	(Printer.add_version): Add second name using versioned namespace.
	(add_one_template_type_printer, add_one_type_printer): Add second
	type printers using versioned namespace.
	(register_type_printers): Add template type printer for basic_string.
	(build_libstdcxx_dictionary): Remove dead code.
	* python/libstdcxx/v6/xmethods.py: Make all matchers look for
	versioned namespace.
	* testsuite/libstdc++-prettyprinters/48362.cc: Adjust expected
	results.
	* testsuite/libstdc++-prettyprinters/whatis.cc: Likewise.

Co-Authored-By: Jonathan Wakely <jwakely@redhat.com>

From-SVN: r244262
parent ad730fac
2017-01-10 François Dumont <fdumont@gcc.gnu.org>
Jonathan Wakely <jwakely@redhat.com>
* python/libstdcxx/v6/printers.py (_versioned_namespace): Define.
(is_specialization, strip_versioned_namespace): New helpers functions
to work with symbols in the versioned namespace.
(Printer.add_version): Add second name using versioned namespace.
(add_one_template_type_printer, add_one_type_printer): Add second
type printers using versioned namespace.
(register_type_printers): Add template type printer for basic_string.
(build_libstdcxx_dictionary): Remove dead code.
* python/libstdcxx/v6/xmethods.py: Make all matchers look for
versioned namespace.
* testsuite/libstdc++-prettyprinters/48362.cc: Adjust expected
results.
* testsuite/libstdc++-prettyprinters/whatis.cc: Likewise.
2017-01-09 Jonathan Wakely <jwakely@redhat.com> 2017-01-09 Jonathan Wakely <jwakely@redhat.com>
PR libstdc++/79017 PR libstdc++/79017
......
...@@ -100,11 +100,26 @@ def find_type(orig, name): ...@@ -100,11 +100,26 @@ def find_type(orig, name):
raise ValueError("Cannot find type %s::%s" % (str(orig), name)) raise ValueError("Cannot find type %s::%s" % (str(orig), name))
typ = field.type typ = field.type
_versioned_namespace = '__7::'
# Test if a type is a given template instantiation.
def is_specialization_of(type, template_name):
global _versioned_namespace
if _versioned_namespace:
return re.match('^std::(%s)?%s<.*>$' % (_versioned_namespace, template_name), type) is not None
return re.match('^std::%s<.*>$' % template_name, type) is not None
def strip_versioned_namespace(typename):
global _versioned_namespace
if _versioned_namespace:
return typename.replace(_versioned_namespace, '')
return typename
class SharedPointerPrinter: class SharedPointerPrinter:
"Print a shared_ptr or weak_ptr" "Print a shared_ptr or weak_ptr"
def __init__ (self, typename, val): def __init__ (self, typename, val):
self.typename = typename self.typename = strip_versioned_namespace(typename)
self.val = val self.val = val
def to_string (self): def to_string (self):
...@@ -127,9 +142,9 @@ class UniquePointerPrinter: ...@@ -127,9 +142,9 @@ class UniquePointerPrinter:
def to_string (self): def to_string (self):
impl_type = self.val.type.fields()[0].type.tag impl_type = self.val.type.fields()[0].type.tag
if impl_type.startswith('std::__uniq_ptr_impl<'): # New implementation if is_specialization_of(impl_type, '__uniq_ptr_impl'): # New implementation
v = self.val['_M_t']['_M_t']['_M_head_impl'] v = self.val['_M_t']['_M_t']['_M_head_impl']
elif impl_type.startswith('std::tuple<'): elif is_specialization_of(impl_type, 'tuple'):
v = self.val['_M_t']['_M_head_impl'] v = self.val['_M_t']['_M_head_impl']
else: else:
raise ValueError("Unsupported implementation for unique_ptr: %s" % self.val.type.fields()[0].type.tag) raise ValueError("Unsupported implementation for unique_ptr: %s" % self.val.type.fields()[0].type.tag)
...@@ -179,7 +194,7 @@ class StdListPrinter: ...@@ -179,7 +194,7 @@ class StdListPrinter:
return ('[%d]' % count, val) return ('[%d]' % count, val)
def __init__(self, typename, val): def __init__(self, typename, val):
self.typename = typename self.typename = strip_versioned_namespace(typename)
self.val = val self.val = val
def children(self): def children(self):
...@@ -299,7 +314,7 @@ class StdVectorPrinter: ...@@ -299,7 +314,7 @@ class StdVectorPrinter:
return ('[%d]' % count, elt) return ('[%d]' % count, elt)
def __init__(self, typename, val): def __init__(self, typename, val):
self.typename = typename self.typename = strip_versioned_namespace(typename)
self.val = val self.val = val
self.is_bool = val.type.template_argument(0).code == gdb.TYPE_CODE_BOOL self.is_bool = val.type.template_argument(0).code == gdb.TYPE_CODE_BOOL
...@@ -403,7 +418,7 @@ class StdTuplePrinter: ...@@ -403,7 +418,7 @@ class StdTuplePrinter:
return ('[%d]' % self.count, impl['_M_head_impl']) return ('[%d]' % self.count, impl['_M_head_impl'])
def __init__ (self, typename, val): def __init__ (self, typename, val):
self.typename = typename self.typename = strip_versioned_namespace(typename)
self.val = val; self.val = val;
def children (self): def children (self):
...@@ -418,7 +433,7 @@ class StdStackOrQueuePrinter: ...@@ -418,7 +433,7 @@ class StdStackOrQueuePrinter:
"Print a std::stack or std::queue" "Print a std::stack or std::queue"
def __init__ (self, typename, val): def __init__ (self, typename, val):
self.typename = typename self.typename = strip_versioned_namespace(typename)
self.visualizer = gdb.default_visualizer(val['c']) self.visualizer = gdb.default_visualizer(val['c'])
def children (self): def children (self):
...@@ -496,7 +511,10 @@ class StdRbtreeIteratorPrinter: ...@@ -496,7 +511,10 @@ class StdRbtreeIteratorPrinter:
def __init__ (self, typename, val): def __init__ (self, typename, val):
self.val = val self.val = val
valtype = self.val.type.template_argument(0).strip_typedefs() valtype = self.val.type.template_argument(0).strip_typedefs()
nodetype = gdb.lookup_type('std::_Rb_tree_node<' + str(valtype) + '>') nodetype = '_Rb_tree_node<' + str(valtype) + '>'
if _versioned_namespace and typename.startswith('std::' + _versioned_namespace):
nodetype = _versioned_namespace + nodetype
nodetype = gdb.lookup_type('std::' + nodetype)
self.link_type = nodetype.strip_typedefs().pointer() self.link_type = nodetype.strip_typedefs().pointer()
def to_string (self): def to_string (self):
...@@ -552,7 +570,7 @@ class StdMapPrinter: ...@@ -552,7 +570,7 @@ class StdMapPrinter:
return result return result
def __init__ (self, typename, val): def __init__ (self, typename, val):
self.typename = typename self.typename = strip_versioned_namespace(typename)
self.val = val self.val = val
def to_string (self): def to_string (self):
...@@ -592,7 +610,7 @@ class StdSetPrinter: ...@@ -592,7 +610,7 @@ class StdSetPrinter:
return result return result
def __init__ (self, typename, val): def __init__ (self, typename, val):
self.typename = typename self.typename = strip_versioned_namespace(typename)
self.val = val self.val = val
def to_string (self): def to_string (self):
...@@ -609,7 +627,7 @@ class StdBitsetPrinter: ...@@ -609,7 +627,7 @@ class StdBitsetPrinter:
"Print a std::bitset" "Print a std::bitset"
def __init__(self, typename, val): def __init__(self, typename, val):
self.typename = typename self.typename = strip_versioned_namespace(typename)
self.val = val self.val = val
def to_string (self): def to_string (self):
...@@ -679,7 +697,7 @@ class StdDequePrinter: ...@@ -679,7 +697,7 @@ class StdDequePrinter:
return result return result
def __init__(self, typename, val): def __init__(self, typename, val):
self.typename = typename self.typename = strip_versioned_namespace(typename)
self.val = val self.val = val
self.elttype = val.type.template_argument(0) self.elttype = val.type.template_argument(0)
size = self.elttype.sizeof size = self.elttype.sizeof
...@@ -805,7 +823,7 @@ class Tr1UnorderedSetPrinter: ...@@ -805,7 +823,7 @@ class Tr1UnorderedSetPrinter:
"Print a tr1::unordered_set" "Print a tr1::unordered_set"
def __init__ (self, typename, val): def __init__ (self, typename, val):
self.typename = typename self.typename = strip_versioned_namespace(typename)
self.val = val self.val = val
def hashtable (self): def hashtable (self):
...@@ -831,7 +849,7 @@ class Tr1UnorderedMapPrinter: ...@@ -831,7 +849,7 @@ class Tr1UnorderedMapPrinter:
"Print a tr1::unordered_map" "Print a tr1::unordered_map"
def __init__ (self, typename, val): def __init__ (self, typename, val):
self.typename = typename self.typename = strip_versioned_namespace(typename)
self.val = val self.val = val
def hashtable (self): def hashtable (self):
...@@ -897,7 +915,7 @@ class StdForwardListPrinter: ...@@ -897,7 +915,7 @@ class StdForwardListPrinter:
def __init__(self, typename, val): def __init__(self, typename, val):
self.val = val self.val = val
self.typename = typename self.typename = strip_versioned_namespace(typename)
def children(self): def children(self):
nodetype = find_type(self.val.type, '_Node') nodetype = find_type(self.val.type, '_Node')
...@@ -952,12 +970,12 @@ class SingleObjContainerPrinter(object): ...@@ -952,12 +970,12 @@ class SingleObjContainerPrinter(object):
return self.visualizer.display_hint () return self.visualizer.display_hint ()
return self.hint return self.hint
class StdExpAnyPrinter(SingleObjContainerPrinter): class StdExpAnyPrinter(SingleObjContainerPrinter):
"Print a std::any or std::experimental::any" "Print a std::any or std::experimental::any"
def __init__ (self, typename, val): def __init__ (self, typename, val):
self.typename = re.sub('^std::experimental::fundamentals_v\d::', 'std::experimental::', typename, 1) self.typename = re.sub('^std::experimental::fundamentals_v\d::', 'std::experimental::', typename, 1)
self.typename = strip_versioned_namespace(self.typename)
self.val = val self.val = val
self.contained_type = None self.contained_type = None
contained_value = None contained_value = None
...@@ -972,8 +990,11 @@ class StdExpAnyPrinter(SingleObjContainerPrinter): ...@@ -972,8 +990,11 @@ class StdExpAnyPrinter(SingleObjContainerPrinter):
if not m: if not m:
raise ValueError("Unknown manager function in %s" % self.typename) raise ValueError("Unknown manager function in %s" % self.typename)
mgrname = m.group(1)
# FIXME need to expand 'std::string' so that gdb.lookup_type works # FIXME need to expand 'std::string' so that gdb.lookup_type works
if 'std::string' in mgrname:
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))
mgrtype = gdb.lookup_type(mgrname) mgrtype = gdb.lookup_type(mgrname)
self.contained_type = mgrtype.template_argument(0) self.contained_type = mgrtype.template_argument(0)
valptr = None valptr = None
...@@ -994,7 +1015,7 @@ class StdExpAnyPrinter(SingleObjContainerPrinter): ...@@ -994,7 +1015,7 @@ class StdExpAnyPrinter(SingleObjContainerPrinter):
if hasattr (self.visualizer, 'children'): if hasattr (self.visualizer, 'children'):
return desc + self.visualizer.to_string () return desc + self.visualizer.to_string ()
valtype = self._recognize (self.contained_type) valtype = self._recognize (self.contained_type)
return desc + valtype return desc + strip_versioned_namespace(str(valtype))
class StdExpOptionalPrinter(SingleObjContainerPrinter): class StdExpOptionalPrinter(SingleObjContainerPrinter):
"Print a std::optional or std::experimental::optional" "Print a std::optional or std::experimental::optional"
...@@ -1002,6 +1023,7 @@ class StdExpOptionalPrinter(SingleObjContainerPrinter): ...@@ -1002,6 +1023,7 @@ class StdExpOptionalPrinter(SingleObjContainerPrinter):
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 = re.sub('^std::(experimental::|)(fundamentals_v\d::|)(.*)', r'std::\1\3<%s>' % valtype, typename, 1) self.typename = re.sub('^std::(experimental::|)(fundamentals_v\d::|)(.*)', r'std::\1\3<%s>' % valtype, typename, 1)
self.typename = strip_versioned_namespace(self.typename)
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'])
...@@ -1021,6 +1043,7 @@ class StdVariantPrinter(SingleObjContainerPrinter): ...@@ -1021,6 +1043,7 @@ class StdVariantPrinter(SingleObjContainerPrinter):
def __init__(self, typename, val): def __init__(self, typename, val):
alternatives = self._template_args(val) alternatives = self._template_args(val)
self.typename = "%s<%s>" % (typename, ', '.join([self._recognize(alt) for alt in alternatives])) self.typename = "%s<%s>" % (typename, ', '.join([self._recognize(alt) for alt in alternatives]))
self.typename = strip_versioned_namespace(self.typename)
self.index = val['_M_index'] self.index = val['_M_index']
if self.index >= len(alternatives): if self.index >= len(alternatives):
self.contained_type = None self.contained_type = None
...@@ -1058,7 +1081,7 @@ class StdNodeHandlePrinter(SingleObjContainerPrinter): ...@@ -1058,7 +1081,7 @@ class StdNodeHandlePrinter(SingleObjContainerPrinter):
def __init__(self, typename, val): def __init__(self, typename, val):
self.value_type = val.type.template_argument(1) self.value_type = val.type.template_argument(1)
nodetype = val.type.template_argument(2).template_argument(0) nodetype = val.type.template_argument(2).template_argument(0)
self.is_rb_tree_node = nodetype.name.startswith('std::_Rb_tree_node') self.is_rb_tree_node = is_specialization_of(nodetype.name, '_Rb_tree_node')
self.is_map_node = val.type.template_argument(0) != self.value_type self.is_map_node = val.type.template_argument(0) != self.value_type
nodeptr = val['_M_ptr'] nodeptr = val['_M_ptr']
if nodeptr: if nodeptr:
...@@ -1202,7 +1225,8 @@ class Printer(object): ...@@ -1202,7 +1225,8 @@ class Printer(object):
# Add a name using _GLIBCXX_BEGIN_NAMESPACE_VERSION. # Add a name using _GLIBCXX_BEGIN_NAMESPACE_VERSION.
def add_version(self, base, name, function): def add_version(self, base, name, function):
self.add(base + name, function) self.add(base + name, function)
self.add(base + '__7::' + name, function) if _versioned_namespace:
self.add(base + _versioned_namespace + name, function)
# Add a name using _GLIBCXX_BEGIN_NAMESPACE_CONTAINER. # Add a name using _GLIBCXX_BEGIN_NAMESPACE_CONTAINER.
def add_container(self, base, name, function): def add_container(self, base, name, function):
...@@ -1294,7 +1318,13 @@ class TemplateTypePrinter(object): ...@@ -1294,7 +1318,13 @@ class TemplateTypePrinter(object):
return self._recognizer(self.pattern, self.subst) return self._recognizer(self.pattern, self.subst)
def add_one_template_type_printer(obj, name, match, subst): def add_one_template_type_printer(obj, name, match, subst):
printer = TemplateTypePrinter(name, '^std::' + match + '$', 'std::' + subst) match = '^std::' + match + '$'
printer = TemplateTypePrinter(name, match, 'std::' + subst)
gdb.types.register_type_printer(obj, printer)
if _versioned_namespace:
# Add second type printer for same type in versioned namespace:
match = match.replace('std::', 'std::' + _versioned_namespace)
printer = TemplateTypePrinter(name, match, 'std::' + subst)
gdb.types.register_type_printer(obj, printer) gdb.types.register_type_printer(obj, printer)
class FilteringTypePrinter(object): class FilteringTypePrinter(object):
...@@ -1322,7 +1352,7 @@ class FilteringTypePrinter(object): ...@@ -1322,7 +1352,7 @@ class FilteringTypePrinter(object):
except: except:
pass pass
if self.type_obj == type_obj: if self.type_obj == type_obj:
return self.name return strip_versioned_namespace(self.name)
return None return None
def instantiate(self): def instantiate(self):
...@@ -1331,6 +1361,9 @@ class FilteringTypePrinter(object): ...@@ -1331,6 +1361,9 @@ class FilteringTypePrinter(object):
def add_one_type_printer(obj, match, name): def add_one_type_printer(obj, match, name):
printer = FilteringTypePrinter(match, 'std::' + name) printer = FilteringTypePrinter(match, 'std::' + name)
gdb.types.register_type_printer(obj, printer) gdb.types.register_type_printer(obj, printer)
if _versioned_namespace:
printer = FilteringTypePrinter(match, 'std::' + _versioned_namespace + name)
gdb.types.register_type_printer(obj, printer)
def register_type_printers(obj): def register_type_printers(obj):
global _use_type_printing global _use_type_printing
...@@ -1372,9 +1405,9 @@ def register_type_printers(obj): ...@@ -1372,9 +1405,9 @@ def register_type_printers(obj):
# Note that we can't have a printer for std::wstreampos, because # Note that we can't have a printer for std::wstreampos, because
# it shares the same underlying type as std::streampos. # it shares the same underlying type as std::streampos.
add_one_type_printer(obj, 'fpos', 'streampos') add_one_type_printer(obj, 'fpos', 'streampos')
add_one_type_printer(obj, 'basic_string', 'u16string') add_one_type_printer(obj, 'basic_string', 'u16string')
add_one_type_printer(obj, 'basic_string', 'u32string') add_one_type_printer(obj, 'basic_string', 'u32string')
add_one_type_printer(obj, 'basic_string_view', 'u16string_view') add_one_type_printer(obj, 'basic_string_view', 'u16string_view')
add_one_type_printer(obj, 'basic_string_view', 'u32string_view') add_one_type_printer(obj, 'basic_string_view', 'u32string_view')
...@@ -1397,6 +1430,10 @@ def register_type_printers(obj): ...@@ -1397,6 +1430,10 @@ def register_type_printers(obj):
'unique_ptr<(.*), std::default_delete<\\1 ?> >', 'unique_ptr<(.*), std::default_delete<\\1 ?> >',
'unique_ptr<{1}>') 'unique_ptr<{1}>')
add_one_template_type_printer(obj, 'basic_string<T>',
'basic_string<((un)?signed char), std::char_traits<\\1 ?>, std::allocator<\\1 ?> >',
'basic_string<{1}>')
add_one_template_type_printer(obj, 'deque<T>', add_one_template_type_printer(obj, 'deque<T>',
'deque<(.*), std::allocator<\\1 ?> >', 'deque<(.*), std::allocator<\\1 ?> >',
'deque<{1}>') 'deque<{1}>')
...@@ -1465,11 +1502,6 @@ def build_libstdcxx_dictionary (): ...@@ -1465,11 +1502,6 @@ def build_libstdcxx_dictionary ():
libstdcxx_printer = Printer("libstdc++-v6") libstdcxx_printer = Printer("libstdc++-v6")
# For _GLIBCXX_BEGIN_NAMESPACE_VERSION.
vers = '(__7::)?'
# For _GLIBCXX_BEGIN_NAMESPACE_CONTAINER.
container = '(__cxx1998::' + vers + ')?'
# libstdc++ objects requiring pretty-printing. # libstdc++ objects requiring pretty-printing.
# In order from: # In order from:
# http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a01847.html # http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a01847.html
......
...@@ -148,7 +148,7 @@ class ArrayMethodsMatcher(gdb.xmethod.XMethodMatcher): ...@@ -148,7 +148,7 @@ class ArrayMethodsMatcher(gdb.xmethod.XMethodMatcher):
self.methods = [self._method_dict[m] for m in self._method_dict] self.methods = [self._method_dict[m] for m in self._method_dict]
def match(self, class_type, method_name): def match(self, class_type, method_name):
if not re.match('^std::array<.*>$', class_type.tag): if not re.match('^std::(__\d+::)?array<.*>$', class_type.tag):
return None return None
method = self._method_dict.get(method_name) method = self._method_dict.get(method_name)
if method is None or not method.enabled: if method is None or not method.enabled:
...@@ -265,7 +265,7 @@ class DequeMethodsMatcher(gdb.xmethod.XMethodMatcher): ...@@ -265,7 +265,7 @@ class DequeMethodsMatcher(gdb.xmethod.XMethodMatcher):
self.methods = [self._method_dict[m] for m in self._method_dict] self.methods = [self._method_dict[m] for m in self._method_dict]
def match(self, class_type, method_name): def match(self, class_type, method_name):
if not re.match('^std::deque<.*>$', class_type.tag): if not re.match('^std::(__\d+::)?deque<.*>$', class_type.tag):
return None return None
method = self._method_dict.get(method_name) method = self._method_dict.get(method_name)
if method is None or not method.enabled: if method is None or not method.enabled:
...@@ -309,7 +309,7 @@ class ForwardListMethodsMatcher(gdb.xmethod.XMethodMatcher): ...@@ -309,7 +309,7 @@ class ForwardListMethodsMatcher(gdb.xmethod.XMethodMatcher):
self.methods = [self._method_dict[m] for m in self._method_dict] self.methods = [self._method_dict[m] for m in self._method_dict]
def match(self, class_type, method_name): def match(self, class_type, method_name):
if not re.match('^std::forward_list<.*>$', class_type.tag): if not re.match('^std::(__\d+::)?forward_list<.*>$', class_type.tag):
return None return None
method = self._method_dict.get(method_name) method = self._method_dict.get(method_name)
if method is None or not method.enabled: if method is None or not method.enabled:
...@@ -390,7 +390,7 @@ class ListMethodsMatcher(gdb.xmethod.XMethodMatcher): ...@@ -390,7 +390,7 @@ class ListMethodsMatcher(gdb.xmethod.XMethodMatcher):
self.methods = [self._method_dict[m] for m in self._method_dict] self.methods = [self._method_dict[m] for m in self._method_dict]
def match(self, class_type, method_name): def match(self, class_type, method_name):
if not re.match('^std::(__cxx11::)?list<.*>$', class_type.tag): if not re.match('^std::(__\d+::)?(__cxx11::)?list<.*>$', class_type.tag):
return None return None
method = self._method_dict.get(method_name) method = self._method_dict.get(method_name)
if method is None or not method.enabled: if method is None or not method.enabled:
...@@ -505,7 +505,7 @@ class VectorMethodsMatcher(gdb.xmethod.XMethodMatcher): ...@@ -505,7 +505,7 @@ class VectorMethodsMatcher(gdb.xmethod.XMethodMatcher):
self.methods = [self._method_dict[m] for m in self._method_dict] self.methods = [self._method_dict[m] for m in self._method_dict]
def match(self, class_type, method_name): def match(self, class_type, method_name):
if not re.match('^std::vector<.*>$', class_type.tag): if not re.match('^std::(__\d+::)?vector<.*>$', class_type.tag):
return None return None
method = self._method_dict.get(method_name) method = self._method_dict.get(method_name)
if method is None or not method.enabled: if method is None or not method.enabled:
...@@ -554,7 +554,7 @@ class AssociativeContainerMethodsMatcher(gdb.xmethod.XMethodMatcher): ...@@ -554,7 +554,7 @@ class AssociativeContainerMethodsMatcher(gdb.xmethod.XMethodMatcher):
self.methods = [self._method_dict[m] for m in self._method_dict] self.methods = [self._method_dict[m] for m in self._method_dict]
def match(self, class_type, method_name): def match(self, class_type, method_name):
if not re.match('^std::%s<.*>$' % self._name, class_type.tag): if not re.match('^std::(__\d+::)?%s<.*>$' % self._name, class_type.tag):
return None return None
method = self._method_dict.get(method_name) method = self._method_dict.get(method_name)
if method is None or not method.enabled: if method is None or not method.enabled:
...@@ -586,9 +586,9 @@ class UniquePtrGetWorker(gdb.xmethod.XMethodWorker): ...@@ -586,9 +586,9 @@ class UniquePtrGetWorker(gdb.xmethod.XMethodWorker):
def __call__(self, obj): def __call__(self, obj):
impl_type = obj.dereference().type.fields()[0].type.tag impl_type = obj.dereference().type.fields()[0].type.tag
if impl_type.startswith('std::__uniq_ptr_impl<'): # New implementation if re.match('^std::(__\d+::)?__uniq_ptr_impl<.*>$', impl_type): # New implementation
return obj['_M_t']['_M_t']['_M_head_impl'] return obj['_M_t']['_M_t']['_M_head_impl']
elif impl_type.startswith('std::tuple<'): elif re.match('^std::(__\d+::)?tuple<.*>$', impl_type):
return obj['_M_t']['_M_head_impl'] return obj['_M_t']['_M_head_impl']
return None return None
...@@ -640,7 +640,7 @@ class UniquePtrMethodsMatcher(gdb.xmethod.XMethodMatcher): ...@@ -640,7 +640,7 @@ class UniquePtrMethodsMatcher(gdb.xmethod.XMethodMatcher):
self.methods = [self._method_dict[m] for m in self._method_dict] self.methods = [self._method_dict[m] for m in self._method_dict]
def match(self, class_type, method_name): def match(self, class_type, method_name):
if not re.match('^std::unique_ptr<.*>$', class_type.tag): if not re.match('^std::(__\d+::)?unique_ptr<.*>$', class_type.tag):
return None return None
method = self._method_dict.get(method_name) method = self._method_dict.get(method_name)
if method is None or not method.enabled: if method is None or not method.enabled:
...@@ -758,7 +758,7 @@ class SharedPtrMethodsMatcher(gdb.xmethod.XMethodMatcher): ...@@ -758,7 +758,7 @@ class SharedPtrMethodsMatcher(gdb.xmethod.XMethodMatcher):
self.methods = [self._method_dict[m] for m in self._method_dict] self.methods = [self._method_dict[m] for m in self._method_dict]
def match(self, class_type, method_name): def match(self, class_type, method_name):
if not re.match('^std::shared_ptr<.*>$', class_type.tag): if not re.match('^std::(__\d+::)?shared_ptr<.*>$', class_type.tag):
return None return None
method = self._method_dict.get(method_name) method = self._method_dict.get(method_name)
if method is None or not method.enabled: if method is None or not method.enabled:
......
...@@ -26,10 +26,10 @@ int ...@@ -26,10 +26,10 @@ int
main() main()
{ {
std::tuple<> t1; std::tuple<> t1;
// { dg-final { regexp-test t1 {empty std::(__7::)?tuple} } } // { dg-final { regexp-test t1 {empty std::tuple} } }
std::tuple<std::string, int, std::tuple<>> t2{ "Johnny", 5, {} }; std::tuple<std::string, int, std::tuple<>> t2{ "Johnny", 5, {} };
// { dg-final { regexp-test t2 {std::(__7::)?tuple containing = {\[1\] = "Johnny", \[2\] = 5, \[3\] = {<std::(__7::)?tuple<>> = empty std::(__7::)?tuple, <No data fields>}}} } } // { dg-final { regexp-test t2 {std::tuple containing = {\[1\] = "Johnny", \[2\] = 5, \[3\] = {<std::(__7::)?tuple<>> = empty std::tuple, <No data fields>}}} } }
std::cout << "\n"; std::cout << "\n";
return 0; // Mark SPOT return 0; // Mark SPOT
......
...@@ -166,11 +166,11 @@ holder<std::knuth_b> knuth_b_holder; ...@@ -166,11 +166,11 @@ holder<std::knuth_b> knuth_b_holder;
ustring *ustring_ptr; ustring *ustring_ptr;
holder<ustring> ustring_holder; holder<ustring> ustring_holder;
// { dg-final { whatis-test ustring_holder "holder<std::basic_string<unsigned char, std::char_traits<unsigned char>, std::allocator<unsigned char> > >" } } // { dg-final { whatis-test ustring_holder "holder<std::basic_string<unsigned char> >" } }
std::basic_string<signed char> *sstring_ptr; std::basic_string<signed char> *sstring_ptr;
holder< std::basic_string<signed char> > sstring_holder; holder< std::basic_string<signed char> > sstring_holder;
// { dg-final { whatis-test sstring_holder "holder<std::basic_string<signed char, std::char_traits<signed char>, std::allocator<signed char> > >" } } // { dg-final { whatis-test sstring_holder "holder<std::basic_string<signed char> >" } }
std::vector<std::deque<std::unique_ptr<char>>> *seq1_ptr; std::vector<std::deque<std::unique_ptr<char>>> *seq1_ptr;
holder< std::vector<std::deque<std::unique_ptr<char>>> > seq1_holder; holder< std::vector<std::deque<std::unique_ptr<char>>> > seq1_holder;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment