[gcc r14-7699] gccrs: Insert empty repeated metavars for nested repetitions

Arthur Cohen cohenarthur@gcc.gnu.org
Tue Jan 16 17:54:50 GMT 2024


https://gcc.gnu.org/g:0770c239f475ed2ae25d96175019865156db516e

commit r14-7699-g0770c239f475ed2ae25d96175019865156db516e
Author: Owen Avery <powerboat9.gamer@gmail.com>
Date:   Wed Jun 7 12:26:37 2023 -0400

    gccrs: Insert empty repeated metavars for nested repetitions
    
    gcc/rust/ChangeLog:
    
            * expand/rust-macro-expand.cc
            (MacroExpander::match_repetition_skipped_metavars): New.
            (MacroExpander::match_repetition): Use new method.
            * expand/rust-macro-expand.h
            (MacroExpander::match_repetition_skipped_metavars): New.
    
    gcc/testsuite/ChangeLog:
    
            * rust/compile/macro-issue2268.rs: New test.
    
    Signed-off-by: Owen Avery <powerboat9.gamer@gmail.com>

Diff:
---
 gcc/rust/expand/rust-macro-expand.cc          | 75 ++++++++++++++++++++-------
 gcc/rust/expand/rust-macro-expand.h           |  5 ++
 gcc/testsuite/rust/compile/macro-issue2268.rs |  5 ++
 3 files changed, 67 insertions(+), 18 deletions(-)

diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc
index 27a298efc30..0d8b930cb58 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -669,6 +669,62 @@ MacroExpander::match_n_matches (Parser<MacroInvocLexer> &parser,
   return res;
 }
 
+/*
+ * Helper function for defining unmatched repetition metavars
+ */
+void
+MacroExpander::match_repetition_skipped_metavars (AST::MacroMatch &match)
+{
+  // We have to handle zero fragments differently: They will not have been
+  // "matched" but they are still valid and should be inserted as a special
+  // case. So we go through the stack map, and for every fragment which doesn't
+  // exist, insert a zero-matched fragment.
+  switch (match.get_macro_match_type ())
+    {
+    case AST::MacroMatch::MacroMatchType::Fragment:
+      match_repetition_skipped_metavars (
+	static_cast<AST::MacroMatchFragment &> (match));
+      break;
+    case AST::MacroMatch::MacroMatchType::Repetition:
+      match_repetition_skipped_metavars (
+	static_cast<AST::MacroMatchRepetition &> (match));
+      break;
+    case AST::MacroMatch::MacroMatchType::Matcher:
+      match_repetition_skipped_metavars (
+	static_cast<AST::MacroMatcher &> (match));
+      break;
+    case AST::MacroMatch::MacroMatchType::Tok:
+      break;
+    }
+}
+
+void
+MacroExpander::match_repetition_skipped_metavars (
+  AST::MacroMatchFragment &fragment)
+{
+  auto &stack_map = sub_stack.peek ();
+  auto it = stack_map.find (fragment.get_ident ());
+
+  if (it == stack_map.end ())
+    sub_stack.insert_matches (fragment.get_ident (),
+			      MatchedFragmentContainer::zero ());
+}
+
+void
+MacroExpander::match_repetition_skipped_metavars (
+  AST::MacroMatchRepetition &rep)
+{
+  for (auto &match : rep.get_matches ())
+    match_repetition_skipped_metavars (*match);
+}
+
+void
+MacroExpander::match_repetition_skipped_metavars (AST::MacroMatcher &rep)
+{
+  for (auto &match : rep.get_matches ())
+    match_repetition_skipped_metavars (*match);
+}
+
 bool
 MacroExpander::match_repetition (Parser<MacroInvocLexer> &parser,
 				 AST::MacroMatchRepetition &rep)
@@ -703,24 +759,7 @@ MacroExpander::match_repetition (Parser<MacroInvocLexer> &parser,
 		  res ? "successfully" : "unsuccessfully",
 		  (unsigned long) match_amount);
 
-  // We have to handle zero fragments differently: They will not have been
-  // "matched" but they are still valid and should be inserted as a special
-  // case. So we go through the stack map, and for every fragment which doesn't
-  // exist, insert a zero-matched fragment.
-  auto &stack_map = sub_stack.peek ();
-  for (auto &match : rep.get_matches ())
-    {
-      if (match->get_macro_match_type ()
-	  == AST::MacroMatch::MacroMatchType::Fragment)
-	{
-	  auto fragment = static_cast<AST::MacroMatchFragment *> (match.get ());
-	  auto it = stack_map.find (fragment->get_ident ());
-
-	  if (it == stack_map.end ())
-	    sub_stack.insert_matches (fragment->get_ident (),
-				      MatchedFragmentContainer::zero ());
-	}
-    }
+  match_repetition_skipped_metavars (rep);
 
   return res;
 }
diff --git a/gcc/rust/expand/rust-macro-expand.h b/gcc/rust/expand/rust-macro-expand.h
index ce8d0f2c7d4..378a7e25f50 100644
--- a/gcc/rust/expand/rust-macro-expand.h
+++ b/gcc/rust/expand/rust-macro-expand.h
@@ -304,6 +304,11 @@ struct MacroExpander
 
   bool match_token (Parser<MacroInvocLexer> &parser, AST::Token &token);
 
+  void match_repetition_skipped_metavars (AST::MacroMatch &);
+  void match_repetition_skipped_metavars (AST::MacroMatchFragment &);
+  void match_repetition_skipped_metavars (AST::MacroMatchRepetition &);
+  void match_repetition_skipped_metavars (AST::MacroMatcher &);
+
   bool match_repetition (Parser<MacroInvocLexer> &parser,
 			 AST::MacroMatchRepetition &rep);
 
diff --git a/gcc/testsuite/rust/compile/macro-issue2268.rs b/gcc/testsuite/rust/compile/macro-issue2268.rs
new file mode 100644
index 00000000000..4bd9c101c73
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro-issue2268.rs
@@ -0,0 +1,5 @@
+macro_rules! foo {
+    ($(+ $($a:ident)*)*) => {$($($a)*)*}
+}
+
+foo!();


More information about the Gcc-cvs mailing list