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 ">".
This commit is contained in:
Tom Tromey 2025-02-23 15:34:40 -07:00
parent 8f6ddbfc7d
commit caf7719651
2 changed files with 24 additions and 0 deletions

View File

@ -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

View File

@ -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
}