diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-03-06 20:50:55 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-06 20:50:55 +0000 |
commit | e2bccf43ed1bf33d5f454eab39a7a4a1f115b0bd (patch) | |
tree | 6e9e933267fd6c651c59607668e2fa08641b8b9d /gcc/rust/parse/rust-parse-impl.h | |
parent | d89c8ccf3237e66029125c0fe007297bb86eca74 (diff) | |
parent | 58d1721529e99c7c633615e7491b777a6198ed00 (diff) | |
download | gcc-e2bccf43ed1bf33d5f454eab39a7a4a1f115b0bd.zip gcc-e2bccf43ed1bf33d5f454eab39a7a4a1f115b0bd.tar.gz gcc-e2bccf43ed1bf33d5f454eab39a7a4a1f115b0bd.tar.bz2 |
Merge #985
985: Parse macro!(); as MacroInvocation with semicolon r=CohenArthur a=CohenArthur
When parsing a macro invocation as a statement, the parser would parse
an expression and then try parsing a semicolon. Since no actual
lookahead was done (which is a good thing), we couldn't convert a
`MacroInvocation` to a `MacroInvocationSemi` after the fact.
Since, unlike function calls, macro invocations can act differently
based on whether or not they are followed by a semicolon, we actually
need to differentiate between the two up until expansion.
This commits adds a new virtual method for ExprWithoutBlock when
converting to ExprStmtWithoutBlock so that classes inheriting
ExprWithoutBlock can specify a new behavior. In the case of our
MacroInvocation class, it simply means toggling a boolean: If we're
converting a macro from an expression to a statement, it must mean that
it should contain a semicolon.
Closes #941
Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
Diffstat (limited to 'gcc/rust/parse/rust-parse-impl.h')
-rw-r--r-- | gcc/rust/parse/rust-parse-impl.h | 61 |
1 files changed, 35 insertions, 26 deletions
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h index af8f625..8559c3b 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -1529,7 +1529,7 @@ Parser<ManagedTokenSource>::parse_macro_rules_def (AST::AttrVec outer_attrs) // Parses a semi-coloned (except for full block) macro invocation item. template <typename ManagedTokenSource> -std::unique_ptr<AST::MacroInvocationSemi> +std::unique_ptr<AST::MacroInvocation> Parser<ManagedTokenSource>::parse_macro_invocation_semi ( AST::AttrVec outer_attrs) { @@ -1618,10 +1618,10 @@ Parser<ManagedTokenSource>::parse_macro_invocation_semi ( { // as this is the end, allow recovery (probably) - may change - return std::unique_ptr<AST::MacroInvocationSemi> ( - new AST::MacroInvocationSemi (std::move (invoc_data), - std::move (outer_attrs), - macro_locus)); + return std::unique_ptr<AST::MacroInvocation> ( + new AST::MacroInvocation (std::move (invoc_data), + std::move (outer_attrs), macro_locus, + true)); } } @@ -1630,9 +1630,9 @@ Parser<ManagedTokenSource>::parse_macro_invocation_semi ( t->get_token_description (), lexer.peek_token ()->get_token_description ()); - return std::unique_ptr<AST::MacroInvocationSemi> ( - new AST::MacroInvocationSemi (std::move (invoc_data), - std::move (outer_attrs), macro_locus)); + return std::unique_ptr<AST::MacroInvocation> ( + new AST::MacroInvocation (std::move (invoc_data), + std::move (outer_attrs), macro_locus, true)); } else { @@ -7200,7 +7200,11 @@ Parser<ManagedTokenSource>::parse_expr_stmt_without_block ( // attempt to parse via parse_expr_without_block - seems to work std::unique_ptr<AST::ExprWithoutBlock> expr = nullptr; Location locus = lexer.peek_token ()->get_locus (); - expr = parse_expr_without_block (std::move (outer_attrs)); + + auto restrictions = ParseRestrictions (); + restrictions.expr_can_be_stmt = true; + + expr = parse_expr_without_block (std::move (outer_attrs), restrictions); if (expr == nullptr) { // expr is required, error @@ -7227,7 +7231,8 @@ Parser<ManagedTokenSource>::parse_expr_stmt_without_block ( * disambiguates). */ template <typename ManagedTokenSource> std::unique_ptr<AST::ExprWithoutBlock> -Parser<ManagedTokenSource>::parse_expr_without_block (AST::AttrVec outer_attrs) +Parser<ManagedTokenSource>::parse_expr_without_block ( + AST::AttrVec outer_attrs, ParseRestrictions restrictions) { /* Notes on types of expr without block: * - literal expr tokens that are literals @@ -7298,7 +7303,8 @@ Parser<ManagedTokenSource>::parse_expr_without_block (AST::AttrVec outer_attrs) /* HACK: piggyback on pratt parsed expr and abuse polymorphism to * essentially downcast */ - std::unique_ptr<AST::Expr> expr = parse_expr (std::move (outer_attrs)); + std::unique_ptr<AST::Expr> expr + = parse_expr (std::move (outer_attrs), restrictions); if (expr == nullptr) { @@ -11825,10 +11831,11 @@ Parser<ManagedTokenSource>::parse_path_based_stmt_or_expr ( { lexer.skip_token (); - std::unique_ptr<AST::MacroInvocationSemi> stmt ( - new AST::MacroInvocationSemi (std::move (invoc_data), - std::move (outer_attrs), - stmt_or_expr_loc)); + std::unique_ptr<AST::MacroInvocation> stmt ( + new AST::MacroInvocation (std::move (invoc_data), + std::move (outer_attrs), + stmt_or_expr_loc), + true); return ExprOrStmt (std::move (stmt)); } @@ -11836,7 +11843,8 @@ Parser<ManagedTokenSource>::parse_path_based_stmt_or_expr ( std::unique_ptr<AST::MacroInvocation> expr ( new AST::MacroInvocation (std::move (invoc_data), std::move (outer_attrs), - stmt_or_expr_loc)); + stmt_or_expr_loc), + false); return ExprOrStmt (std::move (expr)); } else @@ -12145,10 +12153,10 @@ Parser<ManagedTokenSource>::parse_macro_invocation_maybe_semi ( { lexer.skip_token (); - std::unique_ptr<AST::MacroInvocationSemi> stmt ( - new AST::MacroInvocationSemi (std::move (invoc_data), - std::move (outer_attrs), - macro_locus)); + std::unique_ptr<AST::MacroInvocation> stmt ( + new AST::MacroInvocation (std::move (invoc_data), + std::move (outer_attrs), macro_locus), + true); return ExprOrStmt (std::move (stmt)); } @@ -12430,7 +12438,8 @@ Parser<ManagedTokenSource>::null_denotation (const_TokenPtr tok, case EXCLAM: // macro return parse_macro_invocation_partial (std::move (path), - std::move (outer_attrs)); + std::move (outer_attrs), + restrictions); case LEFT_CURLY: { bool not_a_block = lexer.peek_token (1)->get_id () == IDENTIFIER @@ -14331,7 +14340,8 @@ Parser<ManagedTokenSource>::parse_function_call_expr ( template <typename ManagedTokenSource> std::unique_ptr<AST::MacroInvocation> Parser<ManagedTokenSource>::parse_macro_invocation_partial ( - AST::PathInExpression path, AST::AttrVec outer_attrs) + AST::PathInExpression path, AST::AttrVec outer_attrs, + ParseRestrictions restrictions) { // macro invocation if (!skip_token (EXCLAM)) @@ -14356,10 +14366,9 @@ Parser<ManagedTokenSource>::parse_macro_invocation_partial ( Location macro_locus = converted_path.get_locus (); - return std::unique_ptr<AST::MacroInvocation> ( - new AST::MacroInvocation (AST::MacroInvocData (std::move (converted_path), - std::move (tok_tree)), - std::move (outer_attrs), macro_locus)); + return std::unique_ptr<AST::MacroInvocation> (new AST::MacroInvocation ( + AST::MacroInvocData (std::move (converted_path), std::move (tok_tree)), + std::move (outer_attrs), macro_locus, restrictions.expr_can_be_stmt)); } /* Parses a struct expr struct with a path in expression already parsed (but not |