diff --git a/libstdc++-v3/python/libstdcxx/v6/xmethods.py b/libstdc++-v3/python/libstdcxx/v6/xmethods.py index ef0a6e3cef3..844c8a2105a 100644 --- a/libstdc++-v3/python/libstdcxx/v6/xmethods.py +++ b/libstdc++-v3/python/libstdcxx/v6/xmethods.py @@ -25,10 +25,21 @@ matcher_name_prefix = 'libstdc++::' def get_bool_type(): return gdb.lookup_type('bool') - def get_std_size_type(): return gdb.lookup_type('std::size_t') +def is_specialization_of(x, template_name): + """ + Test whether a type is a specialization of the named class template. + The type can be specified as a string or a gdb.Type object. + The template should be the name of a class template as a string, + without any 'std' qualification. + """ + if isinstance(x, gdb.Type): + x = x.tag + if _versioned_namespace: + template_name = '(%s)?%s' % (_versioned_namespace, template_name) + return re.match(r'^std::(__\d::)?%s<.*>$' % template_name, x) is not None class LibStdCxxXMethod(gdb.xmethod.XMethod): def __init__(self, name, worker_class): @@ -159,7 +170,7 @@ class ArrayMethodsMatcher(gdb.xmethod.XMethodMatcher): self.methods = [self._method_dict[m] for m in self._method_dict] def match(self, class_type, method_name): - if not re.match('^std::(__\d+::)?array<.*>$', class_type.tag): + if not is_specialization_of(class_type, 'array'): return None method = self._method_dict.get(method_name) if method is None or not method.enabled: @@ -171,6 +182,7 @@ class ArrayMethodsMatcher(gdb.xmethod.XMethodMatcher): return None return method.worker_class(value_type, size) + # Xmethods for std::deque @@ -284,7 +296,7 @@ class DequeMethodsMatcher(gdb.xmethod.XMethodMatcher): self.methods = [self._method_dict[m] for m in self._method_dict] def match(self, class_type, method_name): - if not re.match('^std::(__\d+::)?deque<.*>$', class_type.tag): + if not is_specialization_of(class_type, 'deque'): return None method = self._method_dict.get(method_name) if method is None or not method.enabled: @@ -332,7 +344,7 @@ class ForwardListMethodsMatcher(gdb.xmethod.XMethodMatcher): self.methods = [self._method_dict[m] for m in self._method_dict] def match(self, class_type, method_name): - if not re.match('^std::(__\d+::)?forward_list<.*>$', class_type.tag): + if not is_specialization_of(class_type, 'forward_list'): return None method = self._method_dict.get(method_name) if method is None or not method.enabled: @@ -419,7 +431,7 @@ class ListMethodsMatcher(gdb.xmethod.XMethodMatcher): self.methods = [self._method_dict[m] for m in self._method_dict] def match(self, class_type, method_name): - if not re.match('^std::(__\d+::)?(__cxx11::)?list<.*>$', class_type.tag): + if not is_specialization_of(class_type, '(__cxx11::)?list'): return None method = self._method_dict.get(method_name) if method is None or not method.enabled: @@ -542,7 +554,7 @@ class VectorMethodsMatcher(gdb.xmethod.XMethodMatcher): self.methods = [self._method_dict[m] for m in self._method_dict] def match(self, class_type, method_name): - if not re.match('^std::(__\d+::)?vector<.*>$', class_type.tag): + if not is_specialization_of(class_type, 'vector'): return None method = self._method_dict.get(method_name) if method is None or not method.enabled: @@ -595,7 +607,7 @@ class AssociativeContainerMethodsMatcher(gdb.xmethod.XMethodMatcher): self.methods = [self._method_dict[m] for m in self._method_dict] def match(self, class_type, method_name): - if not re.match('^std::(__\d+::)?%s<.*>$' % self._name, class_type.tag): + if not is_specialization_of(class_type, self._name): return None method = self._method_dict.get(method_name) if method is None or not method.enabled: @@ -631,9 +643,9 @@ class UniquePtrGetWorker(gdb.xmethod.XMethodWorker): def __call__(self, obj): impl_type = obj.dereference().type.fields()[0].type.tag # Check for new implementations first: - if re.match('^std::(__\d+::)?__uniq_ptr_(data|impl)<.*>$', impl_type): + if is_specialization_of(impl_type, '__uniq_ptr_(data|impl)'): tuple_member = obj['_M_t']['_M_t'] - elif re.match('^std::(__\d+::)?tuple<.*>$', impl_type): + elif is_specialization_of(impl_type, 'tuple'): tuple_member = obj['_M_t'] else: return None @@ -698,7 +710,7 @@ class UniquePtrMethodsMatcher(gdb.xmethod.XMethodMatcher): self.methods = [self._method_dict[m] for m in self._method_dict] def match(self, class_type, method_name): - if not re.match('^std::(__\d+::)?unique_ptr<.*>$', class_type.tag): + if not is_specialization_of(class_type, 'unique_ptr'): return None method = self._method_dict.get(method_name) if method is None or not method.enabled: @@ -772,7 +784,7 @@ class SharedPtrSubscriptWorker(SharedPtrGetWorker): def __call__(self, obj, index): # Check bounds if _elem_type is an array of known bound - m = re.match('.*\[(\d+)]$', str(self._elem_type)) + m = re.match(r'.*\[(\d+)]$', str(self._elem_type)) if m and index >= int(m.group(1)): raise IndexError('shared_ptr<%s> index "%d" should not be >= %d.' % (self._elem_type, int(index), int(m.group(1)))) @@ -827,7 +839,7 @@ class SharedPtrMethodsMatcher(gdb.xmethod.XMethodMatcher): self.methods = [self._method_dict[m] for m in self._method_dict] def match(self, class_type, method_name): - if not re.match('^std::(__\d+::)?shared_ptr<.*>$', class_type.tag): + if not is_specialization_of(class_type, 'shared_ptr'): return None method = self._method_dict.get(method_name) if method is None or not method.enabled: