From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2181) id DD7843861911; Thu, 28 Sep 2023 20:21:36 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DD7843861911 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1695932496; bh=jgtLPHQkjvqBKLYoFJDPTIUbgMxAqwLXMj0VWkjWU4o=; h=From:To:Subject:Date:From; b=WoRIX1uqFxwNV+N0ss5K6F6fNByQ4MEgfU+heRIO/8BHJvAgIrZ/rGRZZjgO0i5Q3 LA9AqH8wrEJF/mHeF8KHaBBp7/Cvsu364o8Dgyf/UqhFvgqpvI8RvZY4CTczWWVaUX egZEhUz+KE7kKL4LTDeOzGQy0dPjddhrKjgUc7xY= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Jonathan Wakely To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc r14-4317] libstdc++: Refactor Python Xmethods to use is_specialization_of X-Act-Checkin: gcc X-Git-Author: Jonathan Wakely X-Git-Refname: refs/heads/master X-Git-Oldrev: 6b5c3f9b8139d9eee358b354b35da0b757a0270d X-Git-Newrev: 17d3477fa89466604bee5af2a2caf8de5441aeb5 Message-Id: <20230928202136.DD7843861911@sourceware.org> Date: Thu, 28 Sep 2023 20:21:36 +0000 (GMT) List-Id: https://gcc.gnu.org/g:17d3477fa89466604bee5af2a2caf8de5441aeb5 commit r14-4317-g17d3477fa89466604bee5af2a2caf8de5441aeb5 Author: Jonathan Wakely Date: Thu Sep 28 20:52:01 2023 +0100 libstdc++: Refactor Python Xmethods to use is_specialization_of This copies the is_specialization_of function from printers.py (with slight modification for versioned namespace handling) and reuses it in xmethods.py to replace repetitive re.match calls in every class. This fixes the problem that the regular expressions used \d without escaping the backslash properly. libstdc++-v3/ChangeLog: * python/libstdcxx/v6/xmethods.py (is_specialization_of): Define new function. (ArrayMethodsMatcher, DequeMethodsMatcher) (ForwardListMethodsMatcher, ListMethodsMatcher) (VectorMethodsMatcher, AssociativeContainerMethodsMatcher) (UniquePtrGetWorker, UniquePtrMethodsMatcher) (SharedPtrSubscriptWorker, SharedPtrMethodsMatcher): Use is_specialization_of instead of re.match. Diff: --- libstdc++-v3/python/libstdcxx/v6/xmethods.py | 36 ++++++++++++++++++---------- 1 file changed, 24 insertions(+), 12 deletions(-) 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: