]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Properly match delimiters
authorOwen Avery <powerboat9.gamer@gmail.com>
Tue, 30 May 2023 20:24:08 +0000 (16:24 -0400)
committerArthur Cohen <arthur.cohen@embecosm.com>
Tue, 16 Jan 2024 17:37:23 +0000 (18:37 +0100)
gcc/rust/ChangeLog:

* expand/rust-macro-expand.cc
(MacroExpander::try_match_rule): Don't match delimiters for root matcher.
(MacroExpander::match_matcher): Add option to match delimiters.
* expand/rust-macro-expand.h
(MacroExpander::match_matcher): Likewise.
* parse/rust-parse-impl.h
(Parser::skip_token): Add zero argument method.
* parse/rust-parse.h:
(Parser::skip_token): Likewise.

gcc/testsuite/ChangeLog:

* rust/compile/macro-delim.rs: New test.

Signed-off-by: Owen Avery <powerboat9.gamer@gmail.com>
gcc/rust/expand/rust-macro-expand.cc
gcc/rust/expand/rust-macro-expand.h
gcc/rust/parse/rust-parse-impl.h
gcc/rust/parse/rust-parse.h
gcc/testsuite/rust/compile/macro-delim.rs [new file with mode: 0644]

index f347335f2efedcfe1bc69ba1a164fa125ee9743a..7229a09f2fe5bad1e54140ed1c88fda70b669a43 100644 (file)
@@ -352,7 +352,7 @@ MacroExpander::try_match_rule (AST::MacroRule &match_rule,
   AST::MacroMatcher &matcher = match_rule.get_matcher ();
 
   expansion_depth++;
-  if (!match_matcher (parser, matcher))
+  if (!match_matcher (parser, matcher, false, false))
     {
       expansion_depth--;
       return false;
@@ -437,7 +437,8 @@ MacroExpander::match_fragment (Parser<MacroInvocLexer> &parser,
 
 bool
 MacroExpander::match_matcher (Parser<MacroInvocLexer> &parser,
-                             AST::MacroMatcher &matcher, bool in_repetition)
+                             AST::MacroMatcher &matcher, bool in_repetition,
+                             bool match_delim)
 {
   if (depth_exceeds_recursion_limit ())
     {
@@ -447,29 +448,34 @@ MacroExpander::match_matcher (Parser<MacroInvocLexer> &parser,
 
   auto delimiter = parser.peek_current_token ();
 
+  auto check_delim = [&matcher, match_delim] (AST::DelimType delim) {
+    return !match_delim || matcher.get_delim_type () == delim;
+  };
+
   // this is used so we can check that we delimit the stream correctly.
   switch (delimiter->get_id ())
     {
       case LEFT_PAREN: {
-       if (!parser.skip_token (LEFT_PAREN))
+       if (!check_delim (AST::DelimType::PARENS))
          return false;
       }
       break;
 
       case LEFT_SQUARE: {
-       if (!parser.skip_token (LEFT_SQUARE))
+       if (!check_delim (AST::DelimType::SQUARE))
          return false;
       }
       break;
 
       case LEFT_CURLY: {
-       if (!parser.skip_token (LEFT_CURLY))
+       if (!check_delim (AST::DelimType::CURLY))
          return false;
       }
       break;
     default:
-      gcc_unreachable ();
+      return false;
     }
+  parser.skip_token ();
 
   const MacroInvocLexer &source = parser.get_token_source ();
 
index ceac8e60405770a6f4ff2d67a00694d17190bc57..a24ec4f682c004d27b891c3ae381f6330481c77d 100644 (file)
@@ -275,7 +275,8 @@ struct MacroExpander
                         AST::MacroMatchRepetition &rep);
 
   bool match_matcher (Parser<MacroInvocLexer> &parser,
-                     AST::MacroMatcher &matcher, bool in_repetition = false);
+                     AST::MacroMatcher &matcher, bool in_repetition = false,
+                     bool match_delim = true);
 
   /**
    * Match any amount of matches
index 3f2500660df61081e90c49054aec871c1e4682fc..9faa374915c6f3cfc52daa2825f39bf51d22a1dc 100644 (file)
@@ -12159,6 +12159,14 @@ Parser<ManagedTokenSource>::skip_after_semicolon ()
     lexer.skip_token ();
 }
 
+/* Skips the current token */
+template <typename ManagedTokenSource>
+void
+Parser<ManagedTokenSource>::skip_token ()
+{
+  lexer.skip_token ();
+}
+
 /* Checks if current token has inputted id - skips it and returns true if so,
  * diagnoses an error and returns false otherwise. */
 template <typename ManagedTokenSource>
index 1e7e5262eec5882b81948488de9cd64591161ff0..315d3fcdec6cdde8aa464b8f8dc41e0ed1dc88e9 100644 (file)
@@ -94,6 +94,11 @@ struct ParseRestrictions
 template <typename ManagedTokenSource> class Parser
 {
 public:
+  /**
+   * Consume a token
+   */
+  void skip_token ();
+
   /**
    * Consume a token, reporting an error if it isn't the next token
    *
diff --git a/gcc/testsuite/rust/compile/macro-delim.rs b/gcc/testsuite/rust/compile/macro-delim.rs
new file mode 100644 (file)
index 0000000..de4cd56
--- /dev/null
@@ -0,0 +1,8 @@
+macro_rules! foo {
+    ([]) => {struct Foo;};
+    (()) => {struct _A;};
+    (bool) => {struct _B;};
+}
+
+foo! (());
+foo! (bool);