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.c127
1 files changed, 113 insertions, 14 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index ad99cab..05fa86a 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -239,6 +239,8 @@ static tree cp_literal_operator_id
static void cp_parser_cilk_simd
(cp_parser *, cp_token *);
+static tree cp_parser_cilk_for
+ (cp_parser *, tree);
static bool cp_parser_omp_declare_reduction_exprs
(tree, cp_parser *);
static tree cp_parser_cilk_simd_vectorlength
@@ -9532,6 +9534,18 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
statement = cp_parser_iteration_statement (parser, false);
break;
+ case RID_CILK_FOR:
+ if (!flag_cilkplus)
+ {
+ error_at (cp_lexer_peek_token (parser->lexer)->location,
+ "-fcilkplus must be enabled to use %<_Cilk_for%>");
+ cp_lexer_consume_token (parser->lexer);
+ statement = error_mark_node;
+ }
+ else
+ statement = cp_parser_cilk_for (parser, integer_zero_node);
+ break;
+
case RID_BREAK:
case RID_CONTINUE:
case RID_RETURN:
@@ -29222,7 +29236,7 @@ cp_parser_omp_for_cond (cp_parser *parser, tree decl, enum tree_code code)
case LE_EXPR:
break;
case NE_EXPR:
- if (code == CILK_SIMD)
+ if (code == CILK_SIMD || code == CILK_FOR)
break;
/* Fall through: OpenMP disallows NE_EXPR. */
default:
@@ -29337,15 +29351,12 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl)
/* Parse the initialization statement of either an OpenMP for loop or
a Cilk Plus for loop.
- PARSING_OPENMP is true if parsing OpenMP, or false if parsing Cilk
- Plus.
-
Return true if the resulting construct should have an
OMP_CLAUSE_PRIVATE added to it. */
static bool
cp_parser_omp_for_loop_init (cp_parser *parser,
- bool parsing_openmp,
+ enum tree_code code,
tree &this_pre_body,
vec<tree, va_gc> *for_block,
tree &init,
@@ -29408,7 +29419,7 @@ cp_parser_omp_for_loop_init (cp_parser *parser,
if (cp_lexer_next_token_is (parser->lexer,
CPP_OPEN_PAREN))
{
- if (parsing_openmp)
+ if (code != CILK_SIMD && code != CILK_FOR)
error ("parenthesized initialization is not allowed in "
"OpenMP %<for%> loop");
else
@@ -29480,6 +29491,9 @@ cp_parser_omp_for_loop_init (cp_parser *parser,
cp_id_kind idk;
/* If parsing a type specifier sequence failed, then
this MUST be a simple expression. */
+ if (code == CILK_FOR)
+ error ("%<_Cilk_for%> allows expression instead of declaration only "
+ "in C, not in C++");
cp_parser_parse_tentatively (parser);
decl = cp_parser_primary_expression (parser, false, false,
false, &idk);
@@ -29548,11 +29562,18 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
bool add_private_clause = false;
location_t loc;
- if (!cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR))
+ if (code != CILK_FOR
+ && !cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR))
{
cp_parser_error (parser, "for statement expected");
return NULL;
}
+ if (code == CILK_FOR
+ && !cp_lexer_next_token_is_keyword (parser->lexer, RID_CILK_FOR))
+ {
+ cp_parser_error (parser, "_Cilk_for statement expected");
+ return NULL;
+ }
loc = cp_lexer_consume_token (parser->lexer)->location;
if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
@@ -29562,8 +29583,7 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
this_pre_body = push_stmt_list ();
add_private_clause
- |= cp_parser_omp_for_loop_init (parser,
- /*parsing_openmp=*/code != CILK_SIMD,
+ |= cp_parser_omp_for_loop_init (parser, code,
this_pre_body, for_block,
init, decl, real_decl);
@@ -29733,7 +29753,7 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
/* Note that we saved the original contents of this flag when we entered
the structured block, and so we don't need to re-save it here. */
- if (code == CILK_SIMD)
+ if (code == CILK_SIMD || code == CILK_FOR)
parser->in_statement = IN_CILK_SIMD_FOR;
else
parser->in_statement = IN_OMP_FOR;
@@ -31692,6 +31712,36 @@ cp_parser_initial_pragma (cp_token *first_token)
cp_lexer_get_preprocessor_token (NULL, first_token);
}
+/* Parses the grainsize pragma for the _Cilk_for statement.
+ Syntax:
+ #pragma cilk grainsize = <VALUE>. */
+
+static void
+cp_parser_cilk_grainsize (cp_parser *parser, cp_token *pragma_tok)
+{
+ if (cp_parser_require (parser, CPP_EQ, RT_EQ))
+ {
+ tree exp = cp_parser_binary_expression (parser, false, false,
+ PREC_NOT_OPERATOR, NULL);
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ if (!exp || exp == error_mark_node)
+ {
+ error_at (pragma_tok->location, "invalid grainsize for _Cilk_for");
+ return;
+ }
+
+ /* Make sure the next token is _Cilk_for, it is invalid otherwise. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_CILK_FOR))
+ cp_parser_cilk_for (parser, exp);
+ else
+ warning_at (cp_lexer_peek_token (parser->lexer)->location, 0,
+ "%<#pragma cilk grainsize%> is not followed by "
+ "%<_Cilk_for%>");
+ return;
+ }
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+}
+
/* Normal parsing of a pragma token. Here we can (and must) use the
regular lexer. */
@@ -31874,6 +31924,27 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context)
cp_parser_cilk_simd (parser, pragma_tok);
return true;
+ case PRAGMA_CILK_GRAINSIZE:
+ if (context == pragma_external)
+ {
+ error_at (pragma_tok->location,
+ "%<#pragma cilk grainsize%> must be inside a function");
+ break;
+ }
+
+ /* Ignore the pragma if Cilk Plus is not enabled. */
+ if (flag_cilkplus)
+ {
+ cp_parser_cilk_grainsize (parser, pragma_tok);
+ return true;
+ }
+ else
+ {
+ error_at (pragma_tok->location, "-fcilkplus must be enabled to use "
+ "%<#pragma cilk grainsize%>");
+ break;
+ }
+
default:
gcc_assert (id >= PRAGMA_FIRST_EXTERNAL);
c_invoke_pragma_handler (id);
@@ -31960,10 +32031,10 @@ cp_parser_cilk_simd_vectorlength (cp_parser *parser, tree clauses,
if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
return error_mark_node;
-
+
expr = cp_parser_constant_expression (parser, false, NULL);
expr = maybe_constant_value (expr);
-
+
/* If expr == error_mark_node, then don't emit any errors nor
create a clause. if any of the above functions returns
error mark node then they would have emitted an error message. */
@@ -32197,7 +32268,7 @@ cp_parser_cilk_simd (cp_parser *parser, cp_token *pragma_token)
if (clauses == error_mark_node)
return;
-
+
if (cp_lexer_next_token_is_not_keyword (parser->lexer, RID_FOR))
{
error_at (cp_lexer_peek_token (parser->lexer)->location,
@@ -32212,7 +32283,35 @@ cp_parser_cilk_simd (cp_parser *parser, cp_token *pragma_token)
cpp_validate_cilk_plus_loop (OMP_FOR_BODY (ret));
cp_parser_end_omp_structured_block (parser, save);
add_stmt (finish_omp_structured_block (sb));
- return;
+}
+
+/* Main entry-point for parsing Cilk Plus _Cilk_for
+ loops. The return value is error_mark_node
+ when errors happen and CILK_FOR tree on success. */
+
+static tree
+cp_parser_cilk_for (cp_parser *parser, tree grain)
+{
+ if (cp_lexer_next_token_is_not_keyword (parser->lexer, RID_CILK_FOR))
+ gcc_unreachable ();
+
+ tree sb = begin_omp_structured_block ();
+ int save = cp_parser_begin_omp_structured_block (parser);
+
+ tree clauses = build_omp_clause (EXPR_LOCATION (grain), OMP_CLAUSE_SCHEDULE);
+ OMP_CLAUSE_SCHEDULE_KIND (clauses) = OMP_CLAUSE_SCHEDULE_CILKFOR;
+ OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clauses) = grain;
+ clauses = finish_omp_clauses (clauses);
+
+ tree ret = cp_parser_omp_for_loop (parser, CILK_FOR, clauses, NULL);
+ if (ret)
+ cpp_validate_cilk_plus_loop (ret);
+ else
+ ret = error_mark_node;
+
+ cp_parser_end_omp_structured_block (parser, save);
+ add_stmt (finish_omp_structured_block (sb));
+ return ret;
}
/* Create an identifier for a generic parameter type (a synthesized