From: Owen Avery Date: Tue, 9 May 2023 00:58:59 +0000 (-0400) Subject: gccrs: Handle keywords in macro fragments X-Git-Tag: basepoints/gcc-15~2548 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2aeff9ce08576ad33a29ed6fc6a87e9516b0641f;p=thirdparty%2Fgcc.git gccrs: Handle keywords in macro fragments 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 --- diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc index 09a4849bc8c9..5f6c50e29f47 100644 --- a/gcc/rust/expand/rust-macro-expand.cc +++ b/gcc/rust/expand/rust-macro-expand.cc @@ -378,7 +378,7 @@ MacroExpander::match_fragment (Parser &parser, break; case AST::MacroFragSpec::IDENT: - parser.parse_identifier_pattern (); + parser.parse_identifier_or_keyword_token (); break; case AST::MacroFragSpec::LITERAL: diff --git a/gcc/rust/lex/rust-token.cc b/gcc/rust/lex/rust-token.cc index 8b7cdc0951e0..2956d923d2f1 100644 --- a/gcc/rust/lex/rust-token.cc +++ b/gcc/rust/lex/rust-token.cc @@ -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) { diff --git a/gcc/rust/lex/rust-token.h b/gcc/rust/lex/rust-token.h index 65a37fdb0d0f..48640f5b2434 100644 --- a/gcc/rust/lex/rust-token.h +++ b/gcc/rust/lex/rust-token.h @@ -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); diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h index 1addbe95176d..7fefb16c8d16 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -999,6 +999,24 @@ Parser::parse_delim_token_tree () } } +// Parses an identifier/keyword as a Token +template +std::unique_ptr +Parser::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 (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 diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h index 6957b66a2bba..71f0ff1c0d22 100644 --- a/gcc/rust/parse/rust-parse.h +++ b/gcc/rust/parse/rust-parse.h @@ -148,6 +148,7 @@ public: std::vector > parse_lifetime_params (); AST::Visibility parse_visibility (); std::unique_ptr parse_identifier_pattern (); + std::unique_ptr parse_identifier_or_keyword_token (); std::unique_ptr parse_token_tree (); std::tuple, 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 index 000000000000..deb2dd746600 --- /dev/null +++ b/gcc/testsuite/rust/compile/macro-issue2192.rs @@ -0,0 +1,7 @@ +macro_rules! foo { + ($a:ident) => {} +} + +pub fn bar() { + foo!(self); +}