From 142b84e3c56252004348f57c0822dca39d437395 Mon Sep 17 00:00:00 2001 From: Owen Avery Date: Mon, 8 May 2023 20:58:59 -0400 Subject: 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 --- gcc/rust/expand/rust-macro-expand.cc | 2 +- gcc/rust/lex/rust-token.cc | 34 +++++++++++++++++++++++++++ gcc/rust/lex/rust-token.h | 6 +++++ gcc/rust/parse/rust-parse-impl.h | 18 ++++++++++++++ gcc/rust/parse/rust-parse.h | 1 + gcc/testsuite/rust/compile/macro-issue2192.rs | 7 ++++++ 6 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/rust/compile/macro-issue2192.rs (limited to 'gcc') diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc index c28f4b6..b607cd5 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 f7b089e..179560d 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 39c21cd..9dea83c 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 cdcc8b8..1824545 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 6957b66..71f0ff1 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 0000000..deb2dd7 --- /dev/null +++ b/gcc/testsuite/rust/compile/macro-issue2192.rs @@ -0,0 +1,7 @@ +macro_rules! foo { + ($a:ident) => {} +} + +pub fn bar() { + foo!(self); +} -- cgit v1.1