aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorOwen Avery <powerboat9.gamer@gmail.com>2023-06-07 12:26:37 -0400
committerCohenArthur <arthur.cohen@embecosm.com>2023-06-27 15:20:30 +0000
commit2983beb0d9101a8bf31890951f4a4094bd603f08 (patch)
tree7ef764f894825510a964070822760b62c00f1db1 /gcc
parent5711a2ad9322f11cf86c50f7a4c968f8f7d2d421 (diff)
downloadgcc-2983beb0d9101a8bf31890951f4a4094bd603f08.zip
gcc-2983beb0d9101a8bf31890951f4a4094bd603f08.tar.gz
gcc-2983beb0d9101a8bf31890951f4a4094bd603f08.tar.bz2
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>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/expand/rust-macro-expand.cc75
-rw-r--r--gcc/rust/expand/rust-macro-expand.h5
-rw-r--r--gcc/testsuite/rust/compile/macro-issue2268.rs5
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 a45c13f..729d928 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 d8c8147..988a9df 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 0000000..4bd9c10
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro-issue2268.rs
@@ -0,0 +1,5 @@
+macro_rules! foo {
+ ($(+ $($a:ident)*)*) => {$($($a)*)*}
+}
+
+foo!();