Skip to content

Commit 2983beb

Browse files
powerboat9CohenArthur
authored andcommitted
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 <[email protected]>
1 parent 5711a2a commit 2983beb

File tree

3 files changed

+67
-18
lines changed

3 files changed

+67
-18
lines changed

gcc/rust/expand/rust-macro-expand.cc

Lines changed: 57 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,62 @@ MacroExpander::match_n_matches (Parser<MacroInvocLexer> &parser,
669669
return res;
670670
}
671671

672+
/*
673+
* Helper function for defining unmatched repetition metavars
674+
*/
675+
void
676+
MacroExpander::match_repetition_skipped_metavars (AST::MacroMatch &match)
677+
{
678+
// We have to handle zero fragments differently: They will not have been
679+
// "matched" but they are still valid and should be inserted as a special
680+
// case. So we go through the stack map, and for every fragment which doesn't
681+
// exist, insert a zero-matched fragment.
682+
switch (match.get_macro_match_type ())
683+
{
684+
case AST::MacroMatch::MacroMatchType::Fragment:
685+
match_repetition_skipped_metavars (
686+
static_cast<AST::MacroMatchFragment &> (match));
687+
break;
688+
case AST::MacroMatch::MacroMatchType::Repetition:
689+
match_repetition_skipped_metavars (
690+
static_cast<AST::MacroMatchRepetition &> (match));
691+
break;
692+
case AST::MacroMatch::MacroMatchType::Matcher:
693+
match_repetition_skipped_metavars (
694+
static_cast<AST::MacroMatcher &> (match));
695+
break;
696+
case AST::MacroMatch::MacroMatchType::Tok:
697+
break;
698+
}
699+
}
700+
701+
void
702+
MacroExpander::match_repetition_skipped_metavars (
703+
AST::MacroMatchFragment &fragment)
704+
{
705+
auto &stack_map = sub_stack.peek ();
706+
auto it = stack_map.find (fragment.get_ident ());
707+
708+
if (it == stack_map.end ())
709+
sub_stack.insert_matches (fragment.get_ident (),
710+
MatchedFragmentContainer::zero ());
711+
}
712+
713+
void
714+
MacroExpander::match_repetition_skipped_metavars (
715+
AST::MacroMatchRepetition &rep)
716+
{
717+
for (auto &match : rep.get_matches ())
718+
match_repetition_skipped_metavars (*match);
719+
}
720+
721+
void
722+
MacroExpander::match_repetition_skipped_metavars (AST::MacroMatcher &rep)
723+
{
724+
for (auto &match : rep.get_matches ())
725+
match_repetition_skipped_metavars (*match);
726+
}
727+
672728
bool
673729
MacroExpander::match_repetition (Parser<MacroInvocLexer> &parser,
674730
AST::MacroMatchRepetition &rep)
@@ -703,24 +759,7 @@ MacroExpander::match_repetition (Parser<MacroInvocLexer> &parser,
703759
res ? "successfully" : "unsuccessfully",
704760
(unsigned long) match_amount);
705761

706-
// We have to handle zero fragments differently: They will not have been
707-
// "matched" but they are still valid and should be inserted as a special
708-
// case. So we go through the stack map, and for every fragment which doesn't
709-
// exist, insert a zero-matched fragment.
710-
auto &stack_map = sub_stack.peek ();
711-
for (auto &match : rep.get_matches ())
712-
{
713-
if (match->get_macro_match_type ()
714-
== AST::MacroMatch::MacroMatchType::Fragment)
715-
{
716-
auto fragment = static_cast<AST::MacroMatchFragment *> (match.get ());
717-
auto it = stack_map.find (fragment->get_ident ());
718-
719-
if (it == stack_map.end ())
720-
sub_stack.insert_matches (fragment->get_ident (),
721-
MatchedFragmentContainer::zero ());
722-
}
723-
}
762+
match_repetition_skipped_metavars (rep);
724763

725764
return res;
726765
}

gcc/rust/expand/rust-macro-expand.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,11 @@ struct MacroExpander
304304

305305
bool match_token (Parser<MacroInvocLexer> &parser, AST::Token &token);
306306

307+
void match_repetition_skipped_metavars (AST::MacroMatch &);
308+
void match_repetition_skipped_metavars (AST::MacroMatchFragment &);
309+
void match_repetition_skipped_metavars (AST::MacroMatchRepetition &);
310+
void match_repetition_skipped_metavars (AST::MacroMatcher &);
311+
307312
bool match_repetition (Parser<MacroInvocLexer> &parser,
308313
AST::MacroMatchRepetition &rep);
309314

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
macro_rules! foo {
2+
($(+ $($a:ident)*)*) => {$($($a)*)*}
3+
}
4+
5+
foo!();

0 commit comments

Comments
 (0)