From: "François Dumont" <frs.dumont@gmail.com>
To: "libstdc++@gcc.gnu.org" <libstdc++@gcc.gnu.org>
Cc: gcc-patches <gcc-patches@gcc.gnu.org>
Subject: [PATCH] Fix gdb FilteringTypePrinter (again)
Date: Thu, 6 Oct 2022 19:38:09 +0200 [thread overview]
Message-ID: <4d1dc3d4-e945-d283-964a-4dab3b3cb33e@gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 1938 bytes --]
Hi
Looks like the previous patch was not enough. When using it in the
context of a build without dual abi and versioned namespace I started
having failures again. I guess I hadn't rebuild everything properly.
This time I think the problem was in those lines:
if self.type_obj == type_obj:
return strip_inline_namespaces(self.name)
I've added a call to gdb.types.get_basic_type so that we do not compare
a type with its typedef.
Thanks for the pointer to the doc !
Doing so I eventually use your code Jonathan to make FilteringTypeFilter
more specific to a given instantiation.
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.
Tested under Linux x86_64 normal, version namespace with or without dual
abi.
François
[-- Attachment #2: gdb_printers.patch --]
[-- Type: text/x-patch, Size: 8406 bytes --]
diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 0fa7805183e..52339b247d8 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -2040,62 +2040,72 @@ def add_one_template_type_printer(obj, name, defargs):
class FilteringTypePrinter(object):
r"""
- A type printer that uses typedef names for common template specializations.
+ A type printer that uses typedef names for common template instantiations.
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), only template instantiations with this type
+ as the first template argument, e.g. if template='basic_string<targ1'
- Checks if a specialization of the class template 'match' is the same type
+ Checks if an instantiation of the class template 'template' is the same type
as the typedef 'name', and prints it as 'name' instead.
- e.g. if an instantiation of std::basic_istream<C, T> is the same type as
+ e.g. for template='basic_istream', name='istream', if any instantiation of
+ std::basic_istream<C, T> is the same type as std::istream then print it as
+ std::istream.
+
+ e.g. for template='basic_istream', name='istream', targ1='char', if any
+ instantiation of std::basic_istream<char, T> 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)
@@ -2103,14 +2113,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):
@@ -2120,29 +2130,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])
# <sstream> 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'):
@@ -2170,9 +2184,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',
next reply other threads:[~2022-10-06 17:38 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-10-06 17:38 François Dumont [this message]
2022-11-14 17:57 ` François Dumont
2022-11-15 16:17 ` Jonathan Wakely
2022-11-16 6:04 ` François Dumont
2022-11-16 11:35 ` Jonathan Wakely
2022-11-16 11:54 ` Jonathan Wakely
2022-11-16 12:29 ` Jonathan Wakely
2022-11-17 5:28 ` François Dumont
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4d1dc3d4-e945-d283-964a-4dab3b3cb33e@gmail.com \
--to=frs.dumont@gmail.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=libstdc++@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).