]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Handle keywords in macro fragments
authorOwen Avery <powerboat9.gamer@gmail.com>
Tue, 9 May 2023 00:58:59 +0000 (20:58 -0400)
committerArthur Cohen <arthur.cohen@embecosm.com>
Tue, 16 Jan 2024 17:37:18 +0000 (18:37 +0100)
gcc/rust/ChangeLog:

* lex/rust-token.cc
(token_id_is_keyword): New.
(token_id_keyword_string): New.
* lex/rust-token.h
(token_id_is_keyword): New.
(token_id_keyword_string): New.
* expand/rust-macro-expand.cc
(MacroExpander::match_fragment): Match keywords for ident fragment.
* parse/rust-parse-impl.h
(Parser::parse_identifier_or_keyword_token): Add.
* parse/rust-parse.h
(Parser::parse_identifier_or_keyword_token): Add.

gcc/testsuite/ChangeLog:

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

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

index 09a4849bc8c96bdedba2e5c321a6f9315720944b..5f6c50e29f4713beb79466f8a350fcc1c65fa552 100644 (file)
@@ -378,7 +378,7 @@ MacroExpander::match_fragment (Parser<MacroInvocLexer> &parser,
       break;
 
     case AST::MacroFragSpec::IDENT:
-      parser.parse_identifier_pattern ();
+      parser.parse_identifier_or_keyword_token ();
       break;
 
     case AST::MacroFragSpec::LITERAL:
index 8b7cdc0951e047ce073f9e52e76d340ecacf94ed..2956d923d2f1a90c5ba7dad74bd9cad04b8375c2 100644 (file)
@@ -57,6 +57,40 @@ token_id_to_str (TokenId id)
     }
 }
 
+/* checks if a token is a keyword */
+bool
+token_id_is_keyword (TokenId id)
+{
+  switch (id)
+    {
+#define RS_TOKEN_KEYWORD(name, _) case name:
+#define RS_TOKEN(a, b)
+      RS_TOKEN_LIST return true;
+#undef RS_TOKEN_KEYWORD
+#undef RS_TOKEN
+    default:
+      return false;
+    }
+}
+
+/* gets the string associated with a keyword */
+const char *
+token_id_keyword_string (TokenId id)
+{
+  switch (id)
+    {
+#define RS_TOKEN_KEYWORD(id, str)                                              \
+  case id:                                                                     \
+    return str;
+#define RS_TOKEN(a, b)
+      RS_TOKEN_LIST
+#undef RS_TOKEN_KEYWORD
+#undef RS_TOKEN
+    default:
+      return nullptr;
+    }
+}
+
 const char *
 get_type_hint_string (PrimitiveCoreType type)
 {
index 65a37fdb0d0fc9b9e2f9a673c827a8222aca258f..48640f5b243420dc2501e5cfa188a5c626dfa8cc 100644 (file)
@@ -226,6 +226,12 @@ get_token_description (TokenId id);
  * x-macros */
 const char *
 token_id_to_str (TokenId id);
+/* checks if a token is a keyword */
+bool
+token_id_is_keyword (TokenId id);
+/* gets the string associated with a keyword */
+const char *
+token_id_keyword_string (TokenId id);
 // Get type hint description as a string.
 const char *
 get_type_hint_string (PrimitiveCoreType type);
index 1addbe95176da664c70715110f987f27f74c3ed5..7fefb16c8d16f3602062b88da63597263167dcf4 100644 (file)
@@ -999,6 +999,24 @@ Parser<ManagedTokenSource>::parse_delim_token_tree ()
     }
 }
 
+// Parses an identifier/keyword as a Token
+template <typename ManagedTokenSource>
+std::unique_ptr<AST::Token>
+Parser<ManagedTokenSource>::parse_identifier_or_keyword_token ()
+{
+  const_TokenPtr t = lexer.peek_token ();
+
+  if (t->get_id () == IDENTIFIER || token_id_is_keyword (t->get_id ()))
+    {
+      lexer.skip_token ();
+      return std::unique_ptr<AST::Token> (new AST::Token (std::move (t)));
+    }
+  else
+    {
+      return nullptr;
+    }
+}
+
 /* Parses a TokenTree syntactical production. This is either a delimited token
  * tree or a non-delimiter token. */
 template <typename ManagedTokenSource>
index 6957b66a2bba4e44a576b9675d4d826d766f5e0e..71f0ff1c0d22613c688811ccb57d466896ee2b47 100644 (file)
@@ -148,6 +148,7 @@ public:
   std::vector<std::unique_ptr<AST::LifetimeParam> > parse_lifetime_params ();
   AST::Visibility parse_visibility ();
   std::unique_ptr<AST::IdentifierPattern> parse_identifier_pattern ();
+  std::unique_ptr<AST::Token> parse_identifier_or_keyword_token ();
   std::unique_ptr<AST::TokenTree> parse_token_tree ();
   std::tuple<AST::SimplePath, std::unique_ptr<AST::AttrInput>, Location>
   parse_attribute_body ();
diff --git a/gcc/testsuite/rust/compile/macro-issue2192.rs b/gcc/testsuite/rust/compile/macro-issue2192.rs
new file mode 100644 (file)
index 0000000..deb2dd7
--- /dev/null
@@ -0,0 +1,7 @@
+macro_rules! foo {
+    ($a:ident) => {}
+}
+
+pub fn bar() {
+    foo!(self);
+}