aboutsummaryrefslogtreecommitdiff
path: root/gcc/c/c-parser.c
diff options
context:
space:
mode:
authorBalaji V. Iyer <balaji.v.iyer@intel.com>2013-05-28 19:55:10 +0000
committerBalaji V. Iyer <bviyer@gcc.gnu.org>2013-05-28 12:55:10 -0700
commit36536d79af79b5a252356e79e62b851f3f2bedf9 (patch)
tree7bd32114bcd1a25d4a1caa95b66d2894e6e75dc7 /gcc/c/c-parser.c
parent6d2bee95d82dcf40d115a3ba3a793a9b71a17a64 (diff)
downloadgcc-36536d79af79b5a252356e79e62b851f3f2bedf9.zip
gcc-36536d79af79b5a252356e79e62b851f3f2bedf9.tar.gz
gcc-36536d79af79b5a252356e79e62b851f3f2bedf9.tar.bz2
Implemented Cilk Plus Array Notation for C Compiler.
gcc/ChangeLog 2013-05-28 Balaji V. Iyer <balaji.v.iyer@intel.com> * doc/extend.texi (C Extensions): Added documentation about Cilk Plus array notation built-in reduction functions. * doc/passes.texi (Passes): Added documentation about changes done for Cilk Plus. * doc/invoke.texi (C Dialect Options): Added documentation about the -fcilkplus flag. * Makefile.in (C_COMMON_OBJS): Added c-family/array-notation-common.o. (BUILTINS_DEF): Depend on cilkplus.def. * builtins.def: Include cilkplus.def. Define DEF_CILKPLUS_BUILTIN. * builtin-types.def: Define BT_FN_INT_PTR_PTR_PTR. * cilkplus.def: New file. gcc/c-family/ChangeLog 2013-05-28 Balaji V. Iyer <balaji.v.iyer@intel.com> * c-common.c (c_define_builtins): When cilkplus is enabled, the function array_notation_init_builtins is called. (c_common_init_ts): Added ARRAY_NOTATION_REF as typed. * c-common.def (ARRAY_NOTATION_REF): New tree. * c-common.h (build_array_notation_expr): New function declaration. (build_array_notation_ref): Likewise. (extract_sec_implicit_index_arg): New extern declaration. (is_sec_implicit_index_fn): Likewise. (ARRAY_NOTATION_CHECK): New define. (ARRAY_NOTATION_ARRAY): Likewise. (ARRAY_NOTATION_START): Likewise. (ARRAY_NOTATION_LENGTH): Likewise. (ARRAY_NOTATION_STRIDE): Likewise. * c-pretty-print.c (pp_c_postifix_expression): Added a new case for ARRAY_NOTATION_REF. (pp_c_expression): Likewise. * c.opt (flag_enable_cilkplus): New flag. * array-notation-common.c: New file. gcc/c/ChangeLog 2013-05-28 Balaji V. Iyer <balaji.v.iyer@intel.com> * c-typeck.c (build_array_ref): Added a check to see if array's index is greater than one. If true, then emit an error. (build_function_call_vec): Exclude error reporting and checking for builtin array-notation functions. (convert_arguments): Likewise. (c_finish_return): Added a check for array notations as a return expression. If true, then emit an error. (c_finish_loop): Added a check for array notations in a loop condition. If true then emit an error. (lvalue_p): Added a ARRAY_NOTATION_REF case. (build_binary_op): Added a check for array notation expr inside op1 and op0. If present, we call another function to find correct type. * Make-lang.in (C_AND_OBJC_OBJS): Added c-array-notation.o. * c-parser.c (c_parser_compound_statement): Check if array notation code is used in tree, if so, then transform them into appropriate C code. (c_parser_expr_no_commas): Check if array notation is used in LHS or RHS, if so, then build array notation expression instead of regular modify. (c_parser_postfix_expression_after_primary): Added a check for colon(s) after square braces, if so then handle it like an array notation. Also, break up array notations in unary op if found. (c_parser_direct_declarator_inner): Added a check for array notation. (c_parser_compound_statement): Added a check for array notation in a stmt. If one is present, then expand array notation expr. (c_parser_if_statement): Likewise. (c_parser_switch_statement): Added a check for array notations in a switch statement's condition. If true, then output an error. (c_parser_while_statement): Similarly, but for a while. (c_parser_do_statement): Similarly, but for a do-while. (c_parser_for_statement): Similarly, but for a for-loop. (c_parser_unary_expression): Check if array notation is used in a pre-increment or pre-decrement expression. If true, then expand them. (c_parser_array_notation): New function. * c-array-notation.c: New file. * c-tree.h (is_cilkplus_reduce_builtin): Protoize. gcc/testsuite/ChangeLog 2013-05-28 Balaji V. Iyer <balaji.v.iyer@intel.com> * c-c++-common/cilk-plus/AN/array_test1.c: New test. * c-c++-common/cilk-plus/AN/array_test2.c: Likewise. * c-c++-common/cilk-plus/AN/array_test_ND.c: Likewise. * c-c++-common/cilk-plus/AN/builtin_func_double.c: Likewise. * c-c++-common/cilk-plus/AN/builtin_func_double2.c: Likewise. * c-c++-common/cilk-plus/AN/gather-scatter-errors.c: Likewise. * c-c++-common/cilk-plus/AN/if_test.c: Likewise. * c-c++-common/cilk-plus/AN/sec_implicit_ex.c: Likewise. * c-c++-common/cilk-plus/AN/decl-ptr-colon.c: Likewise. * c-c++-common/cilk-plus/AN/dimensionless-arrays.c: Likewise. * c-c++-common/cilk-plus/AN/fn_ptr.c: Likewise. * c-c++-common/cilk-plus/AN/fp_triplet_values.c: Likewise. * c-c++-common/cilk-plus/AN/gather-scatter.c: Likewise. * c-c++-common/cilk-plus/AN/misc.c: Likewise. * c-c++-common/cilk-plus/AN/parser_errors.c: Likewise. * c-c++-common/cilk-plus/AN/parser_errors2.c: Likewise. * c-c++-common/cilk-plus/AN/parser_errors3.c: Likewise. * c-c++-common/cilk-plus/AN/parser_errors4.c: Likewise. * c-c++-common/cilk-plus/AN/rank_mismatch.c: Likewise. * c-c++-common/cilk-plus/AN/rank_mismatch2.c: Likewise. * c-c++-common/cilk-plus/AN/rank_mismatch3.c: Likewise. * c-c++-common/cilk-plus/AN/sec_implicit.c: Likewise. * c-c++-common/cilk-plus/AN/sec_implicit2.c: Likewise. * c-c++-common/cilk-plus/AN/sec_reduce_max_min_ind.c: Likewise. * c-c++-common/cilk-plus/AN/tst_lngth.c: Likewise. * c-c++-common/cilk-plus/AN/vla.c: Likewise. * c-c++-common/cilk-plus/AN/an-if.c: Likewise. * c-c++-common/cilk-plus/AN/builtin_fn_custom.c: Likewise. * c-c++-common/cilk-plus/AN/builtin_fn_mutating.c: Likewise. * c-c++-common/cilk-plus/AN/comma_exp.c: Likewise. * c-c++-common/cilk-plus/AN/conditional.c: Likewise. * c-c++-common/cilk-plus/AN/exec-once.c: Likewise. * c-c++-common/cilk-plus/AN/exec-once2.c: Likewise. * c-c++-common/cilk-plus/AN/gather_scatter.c: Likewise. * c-c++-common/cilk-plus/AN/n-ptr-test.c: Likewise. * c-c++-common/cilk-plus/AN/side-effects-1.c: Likewise. * c-c++-common/cilk-plus/AN/test_builtin_return.c: Likewise. * c-c++-common/cilk-plus/AN/test_sec_limits.c: Likewise. * gcc.dg/cilk-plus/cilk-plus.exp: New script. From-SVN: r199389
Diffstat (limited to 'gcc/c/c-parser.c')
-rw-r--r--gcc/c/c-parser.c327
1 files changed, 308 insertions, 19 deletions
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index f60f141..b89d8c1 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -1216,6 +1216,8 @@ static void c_parser_objc_at_dynamic_declaration (c_parser *);
static bool c_parser_objc_diagnose_bad_element_prefix
(c_parser *, struct c_declspecs *);
+static tree c_parser_array_notation (location_t, c_parser *, tree, tree);
+
/* Parse a translation unit (C90 6.7, C99 6.9).
translation-unit:
@@ -3067,6 +3069,15 @@ c_parser_direct_declarator_inner (c_parser *parser, bool id_present,
dimen = NULL_TREE;
star_seen = false;
}
+ else if (flag_enable_cilkplus
+ && c_parser_next_token_is (parser, CPP_COLON))
+ {
+ dimen = error_mark_node;
+ star_seen = false;
+ error_at (c_parser_peek_token (parser)->location,
+ "array notations cannot be used in declaration");
+ c_parser_consume_token (parser);
+ }
else if (c_parser_next_token_is (parser, CPP_MULT))
{
if (c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_SQUARE)
@@ -3089,6 +3100,14 @@ c_parser_direct_declarator_inner (c_parser *parser, bool id_present,
}
if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
c_parser_consume_token (parser);
+ else if (flag_enable_cilkplus
+ && c_parser_next_token_is (parser, CPP_COLON))
+ {
+ error_at (c_parser_peek_token (parser)->location,
+ "array notations cannot be used in declaration");
+ c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
+ return NULL;
+ }
else
{
c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
@@ -4071,6 +4090,10 @@ c_parser_compound_statement (c_parser *parser)
}
stmt = c_begin_compound_stmt (true);
c_parser_compound_statement_nostart (parser);
+
+ /* If the compound stmt contains array notations, then we expand them. */
+ if (flag_enable_cilkplus && contains_array_notation_expr (stmt))
+ stmt = expand_array_notation_exprs (stmt);
return c_end_compound_stmt (brace_loc, stmt, true);
}
@@ -4714,6 +4737,7 @@ c_parser_if_statement (c_parser *parser)
bool first_if = false;
tree first_body, second_body;
bool in_if_block;
+ tree if_stmt;
gcc_assert (c_parser_next_token_is_keyword (parser, RID_IF));
c_parser_consume_token (parser);
@@ -4732,7 +4756,12 @@ c_parser_if_statement (c_parser *parser)
else
second_body = NULL_TREE;
c_finish_if_stmt (loc, cond, first_body, second_body, first_if);
- add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
+ if_stmt = c_end_compound_stmt (loc, block, flag_isoc99);
+
+ /* If the if statement contains array notations, then we expand them. */
+ if (flag_enable_cilkplus && contains_array_notation_expr (if_stmt))
+ if_stmt = fix_conditional_array_notations (if_stmt);
+ add_stmt (if_stmt);
}
/* Parse a switch statement (C90 6.6.4, C99 6.8.4).
@@ -4754,6 +4783,13 @@ c_parser_switch_statement (c_parser *parser)
{
switch_cond_loc = c_parser_peek_token (parser)->location;
expr = c_parser_expression (parser).value;
+ if (flag_enable_cilkplus && contains_array_notation_expr (expr))
+ {
+ error_at (switch_cond_loc,
+ "array notations cannot be used as a condition for switch "
+ "statement");
+ expr = error_mark_node;
+ }
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
}
else
@@ -4793,6 +4829,12 @@ c_parser_while_statement (c_parser *parser)
block = c_begin_compound_stmt (flag_isoc99);
loc = c_parser_peek_token (parser)->location;
cond = c_parser_paren_condition (parser);
+ if (flag_enable_cilkplus && contains_array_notation_expr (cond))
+ {
+ error_at (loc, "array notations cannot be used as a condition for while "
+ "statement");
+ cond = error_mark_node;
+ }
save_break = c_break_label;
c_break_label = NULL_TREE;
save_cont = c_cont_label;
@@ -4834,6 +4876,13 @@ c_parser_do_statement (c_parser *parser)
new_cont = c_cont_label;
c_cont_label = save_cont;
cond = c_parser_paren_condition (parser);
+ if (flag_enable_cilkplus && contains_array_notation_expr (cond))
+ {
+ error_at (loc, "array notations cannot be used as a condition for a "
+ "do-while statement");
+ cond = error_mark_node;
+ }
+
if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
c_parser_skip_to_end_of_block_or_statement (parser);
c_finish_loop (loc, cond, NULL, body, new_break, new_cont, false);
@@ -5009,7 +5058,14 @@ c_parser_for_statement (c_parser *parser)
else
{
cond = c_parser_condition (parser);
- c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
+ if (flag_enable_cilkplus && contains_array_notation_expr (cond))
+ {
+ error_at (loc, "array notations cannot be used in a "
+ "condition for a for-loop");
+ cond = error_mark_node;
+ }
+ c_parser_skip_until_found (parser, CPP_SEMICOLON,
+ "expected %<;%>");
}
}
/* Parse the increment expression (the third expression in a
@@ -5388,9 +5444,21 @@ c_parser_expr_no_commas (c_parser *parser, struct c_expr *after)
exp_location = c_parser_peek_token (parser)->location;
rhs = c_parser_expr_no_commas (parser, NULL);
rhs = default_function_array_read_conversion (exp_location, rhs);
- ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
- code, exp_location, rhs.value,
- rhs.original_type);
+
+ /* The line below is where the statement has the form:
+ A = B, where A and B contain array notation exprs. So this is where
+ we handle those. */
+ if (flag_enable_cilkplus
+ && (contains_array_notation_expr (lhs.value)
+ || contains_array_notation_expr (rhs.value)))
+ ret.value = build_array_notation_expr (op_location, lhs.value,
+ lhs.original_type, code,
+ exp_location, rhs.value,
+ rhs.original_type);
+ else
+ ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
+ code, exp_location, rhs.value,
+ rhs.original_type);
if (code == NOP_EXPR)
ret.original_code = MODIFY_EXPR;
else
@@ -5870,14 +5938,28 @@ c_parser_unary_expression (c_parser *parser)
c_parser_consume_token (parser);
exp_loc = c_parser_peek_token (parser)->location;
op = c_parser_cast_expression (parser, NULL);
- op = default_function_array_read_conversion (exp_loc, op);
- return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
+
+ /* If there is array notations in op, we expand them. */
+ if (flag_enable_cilkplus && TREE_CODE (op.value) == ARRAY_NOTATION_REF)
+ return fix_array_notation_expr (exp_loc, PREINCREMENT_EXPR, op);
+ else
+ {
+ op = default_function_array_read_conversion (exp_loc, op);
+ return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
+ }
case CPP_MINUS_MINUS:
c_parser_consume_token (parser);
exp_loc = c_parser_peek_token (parser)->location;
op = c_parser_cast_expression (parser, NULL);
- op = default_function_array_read_conversion (exp_loc, op);
- return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
+
+ /* If there is array notations in op, we expand them. */
+ if (flag_enable_cilkplus && TREE_CODE (op.value) == ARRAY_NOTATION_REF)
+ return fix_array_notation_expr (exp_loc, PREDECREMENT_EXPR, op);
+ else
+ {
+ op = default_function_array_read_conversion (exp_loc, op);
+ return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
+ }
case CPP_AND:
c_parser_consume_token (parser);
op = c_parser_cast_expression (parser, NULL);
@@ -6880,10 +6962,36 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
case CPP_OPEN_SQUARE:
/* Array reference. */
c_parser_consume_token (parser);
- idx = c_parser_expression (parser).value;
- c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
- "expected %<]%>");
- expr.value = build_array_ref (op_loc, expr.value, idx);
+ if (flag_enable_cilkplus
+ && c_parser_peek_token (parser)->type == CPP_COLON)
+ /* If we are here, then we have something like this:
+ Array [ : ]
+ */
+ expr.value = c_parser_array_notation (expr_loc, parser, NULL_TREE,
+ expr.value);
+ else
+ {
+ idx = c_parser_expression (parser).value;
+ /* Here we have 3 options:
+ 1. Array [EXPR] -- Normal Array call.
+ 2. Array [EXPR : EXPR] -- Array notation without stride.
+ 3. Array [EXPR : EXPR : EXPR] -- Array notation with stride.
+
+ For 1, we just handle it just like a normal array expression.
+ For 2 and 3 we handle it like we handle array notations. The
+ idx value we have above becomes the initial/start index.
+ */
+ if (flag_enable_cilkplus
+ && c_parser_peek_token (parser)->type == CPP_COLON)
+ expr.value = c_parser_array_notation (expr_loc, parser, idx,
+ expr.value);
+ else
+ {
+ c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
+ "expected %<]%>");
+ expr.value = build_array_ref (op_loc, expr.value, idx);
+ }
+ }
expr.original_code = ERROR_MARK;
expr.original_type = NULL;
break;
@@ -6991,18 +7099,32 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
case CPP_PLUS_PLUS:
/* Postincrement. */
c_parser_consume_token (parser);
- expr = default_function_array_read_conversion (expr_loc, expr);
- expr.value = build_unary_op (op_loc,
- POSTINCREMENT_EXPR, expr.value, 0);
+ /* If the expressions have array notations, we expand them. */
+ if (flag_enable_cilkplus
+ && TREE_CODE (expr.value) == ARRAY_NOTATION_REF)
+ expr = fix_array_notation_expr (expr_loc, POSTINCREMENT_EXPR, expr);
+ else
+ {
+ expr = default_function_array_read_conversion (expr_loc, expr);
+ expr.value = build_unary_op (op_loc,
+ POSTINCREMENT_EXPR, expr.value, 0);
+ }
expr.original_code = ERROR_MARK;
expr.original_type = NULL;
break;
case CPP_MINUS_MINUS:
/* Postdecrement. */
c_parser_consume_token (parser);
- expr = default_function_array_read_conversion (expr_loc, expr);
- expr.value = build_unary_op (op_loc,
- POSTDECREMENT_EXPR, expr.value, 0);
+ /* If the expressions have array notations, we expand them. */
+ if (flag_enable_cilkplus
+ && TREE_CODE (expr.value) == ARRAY_NOTATION_REF)
+ expr = fix_array_notation_expr (expr_loc, POSTDECREMENT_EXPR, expr);
+ else
+ {
+ expr = default_function_array_read_conversion (expr_loc, expr);
+ expr.value = build_unary_op (op_loc,
+ POSTDECREMENT_EXPR, expr.value, 0);
+ }
expr.original_code = ERROR_MARK;
expr.original_type = NULL;
break;
@@ -10888,4 +11010,171 @@ c_parse_file (void)
the_parser = NULL;
}
+/* This function parses Cilk Plus array notation. The starting index is
+ passed in INITIAL_INDEX and the array name is passes in ARRAY_VALUE. The
+ return value of this function is a tree_node called VALUE_TREE of type
+ ARRAY_NOTATION_REF. */
+
+static tree
+c_parser_array_notation (location_t loc, c_parser *parser, tree initial_index,
+ tree array_value)
+{
+ c_token *token = NULL;
+ tree start_index = NULL_TREE, end_index = NULL_TREE, stride = NULL_TREE;
+ tree value_tree = NULL_TREE, type = NULL_TREE, array_type = NULL_TREE;
+ tree array_type_domain = NULL_TREE;
+
+ if (array_value == error_mark_node)
+ {
+ /* No need to continue. If either of these 2 were true, then an error
+ must be emitted already. Thus, no need to emit them twice. */
+ c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
+ return error_mark_node;
+ }
+
+ array_type = TREE_TYPE (array_value);
+ gcc_assert (array_type);
+ type = TREE_TYPE (array_type);
+ token = c_parser_peek_token (parser);
+
+ if (token->type == CPP_EOF)
+ {
+ c_parser_error (parser, "expected %<:%> or numeral");
+ return value_tree;
+ }
+ else if (token->type == CPP_COLON)
+ {
+ if (!initial_index)
+ {
+ /* If we are here, then we have a case like this A[:]. */
+ c_parser_consume_token (parser);
+ if (TREE_CODE (array_type) == POINTER_TYPE)
+ {
+ error_at (loc, "start-index and length fields necessary for "
+ "using array notations in pointers");
+ c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
+ return error_mark_node;
+ }
+ if (TREE_CODE (array_type) == FUNCTION_TYPE)
+ {
+ error_at (loc, "array notations cannot be used with function "
+ "type");
+ c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
+ return error_mark_node;
+ }
+ if (TREE_CODE (array_type) == ARRAY_TYPE)
+ {
+ tree subtype = TREE_TYPE (array_type);
+ while (subtype && TREE_CODE (subtype) == POINTER_TYPE)
+ {
+ /* Now this could be a function pointer. Find them and
+ give out an error. */
+ subtype = TREE_TYPE (subtype);
+ if (subtype && TREE_CODE (subtype) == FUNCTION_TYPE)
+ {
+ error_at (loc, "array notations cannot be used with "
+ "function pointer arrays");
+ c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
+ NULL);
+ 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");
+ c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
+ return error_mark_node;
+ }
+
+ start_index = TYPE_MINVAL (array_type_domain);
+ start_index = fold_build1 (CONVERT_EXPR, ptrdiff_type_node,
+ start_index);
+ if (!TYPE_MAXVAL (array_type_domain)
+ || !TREE_CONSTANT (TYPE_MAXVAL (array_type_domain)))
+ {
+ error_at (loc, "start-index and length fields necessary for "
+ "using array notations in variable-length arrays");
+ c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
+ return error_mark_node;
+ }
+ end_index = TYPE_MAXVAL (array_type_domain);
+ end_index = fold_build2 (PLUS_EXPR, TREE_TYPE (end_index),
+ end_index, integer_one_node);
+ end_index = fold_build1 (CONVERT_EXPR, ptrdiff_type_node, end_index);
+ stride = build_int_cst (integer_type_node, 1);
+ stride = fold_build1 (CONVERT_EXPR, ptrdiff_type_node, stride);
+ }
+ else if (initial_index != error_mark_node)
+ {
+ /* If we are here, then there should be 2 possibilities:
+ 1. Array [EXPR : EXPR]
+ 2. Array [EXPR : EXPR : EXPR]
+ */
+ start_index = initial_index;
+
+ if (TREE_CODE (array_type) == FUNCTION_TYPE)
+ {
+ error_at (loc, "array notations cannot be used with function "
+ "type");
+ c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
+ return error_mark_node;
+ }
+ if (TREE_CODE (array_type) == ARRAY_TYPE
+ || TREE_CODE (array_type) == POINTER_TYPE)
+ {
+ tree subtype = TREE_TYPE (array_type);
+ while (subtype
+ && (TREE_CODE (subtype) == POINTER_TYPE
+ || TREE_CODE (subtype) == ARRAY_TYPE))
+ {
+ /* Now this could be a function pointer. Find them and
+ give out an error. */
+ subtype = TREE_TYPE (subtype);
+ if (subtype && TREE_CODE (subtype) == FUNCTION_TYPE)
+ {
+ error_at (loc, "array notations cannot be used with "
+ "function pointer arrays");
+ c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
+ NULL);
+ return error_mark_node;
+ }
+ }
+ }
+ c_parser_consume_token (parser); /* consume the ':' */
+ end_index = c_parser_expression (parser).value;
+ if (!end_index || end_index == error_mark_node)
+ {
+ c_parser_skip_to_end_of_block_or_statement (parser);
+ return error_mark_node;
+ }
+ if (c_parser_peek_token (parser)->type == CPP_COLON)
+ {
+ c_parser_consume_token (parser);
+ stride = c_parser_expression (parser).value;
+ if (!stride || stride == error_mark_node)
+ {
+ c_parser_skip_to_end_of_block_or_statement (parser);
+ return error_mark_node;
+ }
+ }
+ }
+ else
+ c_parser_error (parser, "expected array notation expression");
+ }
+ else
+ c_parser_error (parser, "expected array notation expression");
+
+ c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
+
+ value_tree = build_array_notation_ref (loc, array_value, start_index,
+ end_index, stride, type);
+ if (value_tree != error_mark_node)
+ SET_EXPR_LOCATION (value_tree, loc);
+ return value_tree;
+}
+
#include "gt-c-c-parser.h"