aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen Avery <powerboat9.gamer@gmail.com>2023-05-17 12:32:23 -0400
committerCohenArthur <arthur.cohen@embecosm.com>2023-05-18 20:29:52 +0000
commitee5b5905deba07104dec5bdbb889b9754c0e9c89 (patch)
tree1954cb3650f2f864424cbbccfa00e21b1ca6b63a
parent5c78ef9854b560940aeaf36e74439ce3f10d5eb2 (diff)
downloadgcc-ee5b5905deba07104dec5bdbb889b9754c0e9c89.zip
gcc-ee5b5905deba07104dec5bdbb889b9754c0e9c89.tar.gz
gcc-ee5b5905deba07104dec5bdbb889b9754c0e9c89.tar.bz2
Handle keyword metavariables
gcc/rust/ChangeLog: * expand/rust-macro-substitute-ctx.cc (SubstituteCtx::check_repetition_amount): Handle keywords. (SubstituteCtx::substitute_token): Likewise. * lex/rust-token.cc (Token::get_str): Likewise. * parse/rust-parse-impl.h (Parser::parse_macro_match_fragment): Likewise. gcc/testsuite/ChangeLog: * rust/compile/macro-issue2194.rs: New test. Signed-off-by: Owen Avery <powerboat9.gamer@gmail.com>
-rw-r--r--gcc/rust/expand/rust-macro-substitute-ctx.cc24
-rw-r--r--gcc/rust/lex/rust-token.cc3
-rw-r--r--gcc/rust/parse/rust-parse-impl.h6
-rw-r--r--gcc/testsuite/rust/compile/macro-issue2194.rs7
4 files changed, 28 insertions, 12 deletions
diff --git a/gcc/rust/expand/rust-macro-substitute-ctx.cc b/gcc/rust/expand/rust-macro-substitute-ctx.cc
index eb0f149..0a38578 100644
--- a/gcc/rust/expand/rust-macro-substitute-ctx.cc
+++ b/gcc/rust/expand/rust-macro-substitute-ctx.cc
@@ -58,7 +58,8 @@ SubstituteCtx::check_repetition_amount (size_t pattern_start,
if (macro.at (i)->get_id () == DOLLAR_SIGN)
{
auto &frag_token = macro.at (i + 1);
- if (frag_token->get_id () == IDENTIFIER)
+ if (token_id_is_keyword (frag_token->get_id ())
+ || frag_token->get_id () == IDENTIFIER)
{
auto it = fragments.find (frag_token->get_str ());
if (it == fragments.end ())
@@ -199,11 +200,21 @@ std::pair<std::vector<std::unique_ptr<AST::Token>>, size_t>
SubstituteCtx::substitute_token (size_t token_idx)
{
auto &token = macro.at (token_idx);
+
switch (token->get_id ())
{
- case IDENTIFIER:
- rust_debug ("expanding metavar: %s", token->get_str ().c_str ());
- return {substitute_metavar (token), 1};
+ default:
+ if (token_id_is_keyword (token->get_id ()))
+ {
+ case IDENTIFIER:
+ rust_debug ("expanding metavar: %s", token->get_str ().c_str ());
+ return {substitute_metavar (token), 1};
+ }
+ rust_error_at (token->get_locus (),
+ "unexpected token in macro transcribe: expected "
+ "%<(%> or identifier after %<$%>, got %<%s%>",
+ get_token_description (token->get_id ()));
+ break;
case LEFT_PAREN: {
// We need to parse up until the closing delimiter and expand this
// fragment->n times.
@@ -279,11 +290,6 @@ SubstituteCtx::substitute_token (size_t token_idx)
// with no associated fragment and paste the dollar sign in the
// transcription. Unsure how to do that since we always have at
// least the closing curly brace after an empty $...
- default:
- rust_error_at (token->get_locus (),
- "unexpected token in macro transcribe: expected "
- "%<(%> or identifier after %<$%>, got %<%s%>",
- get_token_description (token->get_id ()));
}
// FIXME: gcc_unreachable() error case?
diff --git a/gcc/rust/lex/rust-token.cc b/gcc/rust/lex/rust-token.cc
index 0b5163c..b6be9ca 100644
--- a/gcc/rust/lex/rust-token.cc
+++ b/gcc/rust/lex/rust-token.cc
@@ -152,6 +152,9 @@ Token::get_type_hint_str () const
const std::string &
Token::get_str () const
{
+ if (token_id_is_keyword (token_id))
+ return token_id_keyword_string (token_id);
+
// FIXME: attempt to return null again
// gcc_assert(str != NULL);
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index cf1fd9f..dbb322b 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -2146,10 +2146,10 @@ Parser<ManagedTokenSource>::parse_macro_match_fragment ()
Identifier ident = "";
auto identifier = lexer.peek_token ();
- if (identifier->has_str ())
- ident = identifier->get_str ();
+ if (identifier->get_id () == UNDERSCORE)
+ ident = "_";
else
- ident = std::string (token_id_to_str (identifier->get_id ()));
+ ident = identifier->get_str ();
if (ident.empty ())
{
diff --git a/gcc/testsuite/rust/compile/macro-issue2194.rs b/gcc/testsuite/rust/compile/macro-issue2194.rs
new file mode 100644
index 0000000..c94b114
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro-issue2194.rs
@@ -0,0 +1,7 @@
+macro_rules! foo {($type:ident) => {
+ let $type = 12;
+}}
+
+pub fn foo() {
+ foo!(_a);
+}