From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2181) id 33F393854806; Mon, 20 Mar 2023 11:55:02 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 33F393854806 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1679313302; bh=+GgGBuBemrV2mp1NMvpyU7uQhywO/O/ann/ISHuBKSY=; h=From:To:Subject:Date:From; b=nD0VXPGkBwIh8z07JIjAT1RtdrsseH2Z+Zp37uitBZtPjWY5jfNUk9X1eehn4H4et aYVCjEL+6RqseJAVws8AqGIgxcO8nAfK69NVecaF1mR4m0ugaT9Js22Ff+/mRyOGy/ Jrwm1+Xe20IeZ0EiYC9QRzyb045+YdA622urHzwc= MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="utf-8" From: Jonathan Wakely To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc r12-9301] libstdc++: Fix gdb FilteringTypePrinter X-Act-Checkin: gcc X-Git-Author: =?utf-8?q?Fran=C3=A7ois_Dumont?= X-Git-Refname: refs/heads/releases/gcc-12 X-Git-Oldrev: 0a6e26e79798057301e5e2f56e89aec65e83161c X-Git-Newrev: 0970eafdc61d750b0b0c8c10c466a506be9583a1 Message-Id: <20230320115502.33F393854806@sourceware.org> Date: Mon, 20 Mar 2023 11:55:02 +0000 (GMT) List-Id: https://gcc.gnu.org/g:0970eafdc61d750b0b0c8c10c466a506be9583a1 commit r12-9301-g0970eafdc61d750b0b0c8c10c466a506be9583a1 Author: François Dumont Date: Wed Oct 5 19:24:55 2022 +0200 libstdc++: Fix gdb FilteringTypePrinter Once we found a matching FilteringTypePrinter instance we look for the associated typedef and check that the returned Python Type is equal to the Type to recognize. But gdb Python Type includes properties to distinguish a typedef from the actual type. So use gdb.types.get_basic_type to check if we are indeed on the same type. Additionnaly enhance FilteringTypePrinter matching mecanism by introducing targ1 that, if not None, will be used as the 1st template parameter. libstdc++-v3/ChangeLog: * python/libstdcxx/v6/printers.py (FilteringTypePrinter): Rename 'match' field 'template'. Add self.targ1 to specify the first template parameter of the instantiation to match. (add_one_type_printer): Add targ1 optional parameter, default to None. Use gdb.types.get_basic_type to compare the type to recognize and the type returned from the typedef lookup. (register_type_printers): Adapt calls to add_one_type_printers. (cherry picked from commit 2b7f0378b915a6a294b330bea00e50069f181bd7) Diff: --- libstdc++-v3/python/libstdcxx/v6/printers.py | 84 ++++++++++++++++------------ 1 file changed, 49 insertions(+), 35 deletions(-) diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py index 593b568b3a1..bb06a4959ee 100644 --- a/libstdc++-v3/python/libstdcxx/v6/printers.py +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py @@ -1988,59 +1988,65 @@ class FilteringTypePrinter(object): A type printer that uses typedef names for common template specializations. Args: - match (str): The class template to recognize. + template (str): The class template to recognize. name (str): The typedef-name that will be used instead. + targ1 (str): The first template argument. + If arg1 is provided (not None), match only template specializations + with this type as the first template argument, + e.g. if template='basic_string is the same type as std::istream then print it as std::istream. """ - def __init__(self, match, name): - self.match = match + def __init__(self, template, name, targ1): + self.template = template self.name = name + self.targ1 = targ1 self.enabled = True class _recognizer(object): "The recognizer class for FilteringTypePrinter." - def __init__(self, match, name): - self.match = match + def __init__(self, template, name, targ1): + self.template = template self.name = name + self.targ1 = targ1 self.type_obj = None def recognize(self, type_obj): """ - If type_obj starts with self.match and is the same type as + If type_obj starts with self.template and is the same type as self.name then return self.name, otherwise None. """ if type_obj.tag is None: return None if self.type_obj is None: - if not type_obj.tag.startswith(self.match): + if self.targ1 is not None: + if not type_obj.tag.startswith('{}<{}'.format(self.template, self.targ1)): + # Filter didn't match. + return None + elif not type_obj.tag.startswith(self.template): # Filter didn't match. return None + try: self.type_obj = gdb.lookup_type(self.name).strip_typedefs() except: pass - if self.type_obj == type_obj: - return strip_inline_namespaces(self.name) if self.type_obj is None: return None - # Workaround ambiguous typedefs matching both std:: and std::__cxx11:: symbols. - ambiguous = False - for ch in ('', 'w', 'u8', 'u16', 'u32'): - if self.name == 'std::' + ch + 'string': - ambiguous = True - break + if gdb.types.get_basic_type(self.type_obj) == gdb.types.get_basic_type(type_obj): + return strip_inline_namespaces(self.name) - if ambiguous: + # Workaround ambiguous typedefs matching both std:: and std::__cxx11:: symbols. + if self.template.split('::')[-1] == 'basic_string': if self.type_obj.tag.replace('__cxx11::', '') == type_obj.tag.replace('__cxx11::', ''): return strip_inline_namespaces(self.name) @@ -2048,14 +2054,14 @@ class FilteringTypePrinter(object): def instantiate(self): "Return a recognizer object for this type printer." - return self._recognizer(self.match, self.name) + return self._recognizer(self.template, self.name, self.targ1) -def add_one_type_printer(obj, match, name): - printer = FilteringTypePrinter('std::' + match, 'std::' + name) +def add_one_type_printer(obj, template, name, targ1 = None): + printer = FilteringTypePrinter('std::' + template, 'std::' + name, targ1) gdb.types.register_type_printer(obj, printer) - if _versioned_namespace and not '__cxx11' in match: + if _versioned_namespace and not '__cxx11' in template: ns = 'std::' + _versioned_namespace - printer = FilteringTypePrinter(ns + match, ns + name) + printer = FilteringTypePrinter(ns + template, ns + name, targ1) gdb.types.register_type_printer(obj, printer) def register_type_printers(obj): @@ -2065,29 +2071,33 @@ def register_type_printers(obj): return # Add type printers for typedefs std::string, std::wstring etc. - for ch in ('', 'w', 'u8', 'u16', 'u32'): - add_one_type_printer(obj, 'basic_string', ch + 'string') - add_one_type_printer(obj, '__cxx11::basic_string', ch + 'string') + for ch in (('', 'char'), + ('w', 'wchar_t'), + ('u8', 'char8_t'), + ('u16', 'char16_t'), + ('u32', 'char32_t')): + add_one_type_printer(obj, 'basic_string', ch[0] + 'string', ch[1]) + add_one_type_printer(obj, '__cxx11::basic_string', ch[0] + 'string', ch[1]) # Typedefs for __cxx11::basic_string used to be in namespace __cxx11: add_one_type_printer(obj, '__cxx11::basic_string', - '__cxx11::' + ch + 'string') - add_one_type_printer(obj, 'basic_string_view', ch + 'string_view') + '__cxx11::' + ch[0] + 'string', ch[1]) + add_one_type_printer(obj, 'basic_string_view', ch[0] + 'string_view', ch[1]) # Add type printers for typedefs std::istream, std::wistream etc. - for ch in ('', 'w'): + for ch in (('', 'char'), ('w', 'wchar_t')): for x in ('ios', 'streambuf', 'istream', 'ostream', 'iostream', 'filebuf', 'ifstream', 'ofstream', 'fstream'): - add_one_type_printer(obj, 'basic_' + x, ch + x) + add_one_type_printer(obj, 'basic_' + x, ch[0] + x, ch[1]) for x in ('stringbuf', 'istringstream', 'ostringstream', 'stringstream'): - add_one_type_printer(obj, 'basic_' + x, ch + x) + add_one_type_printer(obj, 'basic_' + x, ch[0] + x, ch[1]) # types are in __cxx11 namespace, but typedefs aren't: - add_one_type_printer(obj, '__cxx11::basic_' + x, ch + x) + add_one_type_printer(obj, '__cxx11::basic_' + x, ch[0] + x, ch[1]) # Add type printers for typedefs regex, wregex, cmatch, wcmatch etc. for abi in ('', '__cxx11::'): - for ch in ('', 'w'): - add_one_type_printer(obj, abi + 'basic_regex', abi + ch + 'regex') + for ch in (('', 'char'), ('w', 'wchar_t')): + add_one_type_printer(obj, abi + 'basic_regex', abi + ch[0] + 'regex', ch[1]) for ch in ('c', 's', 'wc', 'ws'): add_one_type_printer(obj, abi + 'match_results', abi + ch + 'match') for x in ('sub_match', 'regex_iterator', 'regex_token_iterator'): @@ -2115,9 +2125,13 @@ def register_type_printers(obj): # Add type printers for experimental::basic_string_view typedefs. ns = 'experimental::fundamentals_v1::' - for ch in ('', 'w', 'u8', 'u16', 'u32'): + for ch in (('', 'char'), + ('w', 'wchar_t'), + ('u8', 'char8_t'), + ('u16', 'char16_t'), + ('u32', 'char32_t')): add_one_type_printer(obj, ns + 'basic_string_view', - ns + ch + 'string_view') + ns + ch[0] + 'string_view', ch[1]) # Do not show defaulted template arguments in class templates. add_one_template_type_printer(obj, 'unique_ptr',