diff options
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r-- | gcc/cp/parser.c | 127 |
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 |