diff options
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r-- | gcc/cp/parser.c | 147 |
1 files changed, 105 insertions, 42 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 7a6a302..0bd5852 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -7898,11 +7898,62 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, return error_mark_node; } +/* Helper function for cp_parser_parenthesized_expression_list and + cp_parser_postfix_open_square_expression. Parse a single element + of parenthesized expression list. */ + +static cp_expr +cp_parser_parenthesized_expression_list_elt (cp_parser *parser, bool cast_p, + bool allow_expansion_p, + bool fold_expr_p, + bool *non_constant_p) +{ + cp_expr expr (NULL_TREE); + bool expr_non_constant_p; + + /* Parse the next assignment-expression. */ + if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) + { + /* A braced-init-list. */ + cp_lexer_set_source_position (parser->lexer); + maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS); + expr = cp_parser_braced_list (parser, &expr_non_constant_p); + if (non_constant_p && expr_non_constant_p) + *non_constant_p = true; + } + else if (non_constant_p) + { + expr = cp_parser_constant_expression (parser, + /*allow_non_constant_p=*/true, + &expr_non_constant_p); + if (expr_non_constant_p) + *non_constant_p = true; + } + else + expr = cp_parser_assignment_expression (parser, /*pidk=*/NULL, cast_p); + + if (fold_expr_p) + expr = instantiate_non_dependent_expr (expr); + + /* If we have an ellipsis, then this is an expression expansion. */ + if (allow_expansion_p + && cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS)) + { + /* Consume the `...'. */ + cp_lexer_consume_token (parser->lexer); + + /* Build the argument pack. */ + expr = make_pack_expansion (expr); + } + return expr; +} + /* A subroutine of cp_parser_postfix_expression that also gets hijacked by cp_parser_builtin_offsetof. We're looking for postfix-expression [ expression ] postfix-expression [ braced-init-list ] (C++11) + postfix-expression [ expression-list[opt] ] (C++23) FOR_OFFSETOF is set if we're being called in that context, which changes how we deal with integer constant expressions. */ @@ -7914,6 +7965,7 @@ cp_parser_postfix_open_square_expression (cp_parser *parser, bool decltype_p) { tree index = NULL_TREE; + releasing_vec expression_list = NULL; location_t loc = cp_lexer_peek_token (parser->lexer)->location; bool saved_greater_than_is_operator_p; @@ -7935,7 +7987,49 @@ cp_parser_postfix_open_square_expression (cp_parser *parser, index = cp_parser_constant_expression (parser); else { - if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) + if (cxx_dialect >= cxx23 + && cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_SQUARE)) + *&expression_list = make_tree_vector (); + else if (cxx_dialect >= cxx23) + { + while (true) + { + cp_expr expr + = cp_parser_parenthesized_expression_list_elt (parser, + /*cast_p=*/ + false, + /*allow_exp_p=*/ + true, + /*fold_expr_p=*/ + false, + /*non_cst_p=*/ + NULL); + + if (expr == error_mark_node) + index = error_mark_node; + else if (expression_list.get () == NULL + && !PACK_EXPANSION_P (expr.get_value ())) + index = expr.get_value (); + else + vec_safe_push (expression_list, expr.get_value ()); + + /* If the next token isn't a `,', then we are done. */ + if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA)) + break; + + if (expression_list.get () == NULL && index != error_mark_node) + { + *&expression_list = make_tree_vector_single (index); + index = NULL_TREE; + } + + /* Otherwise, consume the `,' and keep going. */ + cp_lexer_consume_token (parser->lexer); + } + if (expression_list.get () && index == error_mark_node) + expression_list.release (); + } + else if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) { bool expr_nonconst_p; cp_lexer_set_source_position (parser->lexer); @@ -7955,7 +8049,9 @@ cp_parser_postfix_open_square_expression (cp_parser *parser, /* Build the ARRAY_REF. */ postfix_expression = grok_array_decl (loc, postfix_expression, - index, decltype_p); + index, &expression_list, + tf_warning_or_error + | (decltype_p ? tf_decltype : 0)); /* When not doing offsetof, array references are not permitted in constant-expressions. */ @@ -8315,44 +8411,11 @@ cp_parser_parenthesized_expression_list (cp_parser* parser, } else { - bool expr_non_constant_p; - - /* Parse the next assignment-expression. */ - if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) - { - /* A braced-init-list. */ - cp_lexer_set_source_position (parser->lexer); - maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS); - expr = cp_parser_braced_list (parser, &expr_non_constant_p); - if (non_constant_p && expr_non_constant_p) - *non_constant_p = true; - } - else if (non_constant_p) - { - expr = (cp_parser_constant_expression - (parser, /*allow_non_constant_p=*/true, - &expr_non_constant_p)); - if (expr_non_constant_p) - *non_constant_p = true; - } - else - expr = cp_parser_assignment_expression (parser, /*pidk=*/NULL, - cast_p); - - if (fold_expr_p) - expr = instantiate_non_dependent_expr (expr); - - /* If we have an ellipsis, then this is an expression - expansion. */ - if (allow_expansion_p - && cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS)) - { - /* Consume the `...'. */ - cp_lexer_consume_token (parser->lexer); - - /* Build the argument pack. */ - expr = make_pack_expansion (expr); - } + expr + = cp_parser_parenthesized_expression_list_elt (parser, cast_p, + allow_expansion_p, + fold_expr_p, + non_constant_p); if (wrap_locations_p) expr.maybe_add_location_wrapper (); @@ -10625,8 +10688,8 @@ cp_parser_builtin_offsetof (cp_parser *parser) case CPP_DEREF: /* offsetof-member-designator "->" identifier */ - expr = grok_array_decl (token->location, expr, - integer_zero_node, false); + expr = grok_array_decl (token->location, expr, integer_zero_node, + NULL, tf_warning_or_error); /* FALLTHRU */ case CPP_DOT: |