]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Handle ">>" in cp-name-parser.y
authorTom Tromey <tom@tromey.com>
Sun, 23 Feb 2025 22:34:40 +0000 (15:34 -0700)
committerTom Tromey <tom@tromey.com>
Fri, 7 Mar 2025 15:09:29 +0000 (08:09 -0700)
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 ">".

gdb/cp-name-parser.y
gdb/unittests/lookup_name_info-selftests.c

index 14ee6cfb9fc9ee8ac0255884a45648db05f4527e..6c36abea4b079f0761f8b21d9f323b97e2c78022 100644 (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
index a6b50851cc96d5e0143f64a7d901a2a8e08f1eba..fb4be2133cb6d5269a18e31f7f3b4dd8947b07e1 100644 (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
 }