diff options
author | Owen Avery <powerboat9.gamer@gmail.com> | 2023-06-07 12:26:37 -0400 |
---|---|---|
committer | CohenArthur <arthur.cohen@embecosm.com> | 2023-06-27 15:20:30 +0000 |
commit | 2983beb0d9101a8bf31890951f4a4094bd603f08 (patch) | |
tree | 7ef764f894825510a964070822760b62c00f1db1 /gcc | |
parent | 5711a2ad9322f11cf86c50f7a4c968f8f7d2d421 (diff) | |
download | gcc-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.cc | 75 | ||||
-rw-r--r-- | gcc/rust/expand/rust-macro-expand.h | 5 | ||||
-rw-r--r-- | 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 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!(); |