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.c79
1 files changed, 73 insertions, 6 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 308b2d4a..e699fbc 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -33773,11 +33773,7 @@ cp_parser_omp_clause_reduction (cp_parser *parser, enum omp_clause_code kind,
if (strcmp (p, "task") == 0)
task = true;
else if (strcmp (p, "inscan") == 0)
- {
- inscan = true;
- sorry ("%<inscan%> modifier on %<reduction%> clause "
- "not supported yet");
- }
+ inscan = true;
if (task || inscan)
{
cp_lexer_consume_token (parser->lexer);
@@ -36820,6 +36816,63 @@ cp_finish_omp_range_for (tree orig, tree begin)
cp_finish_decomp (decl, decomp_first_name, decomp_cnt);
}
+/* OpenMP 5.0:
+
+ scan-loop-body:
+ { structured-block scan-directive structured-block } */
+
+static void
+cp_parser_omp_scan_loop_body (cp_parser *parser)
+{
+ tree substmt, clauses = NULL_TREE;
+
+ matching_braces braces;
+ if (!braces.require_open (parser))
+ return;
+
+ substmt = cp_parser_omp_structured_block (parser, NULL);
+ substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE);
+ add_stmt (substmt);
+
+ cp_token *tok = cp_lexer_peek_token (parser->lexer);
+ if (cp_parser_pragma_kind (tok) == PRAGMA_OMP_SCAN)
+ {
+ enum omp_clause_code clause = OMP_CLAUSE_ERROR;
+
+ cp_lexer_consume_token (parser->lexer);
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ const char *p = IDENTIFIER_POINTER (id);
+ if (strcmp (p, "inclusive") == 0)
+ clause = OMP_CLAUSE_INCLUSIVE;
+ else if (strcmp (p, "exclusive") == 0)
+ clause = OMP_CLAUSE_EXCLUSIVE;
+ }
+ if (clause != OMP_CLAUSE_ERROR)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ clauses = cp_parser_omp_var_list (parser, clause, NULL_TREE);
+ }
+ else
+ cp_parser_error (parser, "expected %<inclusive%> or "
+ "%<exclusive%> clause");
+
+ cp_parser_require_pragma_eol (parser, tok);
+ }
+ else
+ error ("expected %<#pragma omp scan%>");
+
+ clauses = finish_omp_clauses (clauses, C_ORT_OMP);
+ substmt = cp_parser_omp_structured_block (parser, NULL);
+ substmt = build2_loc (tok->location, OMP_SCAN, void_type_node, substmt,
+ clauses);
+ add_stmt (substmt);
+
+ braces.require_close (parser);
+}
+
/* Parse the restricted form of the for statement allowed by OpenMP. */
static tree
@@ -36836,6 +36889,7 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
releasing_vec for_block;
auto_vec<tree, 4> orig_inits;
bool tiling = false;
+ bool inscan = false;
for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
@@ -36851,6 +36905,10 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
ordered_cl = cl;
ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
}
+ else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_REDUCTION
+ && OMP_CLAUSE_REDUCTION_INSCAN (cl)
+ && (code == OMP_SIMD || code == OMP_FOR))
+ inscan = true;
if (ordered && ordered < collapse)
{
@@ -37179,7 +37237,10 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
}
else
body = push_stmt_list ();
- cp_parser_statement (parser, NULL_TREE, false, if_p);
+ if (inscan)
+ cp_parser_omp_scan_loop_body (parser);
+ else
+ cp_parser_statement (parser, NULL_TREE, false, if_p);
if (orig_declv)
body = finish_omp_structured_block (body);
else
@@ -41044,6 +41105,12 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context, bool *if_p)
cp_parser_omp_end_declare_target (parser, pragma_tok);
return false;
+ case PRAGMA_OMP_SCAN:
+ error_at (pragma_tok->location,
+ "%<#pragma omp scan%> may only be used in "
+ "a loop construct with %<inscan%> %<reduction%> clause");
+ break;
+
case PRAGMA_OMP_SECTION:
error_at (pragma_tok->location,
"%<#pragma omp section%> may only be used in "