]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Match tokens in macros more closely
authorOwen Avery <powerboat9.gamer@gmail.com>
Mon, 26 Jun 2023 17:06:10 +0000 (13:06 -0400)
committerArthur Cohen <arthur.cohen@embecosm.com>
Tue, 16 Jan 2024 17:46:30 +0000 (18:46 +0100)
gcc/rust/ChangeLog:

* expand/rust-macro-expand.cc
(MacroExpander::match_token): Match token instead of token id.
* parse/rust-parse-impl.h
(Parser::skip_token): Add token-skipping variant.
(Parser::expect_token): Likewise.
* parse/rust-parse.h
(Parser::skip_token): Likewise.
(Parser::expect_token): Likewise.

gcc/testsuite/ChangeLog:

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

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

index d14b3b3806a7170a92b3397c3c1af91f9731f6ef..27a298efc308725947d7f33f62a92249720b6a94 100644 (file)
@@ -569,8 +569,7 @@ MacroExpander::match_matcher (Parser<MacroInvocLexer> &parser,
 bool
 MacroExpander::match_token (Parser<MacroInvocLexer> &parser, AST::Token &token)
 {
-  // FIXME this needs to actually match the content and the type
-  return parser.skip_token (token.get_id ());
+  return parser.skip_token (token.get_tok_ptr ());
 }
 
 bool
index ff929d3c625ac75392cb52fc53f2e3aea3788776..bc87ed72345bb6583325fa9ab96f9de9037c85d1 100644 (file)
@@ -11936,6 +11936,15 @@ Parser<ManagedTokenSource>::skip_token (TokenId token_id)
   return expect_token (token_id) != const_TokenPtr ();
 }
 
+/* Checks if current token is similar to inputted token - skips it and returns
+ * true if so, diagnoses an error and returns false otherwise. */
+template <typename ManagedTokenSource>
+bool
+Parser<ManagedTokenSource>::skip_token (const_TokenPtr token)
+{
+  return expect_token (token) != const_TokenPtr ();
+}
+
 /* Checks if current token has inputted id - skips it and returns true if so,
  * returns false otherwise without diagnosing an error */
 template <typename ManagedTokenSource>
@@ -11971,6 +11980,30 @@ Parser<ManagedTokenSource>::expect_token (TokenId token_id)
     }
 }
 
+/* Checks the current token - if same as expected, skips and returns it,
+ * otherwise diagnoses error and returns null. */
+template <typename ManagedTokenSource>
+const_TokenPtr
+Parser<ManagedTokenSource>::expect_token (const_TokenPtr token_expect)
+{
+  const_TokenPtr t = lexer.peek_token ();
+  if (t->get_id () == token_expect->get_id ()
+      && (!t->should_have_str () || t->get_str () == token_expect->get_str ()))
+    {
+      lexer.skip_token ();
+      return t;
+    }
+  else
+    {
+      Error error (t->get_locus (), "expecting %qs but %qs found",
+                  token_expect->get_token_description (),
+                  t->get_token_description ());
+      add_error (std::move (error));
+
+      return const_TokenPtr ();
+    }
+}
+
 // Skips all tokens until EOF or }. Don't use.
 template <typename ManagedTokenSource>
 void
index 620257456620f18cf8dec318bcb0be3dc3077f7a..1d49c956b5c0aae4e822cffd05704e8a05a449a4 100644 (file)
@@ -111,6 +111,15 @@ public:
    */
   bool skip_token (TokenId t);
 
+  /**
+   * Consume a token, reporting an error if it isn't the next token
+   *
+   * @param token pointer to similar token to consume
+   *
+   * @return true if the token was next, false if it wasn't found
+   */
+  bool skip_token (const_TokenPtr token);
+
   /**
    * Same as `skip_token` but allows for failure without necessarily reporting
    * an error
@@ -172,6 +181,7 @@ private:
   void skip_after_end_attribute ();
 
   const_TokenPtr expect_token (TokenId t);
+  const_TokenPtr expect_token (const_TokenPtr token_expect);
   void unexpected_token (const_TokenPtr t);
   bool skip_generics_right_angle ();
 
diff --git a/gcc/testsuite/rust/compile/macro-issue2264.rs b/gcc/testsuite/rust/compile/macro-issue2264.rs
new file mode 100644 (file)
index 0000000..497dd3c
--- /dev/null
@@ -0,0 +1,12 @@
+macro_rules! a {
+    (1) => {x};
+    (2) => {};
+}
+
+macro_rules! b {
+    (a) => {x};
+    (b) => {};
+}
+
+a!(2);
+b!(b);