aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2025-02-23 15:34:40 -0700
committerTom Tromey <tom@tromey.com>2025-03-07 08:09:29 -0700
commitcaf77196512fd866663b216486c3ae317c20a2bf (patch)
tree4195672c128106993dcb82306a3d7a15f84d2b80
parent8f6ddbfc7dfd24b18d0b2ae2c47212ef85b45068 (diff)
downloadbinutils-caf77196512fd866663b216486c3ae317c20a2bf.zip
binutils-caf77196512fd866663b216486c3ae317c20a2bf.tar.gz
binutils-caf77196512fd866663b216486c3ae317c20a2bf.tar.bz2
Handle ">>" in cp-name-parser.y
I noticed that a certain name didn't work correctly when trying to remove the parameters. I put this into lookup_name_info-selftests.c. I tracked this down to the fact that cp-name-parser.y doesn't handle ">>" to end templates. This patch fixes this in a simple way -- accepting the "RSH" token where appropriate and then un-pushing a ">".
-rw-r--r--gdb/cp-name-parser.y21
-rw-r--r--gdb/unittests/lookup_name_info-selftests.c3
2 files changed, 24 insertions, 0 deletions
diff --git a/gdb/cp-name-parser.y b/gdb/cp-name-parser.y
index 14ee6cf..6c36abe 100644
--- a/gdb/cp-name-parser.y
+++ b/gdb/cp-name-parser.y
@@ -81,6 +81,14 @@ struct cpname_state
demangle_info (info)
{ }
+ /* Un-push a character into the lexer. This can only un-push the
+ previous character in the input string. */
+ void unpush (char c)
+ {
+ gdb_assert (lexptr[-1] == c);
+ --lexptr;
+ }
+
/* LEXPTR is the current pointer into our lex buffer. PREV_LEXPTR
is the start of the last token lexed, only used for diagnostics.
ERROR_LEXPTR is the first place an error occurred. GLOBAL_ERRMSG
@@ -515,6 +523,11 @@ conversion_op_name
unqualified_name: oper
| oper '<' template_params '>'
{ $$ = state->fill_comp (DEMANGLE_COMPONENT_TEMPLATE, $1, $3.comp); }
+ | oper '<' template_params RSH
+ {
+ $$ = state->fill_comp (DEMANGLE_COMPONENT_TEMPLATE, $1, $3.comp);
+ state->unpush ('>');
+ }
| '~' NAME
{ $$ = state->make_dtor (gnu_v3_complete_object_dtor, $2); }
;
@@ -580,6 +593,11 @@ nested_name : NAME COLONCOLON
/* DEMANGLE_COMPONENT_TEMPLATE_ARGLIST */
templ : NAME '<' template_params '>'
{ $$ = state->fill_comp (DEMANGLE_COMPONENT_TEMPLATE, $1, $3.comp); }
+ | NAME '<' template_params RSH
+ {
+ $$ = state->fill_comp (DEMANGLE_COMPONENT_TEMPLATE, $1, $3.comp);
+ state->unpush ('>');
+ }
;
template_params : template_arg
@@ -2085,6 +2103,9 @@ canonicalize_tests ()
should_be_the_same ("something<void ()>", "something<void (void)>");
should_parse ("void whatever::operator<=><int, int>");
+
+ should_be_the_same ("Foozle<int>::fogey<Empty<int> > (Empty<int>)",
+ "Foozle<int>::fogey<Empty<int>> (Empty<int>)");
}
#endif
diff --git a/gdb/unittests/lookup_name_info-selftests.c b/gdb/unittests/lookup_name_info-selftests.c
index a6b5085..fb4be21 100644
--- a/gdb/unittests/lookup_name_info-selftests.c
+++ b/gdb/unittests/lookup_name_info-selftests.c
@@ -96,6 +96,9 @@ run_tests ()
CHECK (language_cplus, "A::B::C()", "A::B::C");
CHECK (language_cplus, "A::B::C", "A::B::C");
+ CHECK (language_cplus, "Foozle<int>::fogey<Empty<int>> (Empty<int>)",
+ "Foozle<int>::fogey<Empty<int> >");
+
#undef CHECK
#undef CHECK_INCOMPL
}