aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r--gcc/cp/parser.c70
1 files changed, 39 insertions, 31 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 49d951c..93335c8 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -12040,6 +12040,7 @@ cp_parser_handle_directive_omp_attributes (cp_parser *parser, tree *pattrs,
init-statement:
expression-statement
simple-declaration
+ alias-declaration
TM Extension:
@@ -13327,6 +13328,23 @@ cp_parser_for (cp_parser *parser, bool ivdep, unsigned short unroll)
/* Begin the for-statement. */
scope = begin_for_scope (&init);
+ /* Maybe parse the optional init-statement in a range-based for loop. */
+ if (cp_parser_range_based_for_with_init_p (parser)
+ /* Checked for diagnostic purposes only. */
+ && cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
+ {
+ tree dummy;
+ cp_parser_init_statement (parser, &dummy);
+ if (cxx_dialect < cxx20)
+ {
+ pedwarn (cp_lexer_peek_token (parser->lexer)->location,
+ OPT_Wc__20_extensions,
+ "range-based %<for%> loops with initializer only "
+ "available with %<-std=c++20%> or %<-std=gnu++20%>");
+ decl = error_mark_node;
+ }
+ }
+
/* Parse the initialization. */
is_range_for = cp_parser_init_statement (parser, &decl);
@@ -13987,12 +14005,13 @@ cp_parser_iteration_statement (cp_parser* parser, bool *if_p, bool ivdep,
return statement;
}
-/* Parse a init-statement or the declarator of a range-based-for.
+/* Parse an init-statement or the declarator of a range-based-for.
Returns true if a range-based-for declaration is seen.
init-statement:
expression-statement
- simple-declaration */
+ simple-declaration
+ alias-declaration */
static bool
cp_parser_init_statement (cp_parser *parser, tree *decl)
@@ -14008,40 +14027,29 @@ cp_parser_init_statement (cp_parser *parser, tree *decl)
bool is_range_for = false;
bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
- /* Try to parse the init-statement. */
- if (cp_parser_range_based_for_with_init_p (parser))
- {
- tree dummy;
- cp_parser_parse_tentatively (parser);
- /* Parse the declaration. */
- cp_parser_simple_declaration (parser,
- /*function_definition_allowed_p=*/false,
- &dummy);
- cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
- if (!cp_parser_parse_definitely (parser))
- /* That didn't work, try to parse it as an expression-statement. */
- cp_parser_expression_statement (parser, NULL_TREE);
-
- if (cxx_dialect < cxx20)
- {
- pedwarn (cp_lexer_peek_token (parser->lexer)->location,
- OPT_Wc__20_extensions,
- "range-based %<for%> loops with initializer only "
- "available with %<-std=c++20%> or %<-std=gnu++20%>");
- *decl = error_mark_node;
- }
- }
-
/* A colon is used in range-based for. */
parser->colon_corrects_to_scope_p = false;
/* We're going to speculatively look for a declaration, falling back
to an expression, if necessary. */
cp_parser_parse_tentatively (parser);
- /* Parse the declaration. */
- cp_parser_simple_declaration (parser,
- /*function_definition_allowed_p=*/false,
- decl);
+ bool expect_semicolon_p = true;
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_USING))
+ {
+ cp_parser_alias_declaration (parser);
+ expect_semicolon_p = false;
+ if (cxx_dialect < cxx23
+ && !cp_parser_uncommitted_to_tentative_parse_p (parser))
+ pedwarn (cp_lexer_peek_token (parser->lexer)->location,
+ OPT_Wc__23_extensions,
+ "alias-declaration in init-statement only "
+ "available with %<-std=c++23%> or %<-std=gnu++23%>");
+ }
+ else
+ /* Parse the declaration. */
+ cp_parser_simple_declaration (parser,
+ /*function_definition_allowed_p=*/false,
+ decl);
parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
{
@@ -14054,7 +14062,7 @@ cp_parser_init_statement (cp_parser *parser, tree *decl)
"range-based %<for%> loops only available with "
"%<-std=c++11%> or %<-std=gnu++11%>");
}
- else
+ else if (expect_semicolon_p)
/* The ';' is not consumed yet because we told
cp_parser_simple_declaration not to. */
cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);