(enum tree_code, tree, cp_cv_quals, cp_declarator *, tree);
static bool cp_parser_compound_literal_p
(cp_parser *);
+static bool cp_parser_array_designator_p
+ (cp_parser *);
+static bool cp_parser_skip_to_closing_square_bracket
+ (cp_parser *);
/* Returns nonzero if we are parsing tentatively. */
return initializer;
}
+/* Consume tokens up to, and including, the next non-nested closing `]'.
+ Returns true iff we found a closing `]'. */
+
+static bool
+cp_parser_skip_to_closing_square_bracket (cp_parser *parser)
+{
+ unsigned square_depth = 0;
+
+ while (true)
+ {
+ cp_token * token = cp_lexer_peek_token (parser->lexer);
+
+ switch (token->type)
+ {
+ case CPP_EOF:
+ case CPP_PRAGMA_EOL:
+ /* If we've run out of tokens, then there is no closing `]'. */
+ return false;
+
+ case CPP_OPEN_SQUARE:
+ ++square_depth;
+ break;
+
+ case CPP_CLOSE_SQUARE:
+ if (!square_depth--)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ return true;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Consume the token. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+}
+
+/* Return true if we are looking at an array-designator, false otherwise. */
+
+static bool
+cp_parser_array_designator_p (cp_parser *parser)
+{
+ /* Consume the `['. */
+ cp_lexer_consume_token (parser->lexer);
+
+ cp_lexer_save_tokens (parser->lexer);
+
+ /* Skip tokens until the next token is a closing square bracket.
+ If we find the closing `]', and the next token is a `=', then
+ we are looking at an array designator. */
+ bool array_designator_p
+ = (cp_parser_skip_to_closing_square_bracket (parser)
+ && cp_lexer_next_token_is (parser->lexer, CPP_EQ));
+
+ /* Roll back the tokens we skipped. */
+ cp_lexer_rollback_tokens (parser->lexer);
+
+ return array_designator_p;
+}
+
/* Parse an initializer-list.
initializer-list:
bool non_const = false;
cp_parser_parse_tentatively (parser);
- cp_lexer_consume_token (parser->lexer);
- designator = cp_parser_constant_expression (parser, true, &non_const);
- cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
- cp_parser_require (parser, CPP_EQ, RT_EQ);
+
+ if (!cp_parser_array_designator_p (parser))
+ {
+ cp_parser_simulate_error (parser);
+ designator = NULL_TREE;
+ }
+ else
+ {
+ designator = cp_parser_constant_expression (parser, true,
+ &non_const);
+ cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
+ cp_parser_require (parser, CPP_EQ, RT_EQ);
+ }
+
if (!cp_parser_parse_definitely (parser))
designator = NULL_TREE;
else if (non_const)