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.c407
1 files changed, 122 insertions, 285 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index c6ecf69..281e163 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -6062,41 +6062,31 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
return error_mark_node;
}
-/* This function parses Cilk Plus array notations. The starting index is
- passed in INIT_INDEX and the array name is passed in ARRAY_VALUE. If the
- INIT_INDEX is NULL, then we have special case were the entire array is
- accessed (e.g. A[:]). The return value of this function is a tree node
- called VALUE_TREE of type ARRAY_NOTATION_REF. If some error occurred it
- returns error_mark_node. */
+/* This function parses Cilk Plus array notations. If a normal array expr. is
+ parsed then the array index is passed back to the caller through *INIT_INDEX
+ and the function returns a NULL_TREE. If array notation expr. is parsed,
+ then *INIT_INDEX is ignored by the caller and the function returns
+ a tree of type ARRAY_NOTATION_REF. If some error occurred it returns
+ error_mark_node. */
static tree
-cp_parser_array_notation (location_t loc, cp_parser *parser, tree init_index,
+cp_parser_array_notation (location_t loc, cp_parser *parser, tree *init_index,
tree array_value)
{
cp_token *token = NULL;
- tree start_index = NULL_TREE, length_index = NULL_TREE, stride = NULL_TREE;
- tree value_tree, type, array_type, array_type_domain;
- double_int x;
- bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
-
+ tree length_index, stride = NULL_TREE, value_tree, array_type;
if (!array_value || array_value == error_mark_node)
{
cp_parser_skip_to_end_of_statement (parser);
return error_mark_node;
}
+
+ array_type = TREE_TYPE (array_value);
- if (processing_template_decl)
- {
- array_type = TREE_TYPE (array_value);
- type = TREE_TYPE (array_type);
- }
- else
- {
- array_type = TREE_TYPE (array_value);
- gcc_assert (array_type);
- type = array_type;
- }
+ bool saved_colon_corrects = parser->colon_corrects_to_scope_p;
+ parser->colon_corrects_to_scope_p = false;
token = cp_lexer_peek_token (parser->lexer);
+
if (!token)
{
cp_parser_error (parser, "expected %<:%> or numeral");
@@ -6104,125 +6094,57 @@ cp_parser_array_notation (location_t loc, cp_parser *parser, tree init_index,
}
else if (token->type == CPP_COLON)
{
- if (!init_index)
+ /* Consume the ':'. */
+ cp_lexer_consume_token (parser->lexer);
+
+ /* If we are here, then we have a case like this A[:]. */
+ if (cp_lexer_peek_token (parser->lexer)->type != CPP_CLOSE_SQUARE)
{
- /* If we are here, then we have a case like this A[:]. */
- cp_lexer_consume_token (parser->lexer);
-
- if (cp_lexer_peek_token (parser->lexer)->type != CPP_CLOSE_SQUARE)
- {
- cp_parser_error (parser, "expected %<]%>");
- cp_parser_skip_to_end_of_statement (parser);
- return error_mark_node;
- }
- if (TREE_CODE (array_type) == RECORD_TYPE
- || TREE_CODE (array_type) == POINTER_TYPE)
- {
- error_at (loc, "start-index and length fields necessary for "
- "using array notations in pointers or records");
- cp_parser_skip_to_end_of_statement (parser);
- return error_mark_node;
- }
- if (TREE_CODE (array_type) == ARRAY_TYPE)
- {
- tree subtype = TREE_TYPE (array_type);
- while (subtype && TREE_CODE (subtype) == POINTER_TYPE)
- {
- /* This could be a function ptr. If so, then emit error. */
- subtype = TREE_TYPE (subtype);
- if (subtype && TREE_CODE (subtype) == FUNCTION_TYPE)
- {
- error_at (loc, "array notations cannot be used with"
- " function pointer arrays");
- cp_parser_skip_to_end_of_statement (parser);
- return error_mark_node;
- }
- }
- }
- array_type_domain = TYPE_DOMAIN (array_type);
- if (!array_type_domain)
- {
- error_at (loc, "start-index and length fields necessary for "
- "using array notations in dimensionless arrays");
- cp_parser_skip_to_end_of_statement (parser);
- return error_mark_node;
- }
- start_index = TYPE_MINVAL (array_type_domain);
- start_index = fold_build1 (CONVERT_EXPR, ptrdiff_type_node,
- start_index);
- x = TREE_INT_CST (TYPE_MAXVAL (array_type_domain));
- x.low++;
- length_index = double_int_to_tree (integer_type_node, x);
- length_index = fold_build1 (CONVERT_EXPR, ptrdiff_type_node,
- length_index);
- stride = build_int_cst (integer_type_node, 1);
- stride = fold_build1 (CONVERT_EXPR, ptrdiff_type_node, stride);
- }
- else if (init_index != error_mark_node)
- {
- /* If we hare here, then there are 2 possibilities:
- 1. Array [ EXPR : EXPR ]
- 2. Array [ EXPR : EXPR : EXPR ]
- */
- start_index = init_index;
- cp_lexer_consume_token (parser->lexer);
+ cp_parser_error (parser, "expected %<]%>");
+ cp_parser_skip_to_end_of_statement (parser);
+ return error_mark_node;
+ }
+ *init_index = NULL_TREE;
+ stride = NULL_TREE;
+ length_index = NULL_TREE;
+ }
+ else
+ {
+ /* If we are here, then there are three valid possibilities:
+ 1. ARRAY [ EXP ]
+ 2. ARRAY [ EXP : EXP ]
+ 3. ARRAY [ EXP : EXP : EXP ] */
- saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
- /* The ':' is used in array notation. Thus compiler cannot do scope
- correction automatically. */
- parser->colon_corrects_to_scope_p = false;
- length_index = cp_parser_expression (parser, false, NULL);
- parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
- if (!length_index || length_index == error_mark_node)
- cp_parser_skip_to_end_of_statement (parser);
-
- if (cp_lexer_peek_token (parser->lexer)->type == CPP_COLON)
- {
- cp_lexer_consume_token (parser->lexer);
- saved_colon_corrects_to_scope_p =
- parser->colon_corrects_to_scope_p;
- /* Disable correcting single colon correcting to scope. */
- parser->colon_corrects_to_scope_p = false;
- stride = cp_parser_expression (parser, false, NULL);
- parser->colon_corrects_to_scope_p =
- saved_colon_corrects_to_scope_p;
- if (!stride || stride == error_mark_node)
- {
- cp_parser_skip_to_end_of_statement (parser);
- if (cp_lexer_peek_token (parser->lexer)->type
- == CPP_CLOSE_SQUARE)
- cp_lexer_consume_token (parser->lexer);
- }
- }
- else
- stride = build_one_cst (integer_type_node);
+ *init_index = cp_parser_expression (parser, false, NULL);
+ if (cp_lexer_peek_token (parser->lexer)->type != CPP_COLON)
+ {
+ /* This indicates that we have a normal array expression. */
+ parser->colon_corrects_to_scope_p = saved_colon_corrects;
+ return NULL_TREE;
}
- else
+
+ /* Consume the ':'. */
+ cp_lexer_consume_token (parser->lexer);
+ length_index = cp_parser_expression (parser, false, NULL);
+ if (cp_lexer_peek_token (parser->lexer)->type == CPP_COLON)
{
- cp_parser_skip_to_end_of_statement (parser);
- return error_mark_node;
+ cp_lexer_consume_token (parser->lexer);
+ stride = cp_parser_expression (parser, false, NULL);
}
}
-
- if (start_index == error_mark_node || length_index == error_mark_node
- || stride == error_mark_node || !start_index || !length_index
- || !stride)
+ parser->colon_corrects_to_scope_p = saved_colon_corrects;
+
+ if (*init_index == error_mark_node || length_index == error_mark_node
+ || stride == error_mark_node)
{
if (cp_lexer_peek_token (parser->lexer)->type == CPP_CLOSE_SQUARE)
cp_lexer_consume_token (parser->lexer);
return error_mark_node;
}
cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
-
- /* We fold all 3 of the values to make things easier when we transform
- them later. */
- start_index = fold (start_index);
- length_index = fold (length_index);
- stride = fold (stride);
-
- value_tree = build_array_notation_ref (input_location, array_value,
- start_index, length_index, stride,
- type);
+
+ value_tree = build_array_notation_ref (loc, array_value, *init_index,
+ length_index, stride, array_type);
return value_tree;
}
@@ -6241,84 +6163,68 @@ cp_parser_postfix_open_square_expression (cp_parser *parser,
bool for_offsetof,
bool decltype_p)
{
- tree index;
+ tree index = NULL_TREE;
location_t loc = cp_lexer_peek_token (parser->lexer)->location;
/* Consume the `[' token. */
cp_lexer_consume_token (parser->lexer);
- if (flag_enable_cilkplus
- && cp_lexer_peek_token (parser->lexer)->type == CPP_COLON)
- /* If we are here, then we have something like this:
- ARRAY[:]
- */
- postfix_expression = cp_parser_array_notation (loc, parser, NULL_TREE,
- postfix_expression);
+ /* Parse the index expression. */
+ /* ??? For offsetof, there is a question of what to allow here. If
+ offsetof is not being used in an integral constant expression context,
+ then we *could* get the right answer by computing the value at runtime.
+ If we are in an integral constant expression context, then we might
+ could accept any constant expression; hard to say without analysis.
+ Rather than open the barn door too wide right away, allow only integer
+ constant expressions here. */
+ if (for_offsetof)
+ index = cp_parser_constant_expression (parser, false, NULL);
else
{
- /* Here are have these options:
- 1. ARRAY[EXPR] -- This is the normal array call.
- 2. ARRAY[EXPR : EXPR] -- Array notation expr with default stride
- of 1.
- 3. ARRAY[EXPR : EXPR : EXPR] -- Array Notation with userdefined stride.
- 4. Array[Braced List] -- This is handled by braced list.
- */
-
- /* Parse the index expression. */
- /* ??? For offsetof, there is a question of what to allow here. If
- offsetof is not being used in an integral constant expression context,
- then we *could* get the right answer by computing the value at runtime.
- If we are in an integral constant expression context, then we might
- could accept any constant expression; hard to say without analysis.
- Rather than open the barn door too wide right away, allow only integer
- constant expressions here. */
- if (for_offsetof)
- index = cp_parser_constant_expression (parser, false, NULL);
- else
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
{
- bool saved_colon_corrects_to_scope_p =
- parser->colon_corrects_to_scope_p;
- if (flag_enable_cilkplus)
- parser->colon_corrects_to_scope_p = false;
- if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ bool expr_nonconst_p;
+ maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
+ index = cp_parser_braced_list (parser, &expr_nonconst_p);
+ if (flag_enable_cilkplus
+ && cp_lexer_peek_token (parser->lexer)->type == CPP_COLON)
{
- bool expr_nonconst_p;
- maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
- index = cp_parser_braced_list (parser, &expr_nonconst_p);
- if (flag_enable_cilkplus
- && cp_lexer_peek_token (parser->lexer)->type == CPP_COLON)
- {
- error_at (cp_lexer_peek_token (parser->lexer)->location,
- "braced list index is not allowed with array "
- "notations");
- index = error_mark_node;
- }
+ error_at (cp_lexer_peek_token (parser->lexer)->location,
+ "braced list index is not allowed with array "
+ "notation");
+ cp_parser_skip_to_end_of_statement (parser);
+ return error_mark_node;
}
- else
- index = cp_parser_expression (parser, /*cast_p=*/false, NULL);
- parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
}
- if (flag_enable_cilkplus
- && cp_lexer_peek_token (parser->lexer)->type == CPP_COLON)
- postfix_expression = cp_parser_array_notation (loc, parser, index,
- postfix_expression);
- else
+ else if (flag_enable_cilkplus)
{
- /* Look for the closing `]'. */
- cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
-
- /* Build the ARRAY_REF. */
- postfix_expression = grok_array_decl (loc, postfix_expression,
- index, decltype_p);
-
- /* When not doing offsetof, array references are not permitted in
- constant-expressions. */
- if (!for_offsetof
- && (cp_parser_non_integral_constant_expression (parser,
- NIC_ARRAY_REF)))
- postfix_expression = error_mark_node;
+ /* Here are have these two options:
+ ARRAY[EXP : EXP] - Array notation expr with default
+ stride of 1.
+ ARRAY[EXP : EXP : EXP] - Array Notation with user-defined
+ stride. */
+ tree an_exp = cp_parser_array_notation (loc, parser, &index,
+ postfix_expression);
+ if (an_exp)
+ return an_exp;
}
+ else
+ index = cp_parser_expression (parser, /*cast_p=*/false, NULL);
}
+
+ /* Look for the closing `]'. */
+ cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
+
+ /* Build the ARRAY_REF. */
+ postfix_expression = grok_array_decl (loc, postfix_expression,
+ index, decltype_p);
+
+ /* When not doing offsetof, array references are not permitted in
+ constant-expressions. */
+ if (!for_offsetof
+ && (cp_parser_non_integral_constant_expression (parser, NIC_ARRAY_REF)))
+ postfix_expression = error_mark_node;
+
return postfix_expression;
}
@@ -9553,8 +9459,6 @@ cp_parser_compound_statement (cp_parser *parser, tree in_statement_expr,
/* Consume the `}'. */
cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
- if (flag_enable_cilkplus && contains_array_notation_expr (compound_stmt))
- compound_stmt = expand_array_notation_exprs (compound_stmt);
return compound_stmt;
}
@@ -9747,14 +9651,6 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p)
/* Now we're all done with the switch-statement. */
finish_switch_stmt (statement);
- if (flag_enable_cilkplus
- && contains_array_notation_expr (condition))
- {
- error_at (EXPR_LOCATION (condition),
- "array notations cannot be used as a condition for "
- "switch statement");
- statement = error_mark_node;
- }
}
return statement;
@@ -10312,12 +10208,6 @@ cp_parser_iteration_statement (cp_parser* parser)
parser->in_statement = in_statement;
/* We're done with the while-statement. */
finish_while_stmt (statement);
- if (flag_enable_cilkplus && contains_array_notation_expr (condition))
- {
- error_at (EXPR_LOCATION (condition), "array notations cannot be "
- "used as a condition for while statement");
- statement = error_mark_node;
- }
}
break;
@@ -10344,15 +10234,6 @@ cp_parser_iteration_statement (cp_parser* parser)
cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
/* Look for the `;'. */
cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
- if (flag_enable_cilkplus
- && contains_array_notation_expr (DO_COND (statement)))
- {
- error_at (EXPR_LOCATION (DO_COND (statement)),
- "array notations cannot be used as a condition for a "
- "do-while statement");
- statement = error_mark_node;
- }
-
}
break;
@@ -10371,17 +10252,8 @@ cp_parser_iteration_statement (cp_parser* parser)
cp_parser_already_scoped_statement (parser);
parser->in_statement = in_statement;
- if (flag_enable_cilkplus
- && contains_array_notation_expr (FOR_COND (statement)))
- {
- error_at (EXPR_LOCATION (FOR_COND (statement)),
- "array notations cannot be used in a condition for a "
- "for-loop");
- statement = error_mark_node;
- }
- else
- /* We're done with the for-statement. */
- finish_for_stmt (statement);
+ /* We're done with the for-statement. */
+ finish_for_stmt (statement);
}
break;
@@ -16954,54 +16826,30 @@ cp_parser_direct_declarator (cp_parser* parser,
if (token->type != CPP_CLOSE_SQUARE)
{
bool non_constant_p;
-
- if (flag_enable_cilkplus
- && cp_lexer_next_token_is (parser->lexer, CPP_COLON))
+ bounds
+ = cp_parser_constant_expression (parser,
+ /*allow_non_constant=*/true,
+ &non_constant_p);
+ if (!non_constant_p)
+ /* OK */;
+ else if (error_operand_p (bounds))
+ /* Already gave an error. */;
+ else if (!parser->in_function_body
+ || current_binding_level->kind == sk_function_parms)
{
+ /* Normally, the array bound must be an integral constant
+ expression. However, as an extension, we allow VLAs
+ in function scopes as long as they aren't part of a
+ parameter declaration. */
+ cp_parser_error (parser,
+ "array bound is not an integer constant");
bounds = error_mark_node;
- error_at (cp_lexer_peek_token (parser->lexer)->location,
- "array notations cannot be used in declaration");
- cp_lexer_consume_token (parser->lexer);
}
- else
+ else if (processing_template_decl)
{
- bounds
- = cp_parser_constant_expression (parser,
- /*allow_non_constant=*/true,
- &non_constant_p);
- if (!non_constant_p)
- /* OK */;
- else if (error_operand_p (bounds))
- /* Already gave an error. */;
- else if (!parser->in_function_body
- || current_binding_level->kind == sk_function_parms)
- {
- /* Normally, the array bound must be an integral constant
- expression. However, as an extension, we allow VLAs
- in function scopes as long as they aren't part of a
- parameter declaration. */
- cp_parser_error (parser,
- "array bound is not an integer constant");
- bounds = error_mark_node;
- }
- else if (processing_template_decl)
- {
- /* Remember this wasn't a constant-expression. */
- bounds = build_nop (TREE_TYPE (bounds), bounds);
- TREE_SIDE_EFFECTS (bounds) = 1;
- }
- if (flag_enable_cilkplus
- && cp_lexer_next_token_is (parser->lexer, CPP_COLON))
- {
- location_t loc =
- cp_lexer_peek_token (parser->lexer)->location;
- while (cp_lexer_next_token_is_not (parser->lexer,
- CPP_CLOSE_SQUARE))
- cp_lexer_consume_token (parser->lexer);
- error_at (loc, "array notations cannot be used in "
- "declaration");
- bounds = error_mark_node;
- }
+ /* Remember this wasn't a constant-expression. */
+ bounds = build_nop (TREE_TYPE (bounds), bounds);
+ TREE_SIDE_EFFECTS (bounds) = 1;
}
}
else
@@ -18372,11 +18220,6 @@ cp_parser_ctor_initializer_opt_and_function_body (cp_parser *parser,
cp_parser_function_body (parser, in_function_try_block);
if (check_body_p)
check_constexpr_ctor_body (last, list);
-
- /* Transform all array notations to the equivalent array refs and loop. */
- if (flag_enable_cilkplus && contains_array_notation_expr (body))
- body = expand_array_notation_exprs (body);
-
/* Finish the function body. */
finish_function_body (body);
@@ -22356,12 +22199,6 @@ cp_parser_function_definition_after_declarator (cp_parser* parser,
finish_lambda_scope ();
- /* Expand all array notation expressions here. */
- if (flag_enable_cilkplus && current_function_decl
- && contains_array_notation_expr (DECL_SAVED_TREE (current_function_decl)))
- DECL_SAVED_TREE (current_function_decl) =
- expand_array_notation_exprs (DECL_SAVED_TREE (current_function_decl));
-
/* Finish the function. */
fn = finish_function ((ctor_initializer_p ? 1 : 0) |
(inline_p ? 2 : 0));