diff options
author | Tom Tromey <tom@tromey.com> | 2025-02-23 15:34:40 -0700 |
---|---|---|
committer | Tom Tromey <tom@tromey.com> | 2025-03-07 08:09:29 -0700 |
commit | caf77196512fd866663b216486c3ae317c20a2bf (patch) | |
tree | 4195672c128106993dcb82306a3d7a15f84d2b80 | |
parent | 8f6ddbfc7dfd24b18d0b2ae2c47212ef85b45068 (diff) | |
download | binutils-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.y | 21 | ||||
-rw-r--r-- | gdb/unittests/lookup_name_info-selftests.c | 3 |
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 } |