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.c1545
1 files changed, 1432 insertions, 113 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index d4ef7f9..435757d 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -9820,6 +9820,8 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
/* Still increment function_depth so that we don't GC in the
middle of an expression. */
++function_depth;
+ vec<tree> omp_privatization_save;
+ save_omp_privatization_clauses (omp_privatization_save);
/* Clear this in case we're in the middle of a default argument. */
parser->local_variables_forbidden_p = false;
@@ -9921,6 +9923,7 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
expand_or_defer_fn (fn);
}
+ restore_omp_privatization_clauses (omp_privatization_save);
parser->local_variables_forbidden_p = local_variables_forbidden_p;
if (nested)
pop_function_context();
@@ -29093,7 +29096,9 @@ cp_parser_omp_clause_name (cp_parser *parser)
result = PRAGMA_OACC_CLAUSE_CREATE;
break;
case 'd':
- if (!strcmp ("depend", p))
+ if (!strcmp ("defaultmap", p))
+ result = PRAGMA_OMP_CLAUSE_DEFAULTMAP;
+ else if (!strcmp ("depend", p))
result = PRAGMA_OMP_CLAUSE_DEPEND;
else if (!strcmp ("device", p))
result = PRAGMA_OMP_CLAUSE_DEVICE;
@@ -29110,19 +29115,29 @@ cp_parser_omp_clause_name (cp_parser *parser)
else if (!strcmp ("from", p))
result = PRAGMA_OMP_CLAUSE_FROM;
break;
+ case 'g':
+ if (!strcmp ("grainsize", p))
+ result = PRAGMA_OMP_CLAUSE_GRAINSIZE;
+ break;
case 'h':
- if (!strcmp ("host", p))
+ if (!strcmp ("hint", p))
+ result = PRAGMA_OMP_CLAUSE_HINT;
+ else if (!strcmp ("host", p))
result = PRAGMA_OACC_CLAUSE_HOST;
break;
case 'i':
if (!strcmp ("inbranch", p))
result = PRAGMA_OMP_CLAUSE_INBRANCH;
+ else if (!strcmp ("is_device_ptr", p))
+ result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR;
break;
case 'l':
if (!strcmp ("lastprivate", p))
result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
else if (!strcmp ("linear", p))
result = PRAGMA_OMP_CLAUSE_LINEAR;
+ else if (!strcmp ("link", p))
+ result = PRAGMA_OMP_CLAUSE_LINK;
break;
case 'm':
if (!strcmp ("map", p))
@@ -29133,7 +29148,9 @@ cp_parser_omp_clause_name (cp_parser *parser)
result = PRAGMA_CILK_CLAUSE_MASK;
break;
case 'n':
- if (!strcmp ("notinbranch", p))
+ if (!strcmp ("nogroup", p))
+ result = PRAGMA_OMP_CLAUSE_NOGROUP;
+ else if (!strcmp ("notinbranch", p))
result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
else if (!strcmp ("nowait", p))
result = PRAGMA_OMP_CLAUSE_NOWAIT;
@@ -29141,6 +29158,8 @@ cp_parser_omp_clause_name (cp_parser *parser)
result = PRAGMA_CILK_CLAUSE_NOMASK;
else if (!strcmp ("num_gangs", p))
result = PRAGMA_OACC_CLAUSE_NUM_GANGS;
+ else if (!strcmp ("num_tasks", p))
+ result = PRAGMA_OMP_CLAUSE_NUM_TASKS;
else if (!strcmp ("num_teams", p))
result = PRAGMA_OMP_CLAUSE_NUM_TEAMS;
else if (!strcmp ("num_threads", p))
@@ -29169,6 +29188,8 @@ cp_parser_omp_clause_name (cp_parser *parser)
else if (!strcmp ("present_or_create", p)
|| !strcmp ("pcreate", p))
result = PRAGMA_OACC_CLAUSE_PRESENT_OR_CREATE;
+ else if (!strcmp ("priority", p))
+ result = PRAGMA_OMP_CLAUSE_PRIORITY;
else if (!strcmp ("proc_bind", p))
result = PRAGMA_OMP_CLAUSE_PROC_BIND;
break;
@@ -29187,6 +29208,8 @@ cp_parser_omp_clause_name (cp_parser *parser)
result = PRAGMA_OACC_CLAUSE_SELF;
else if (!strcmp ("shared", p))
result = PRAGMA_OMP_CLAUSE_SHARED;
+ else if (!strcmp ("simd", p))
+ result = PRAGMA_OMP_CLAUSE_SIMD;
else if (!strcmp ("simdlen", p))
result = PRAGMA_OMP_CLAUSE_SIMDLEN;
break;
@@ -29195,6 +29218,8 @@ cp_parser_omp_clause_name (cp_parser *parser)
result = PRAGMA_OMP_CLAUSE_TASKGROUP;
else if (!strcmp ("thread_limit", p))
result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT;
+ else if (!strcmp ("threads", p))
+ result = PRAGMA_OMP_CLAUSE_THREADS;
else if (!strcmp ("to", p))
result = PRAGMA_OMP_CLAUSE_TO;
break;
@@ -29203,6 +29228,8 @@ cp_parser_omp_clause_name (cp_parser *parser)
result = PRAGMA_OMP_CLAUSE_UNIFORM;
else if (!strcmp ("untied", p))
result = PRAGMA_OMP_CLAUSE_UNTIED;
+ else if (!strcmp ("use_device_ptr", p))
+ result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR;
break;
case 'v':
if (!strcmp ("vector_length", p))
@@ -29273,18 +29300,33 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
tree name, decl;
token = cp_lexer_peek_token (parser->lexer);
- name = cp_parser_id_expression (parser, /*template_p=*/false,
- /*check_dependency_p=*/true,
- /*template_p=*/NULL,
- /*declarator_p=*/false,
- /*optional_p=*/false);
- if (name == error_mark_node)
- goto skip_comma;
+ if (kind != 0
+ && current_class_ptr
+ && cp_parser_is_keyword (token, RID_THIS))
+ {
+ decl = finish_this_expr ();
+ if (TREE_CODE (decl) == NON_LVALUE_EXPR
+ || CONVERT_EXPR_P (decl))
+ decl = TREE_OPERAND (decl, 0);
+ cp_lexer_consume_token (parser->lexer);
+ }
+ else
+ {
+ name = cp_parser_id_expression (parser, /*template_p=*/false,
+ /*check_dependency_p=*/true,
+ /*template_p=*/NULL,
+ /*declarator_p=*/false,
+ /*optional_p=*/false);
+ if (name == error_mark_node)
+ goto skip_comma;
- decl = cp_parser_lookup_name_simple (parser, name, token->location);
+ decl = cp_parser_lookup_name_simple (parser, name, token->location);
+ if (decl == error_mark_node)
+ cp_parser_name_lookup_error (parser, name, decl, NLE_NULL,
+ token->location);
+ }
if (decl == error_mark_node)
- cp_parser_name_lookup_error (parser, name, decl, NLE_NULL,
- token->location);
+ ;
else if (kind != 0)
{
switch (kind)
@@ -29296,11 +29338,24 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
decl = error_mark_node;
break;
}
- /* FALL THROUGH. */
+ /* FALLTHROUGH. */
case OMP_CLAUSE_MAP:
case OMP_CLAUSE_FROM:
case OMP_CLAUSE_TO:
+ while (cp_lexer_next_token_is (parser->lexer, CPP_DOT))
+ {
+ location_t loc
+ = cp_lexer_peek_token (parser->lexer)->location;
+ cp_id_kind idk = CP_ID_KIND_NONE;
+ cp_lexer_consume_token (parser->lexer);
+ decl
+ = cp_parser_postfix_dot_deref_expression (parser, CPP_DOT,
+ decl, false,
+ &idk, loc);
+ }
+ /* FALLTHROUGH. */
case OMP_CLAUSE_DEPEND:
+ case OMP_CLAUSE_REDUCTION:
while (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
{
tree low_bound = NULL_TREE, length = NULL_TREE;
@@ -29334,7 +29389,7 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
&& !TREE_READONLY (low_bound))
{
error_at (token->location,
- "%qD is not a constant", low_bound);
+ "%qD is not a constant", low_bound);
decl = error_mark_node;
}
@@ -29342,7 +29397,7 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
&& !TREE_READONLY (length))
{
error_at (token->location,
- "%qD is not a constant", length);
+ "%qD is not a constant", length);
decl = error_mark_node;
}
}
@@ -29753,16 +29808,102 @@ cp_parser_omp_clause_final (cp_parser *parser, tree list, location_t location)
}
/* OpenMP 2.5:
- if ( expression ) */
+ if ( expression )
+
+ OpenMP 4.5:
+ if ( directive-name-modifier : expression )
+
+ directive-name-modifier:
+ parallel | task | taskloop | target data | target | target update
+ | target enter data | target exit data */
static tree
-cp_parser_omp_clause_if (cp_parser *parser, tree list, location_t location)
+cp_parser_omp_clause_if (cp_parser *parser, tree list, location_t location,
+ bool is_omp)
{
tree t, c;
+ enum tree_code if_modifier = ERROR_MARK;
if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
return list;
+ if (is_omp && 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);
+ int n = 2;
+
+ if (strcmp ("parallel", p) == 0)
+ if_modifier = OMP_PARALLEL;
+ else if (strcmp ("task", p) == 0)
+ if_modifier = OMP_TASK;
+ else if (strcmp ("taskloop", p) == 0)
+ if_modifier = OMP_TASKLOOP;
+ else if (strcmp ("target", p) == 0)
+ {
+ if_modifier = OMP_TARGET;
+ if (cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
+ {
+ id = cp_lexer_peek_nth_token (parser->lexer, 2)->u.value;
+ p = IDENTIFIER_POINTER (id);
+ if (strcmp ("data", p) == 0)
+ if_modifier = OMP_TARGET_DATA;
+ else if (strcmp ("update", p) == 0)
+ if_modifier = OMP_TARGET_UPDATE;
+ else if (strcmp ("enter", p) == 0)
+ if_modifier = OMP_TARGET_ENTER_DATA;
+ else if (strcmp ("exit", p) == 0)
+ if_modifier = OMP_TARGET_EXIT_DATA;
+ if (if_modifier != OMP_TARGET)
+ n = 3;
+ else
+ {
+ location_t loc
+ = cp_lexer_peek_nth_token (parser->lexer, 2)->location;
+ error_at (loc, "expected %<data%>, %<update%>, %<enter%> "
+ "or %<exit%>");
+ if_modifier = ERROR_MARK;
+ }
+ if (if_modifier == OMP_TARGET_ENTER_DATA
+ || if_modifier == OMP_TARGET_EXIT_DATA)
+ {
+ if (cp_lexer_nth_token_is (parser->lexer, 3, CPP_NAME))
+ {
+ id = cp_lexer_peek_nth_token (parser->lexer, 3)->u.value;
+ p = IDENTIFIER_POINTER (id);
+ if (strcmp ("data", p) == 0)
+ n = 4;
+ }
+ if (n != 4)
+ {
+ location_t loc
+ = cp_lexer_peek_nth_token (parser->lexer, 3)->location;
+ error_at (loc, "expected %<data%>");
+ if_modifier = ERROR_MARK;
+ }
+ }
+ }
+ }
+ if (if_modifier != ERROR_MARK)
+ {
+ if (cp_lexer_nth_token_is (parser->lexer, n, CPP_COLON))
+ {
+ while (n-- > 0)
+ cp_lexer_consume_token (parser->lexer);
+ }
+ else
+ {
+ if (n > 2)
+ {
+ location_t loc
+ = cp_lexer_peek_nth_token (parser->lexer, n)->location;
+ error_at (loc, "expected %<:%>");
+ }
+ if_modifier = ERROR_MARK;
+ }
+ }
+ }
+
t = cp_parser_condition (parser);
if (t == error_mark_node
@@ -29771,9 +29912,48 @@ cp_parser_omp_clause_if (cp_parser *parser, tree list, location_t location)
/*or_comma=*/false,
/*consume_paren=*/true);
- check_no_duplicate_clause (list, OMP_CLAUSE_IF, "if", location);
+ for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF)
+ {
+ if (if_modifier != ERROR_MARK
+ && OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
+ {
+ const char *p = NULL;
+ switch (if_modifier)
+ {
+ case OMP_PARALLEL: p = "parallel"; break;
+ case OMP_TASK: p = "task"; break;
+ case OMP_TASKLOOP: p = "taskloop"; break;
+ case OMP_TARGET_DATA: p = "target data"; break;
+ case OMP_TARGET: p = "target"; break;
+ case OMP_TARGET_UPDATE: p = "target update"; break;
+ case OMP_TARGET_ENTER_DATA: p = "enter data"; break;
+ case OMP_TARGET_EXIT_DATA: p = "exit data"; break;
+ default: gcc_unreachable ();
+ }
+ error_at (location, "too many %<if%> clauses with %qs modifier",
+ p);
+ return list;
+ }
+ else if (OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
+ {
+ if (!is_omp)
+ error_at (location, "too many %<if%> clauses");
+ else
+ error_at (location, "too many %<if%> clauses without modifier");
+ return list;
+ }
+ else if (if_modifier == ERROR_MARK
+ || OMP_CLAUSE_IF_MODIFIER (c) == ERROR_MARK)
+ {
+ error_at (location, "if any %<if%> clause has modifier, then all "
+ "%<if%> clauses have to use modifier");
+ return list;
+ }
+ }
c = build_omp_clause (location, OMP_CLAUSE_IF);
+ OMP_CLAUSE_IF_MODIFIER (c) = if_modifier;
OMP_CLAUSE_IF_EXPR (c) = t;
OMP_CLAUSE_CHAIN (c) = list;
@@ -29879,6 +30059,184 @@ cp_parser_omp_clause_num_threads (cp_parser *parser, tree list,
return c;
}
+/* OpenMP 4.5:
+ num_tasks ( expression ) */
+
+static tree
+cp_parser_omp_clause_num_tasks (cp_parser *parser, tree list,
+ location_t location)
+{
+ tree t, c;
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return list;
+
+ t = cp_parser_expression (parser);
+
+ if (t == error_mark_node
+ || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+
+ check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TASKS,
+ "num_tasks", location);
+
+ c = build_omp_clause (location, OMP_CLAUSE_NUM_TASKS);
+ OMP_CLAUSE_NUM_TASKS_EXPR (c) = t;
+ OMP_CLAUSE_CHAIN (c) = list;
+
+ return c;
+}
+
+/* OpenMP 4.5:
+ grainsize ( expression ) */
+
+static tree
+cp_parser_omp_clause_grainsize (cp_parser *parser, tree list,
+ location_t location)
+{
+ tree t, c;
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return list;
+
+ t = cp_parser_expression (parser);
+
+ if (t == error_mark_node
+ || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+
+ check_no_duplicate_clause (list, OMP_CLAUSE_GRAINSIZE,
+ "grainsize", location);
+
+ c = build_omp_clause (location, OMP_CLAUSE_GRAINSIZE);
+ OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
+ OMP_CLAUSE_CHAIN (c) = list;
+
+ return c;
+}
+
+/* OpenMP 4.5:
+ priority ( expression ) */
+
+static tree
+cp_parser_omp_clause_priority (cp_parser *parser, tree list,
+ location_t location)
+{
+ tree t, c;
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return list;
+
+ t = cp_parser_expression (parser);
+
+ if (t == error_mark_node
+ || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+
+ check_no_duplicate_clause (list, OMP_CLAUSE_PRIORITY,
+ "priority", location);
+
+ c = build_omp_clause (location, OMP_CLAUSE_PRIORITY);
+ OMP_CLAUSE_PRIORITY_EXPR (c) = t;
+ OMP_CLAUSE_CHAIN (c) = list;
+
+ return c;
+}
+
+/* OpenMP 4.5:
+ hint ( expression ) */
+
+static tree
+cp_parser_omp_clause_hint (cp_parser *parser, tree list,
+ location_t location)
+{
+ tree t, c;
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return list;
+
+ t = cp_parser_expression (parser);
+
+ if (t == error_mark_node
+ || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+
+ check_no_duplicate_clause (list, OMP_CLAUSE_HINT, "hint", location);
+
+ c = build_omp_clause (location, OMP_CLAUSE_HINT);
+ OMP_CLAUSE_HINT_EXPR (c) = t;
+ OMP_CLAUSE_CHAIN (c) = list;
+
+ return c;
+}
+
+/* OpenMP 4.5:
+ defaultmap ( tofrom : scalar ) */
+
+static tree
+cp_parser_omp_clause_defaultmap (cp_parser *parser, tree list,
+ location_t location)
+{
+ tree c, id;
+ const char *p;
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return list;
+
+ if (!cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ cp_parser_error (parser, "expected %<tofrom%>");
+ goto out_err;
+ }
+ id = cp_lexer_peek_token (parser->lexer)->u.value;
+ p = IDENTIFIER_POINTER (id);
+ if (strcmp (p, "tofrom") != 0)
+ {
+ cp_parser_error (parser, "expected %<tofrom%>");
+ goto out_err;
+ }
+ cp_lexer_consume_token (parser->lexer);
+ if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
+ goto out_err;
+
+ if (!cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ cp_parser_error (parser, "expected %<scalar%>");
+ goto out_err;
+ }
+ id = cp_lexer_peek_token (parser->lexer)->u.value;
+ p = IDENTIFIER_POINTER (id);
+ if (strcmp (p, "scalar") != 0)
+ {
+ cp_parser_error (parser, "expected %<scalar%>");
+ goto out_err;
+ }
+ cp_lexer_consume_token (parser->lexer);
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ goto out_err;
+
+ check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULTMAP, "defaultmap",
+ location);
+
+ c = build_omp_clause (location, OMP_CLAUSE_DEFAULTMAP);
+ OMP_CLAUSE_CHAIN (c) = list;
+ return c;
+
+ out_err:
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+ return list;
+}
+
/* OpenACC:
num_workers ( expression ) */
@@ -29917,18 +30275,49 @@ cp_parser_omp_clause_num_workers (cp_parser *parser, tree list)
}
/* OpenMP 2.5:
- ordered */
+ ordered
+
+ OpenMP 4.5:
+ ordered ( constant-expression ) */
static tree
-cp_parser_omp_clause_ordered (cp_parser * /*parser*/,
+cp_parser_omp_clause_ordered (cp_parser *parser,
tree list, location_t location)
{
- tree c;
+ tree c, num = NULL_TREE;
+ HOST_WIDE_INT n;
check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED,
"ordered", location);
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
+ {
+ cp_lexer_consume_token (parser->lexer);
+
+ num = cp_parser_constant_expression (parser);
+
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+
+ if (num == error_mark_node)
+ return list;
+ num = fold_non_dependent_expr (num);
+ if (!tree_fits_shwi_p (num)
+ || !INTEGRAL_TYPE_P (TREE_TYPE (num))
+ || (n = tree_to_shwi (num)) <= 0
+ || (int) n != n)
+ {
+ error_at (location,
+ "ordered argument needs positive constant integer "
+ "expression");
+ return list;
+ }
+ }
+
c = build_omp_clause (location, OMP_CLAUSE_ORDERED);
+ OMP_CLAUSE_ORDERED_EXPR (c) = num;
OMP_CLAUSE_CHAIN (c) = list;
return c;
}
@@ -30047,7 +30436,14 @@ cp_parser_omp_clause_reduction (cp_parser *parser, tree list)
schedule ( schedule-kind , expression )
schedule-kind:
- static | dynamic | guided | runtime | auto */
+ static | dynamic | guided | runtime | auto
+
+ OpenMP 4.5:
+ schedule ( schedule-modifier : schedule-kind )
+ schedule ( schedule-modifier : schedule-kind , expression )
+
+ schedule-modifier:
+ simd */
static tree
cp_parser_omp_clause_schedule (cp_parser *parser, tree list, location_t location)
@@ -30063,6 +30459,19 @@ cp_parser_omp_clause_schedule (cp_parser *parser, tree list, location_t location
{
tree id = cp_lexer_peek_token (parser->lexer)->u.value;
const char *p = IDENTIFIER_POINTER (id);
+ if (strcmp ("simd", p) == 0
+ && cp_lexer_nth_token_is (parser->lexer, 2, CPP_COLON))
+ {
+ OMP_CLAUSE_SCHEDULE_SIMD (c) = 1;
+ cp_lexer_consume_token (parser->lexer);
+ 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);
switch (p[0])
{
@@ -30180,6 +30589,34 @@ cp_parser_omp_clause_cancelkind (cp_parser * /*parser*/,
return c;
}
+/* OpenMP 4.5:
+ nogroup */
+
+static tree
+cp_parser_omp_clause_nogroup (cp_parser * /*parser*/,
+ tree list, location_t location)
+{
+ check_no_duplicate_clause (list, OMP_CLAUSE_NOGROUP, "nogroup", location);
+ tree c = build_omp_clause (location, OMP_CLAUSE_NOGROUP);
+ OMP_CLAUSE_CHAIN (c) = list;
+ return c;
+}
+
+/* OpenMP 4.5:
+ simd
+ threads */
+
+static tree
+cp_parser_omp_clause_orderedkind (cp_parser * /*parser*/,
+ enum omp_clause_code code,
+ tree list, location_t location)
+{
+ check_no_duplicate_clause (list, code, omp_clause_code_name[code], location);
+ tree c = build_omp_clause (location, code);
+ OMP_CLAUSE_CHAIN (c) = list;
+ return c;
+}
+
/* OpenMP 4.0:
num_teams ( expression ) */
@@ -30277,7 +30714,11 @@ cp_parser_omp_clause_aligned (cp_parser *parser, tree list)
/* OpenMP 4.0:
linear ( variable-list )
- linear ( variable-list : expression ) */
+ linear ( variable-list : expression )
+
+ OpenMP 4.5:
+ linear ( modifier ( variable-list ) )
+ linear ( modifier ( variable-list ) : expression ) */
static tree
cp_parser_omp_clause_linear (cp_parser *parser, tree list,
@@ -30285,12 +30726,43 @@ cp_parser_omp_clause_linear (cp_parser *parser, tree list,
{
tree nlist, c, step = integer_one_node;
bool colon;
+ enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
return list;
- nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_LINEAR, list,
- &colon);
+ if (!is_cilk_simd_fn
+ && 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 ("ref", p) == 0)
+ kind = OMP_CLAUSE_LINEAR_REF;
+ else if (strcmp ("val", p) == 0)
+ kind = OMP_CLAUSE_LINEAR_VAL;
+ else if (strcmp ("uval", p) == 0)
+ kind = OMP_CLAUSE_LINEAR_UVAL;
+ if (cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_PAREN))
+ cp_lexer_consume_token (parser->lexer);
+ else
+ kind = OMP_CLAUSE_LINEAR_DEFAULT;
+ }
+
+ if (kind == OMP_CLAUSE_LINEAR_DEFAULT)
+ nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_LINEAR, list,
+ &colon);
+ else
+ {
+ nlist = cp_parser_omp_var_list (parser, OMP_CLAUSE_LINEAR, list);
+ colon = cp_lexer_next_token_is (parser->lexer, CPP_COLON);
+ if (colon)
+ cp_parser_require (parser, CPP_COLON, RT_COLON);
+ else if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+ }
if (colon)
{
@@ -30311,7 +30783,10 @@ cp_parser_omp_clause_linear (cp_parser *parser, tree list,
}
for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
- OMP_CLAUSE_LINEAR_STEP (c) = step;
+ {
+ OMP_CLAUSE_LINEAR_STEP (c) = step;
+ OMP_CLAUSE_LINEAR_KIND (c) = kind;
+ }
return nlist;
}
@@ -30374,14 +30849,104 @@ cp_parser_omp_clause_simdlen (cp_parser *parser, tree list,
return c;
}
+/* OpenMP 4.5:
+ vec:
+ identifier [+/- integer]
+ vec , identifier [+/- integer]
+*/
+
+static tree
+cp_parser_omp_clause_depend_sink (cp_parser *parser, location_t clause_loc,
+ tree list)
+{
+ tree vec = NULL;
+
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME))
+ {
+ cp_parser_error (parser, "expected identifier");
+ return list;
+ }
+
+ while (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ location_t id_loc = cp_lexer_peek_token (parser->lexer)->location;
+ tree t, identifier = cp_parser_identifier (parser);
+ tree addend = NULL;
+
+ if (identifier == error_mark_node)
+ t = error_mark_node;
+ else
+ {
+ t = cp_parser_lookup_name_simple
+ (parser, identifier,
+ cp_lexer_peek_token (parser->lexer)->location);
+ if (t == error_mark_node)
+ cp_parser_name_lookup_error (parser, identifier, t, NLE_NULL,
+ id_loc);
+ }
+
+ bool neg = false;
+ if (cp_lexer_next_token_is (parser->lexer, CPP_MINUS))
+ neg = true;
+ else if (!cp_lexer_next_token_is (parser->lexer, CPP_PLUS))
+ {
+ addend = integer_zero_node;
+ goto add_to_vector;
+ }
+ cp_lexer_consume_token (parser->lexer);
+
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_NUMBER))
+ {
+ cp_parser_error (parser, "expected integer");
+ return list;
+ }
+
+ addend = cp_lexer_peek_token (parser->lexer)->u.value;
+ if (TREE_CODE (addend) != INTEGER_CST)
+ {
+ cp_parser_error (parser, "expected integer");
+ return list;
+ }
+ cp_lexer_consume_token (parser->lexer);
+
+ add_to_vector:
+ if (t != error_mark_node)
+ {
+ vec = tree_cons (addend, t, vec);
+ if (neg)
+ OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec) = 1;
+ }
+
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
+ break;
+
+ cp_lexer_consume_token (parser->lexer);
+ }
+
+ if (cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN) && vec)
+ {
+ tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
+ OMP_CLAUSE_DEPEND_KIND (u) = OMP_CLAUSE_DEPEND_SINK;
+ OMP_CLAUSE_DECL (u) = nreverse (vec);
+ OMP_CLAUSE_CHAIN (u) = list;
+ return u;
+ }
+ return list;
+}
+
/* OpenMP 4.0:
depend ( depend-kind : variable-list )
depend-kind:
- in | out | inout */
+ in | out | inout
+
+ OpenMP 4.5:
+ depend ( source )
+
+ depend ( sink : vec ) */
static tree
-cp_parser_omp_clause_depend (cp_parser *parser, tree list)
+cp_parser_omp_clause_depend (cp_parser *parser, tree list, location_t loc)
{
tree nlist, c;
enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_INOUT;
@@ -30400,6 +30965,10 @@ cp_parser_omp_clause_depend (cp_parser *parser, tree list)
kind = OMP_CLAUSE_DEPEND_INOUT;
else if (strcmp ("out", p) == 0)
kind = OMP_CLAUSE_DEPEND_OUT;
+ else if (strcmp ("source", p) == 0)
+ kind = OMP_CLAUSE_DEPEND_SOURCE;
+ else if (strcmp ("sink", p) == 0)
+ kind = OMP_CLAUSE_DEPEND_SINK;
else
goto invalid_kind;
}
@@ -30407,15 +30976,33 @@ cp_parser_omp_clause_depend (cp_parser *parser, tree list)
goto invalid_kind;
cp_lexer_consume_token (parser->lexer);
+
+ if (kind == OMP_CLAUSE_DEPEND_SOURCE)
+ {
+ c = build_omp_clause (loc, OMP_CLAUSE_DEPEND);
+ OMP_CLAUSE_DEPEND_KIND (c) = kind;
+ OMP_CLAUSE_DECL (c) = NULL_TREE;
+ OMP_CLAUSE_CHAIN (c) = list;
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+ return c;
+ }
+
if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
goto resync_fail;
- nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_DEPEND, list,
- NULL);
-
- for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
- OMP_CLAUSE_DEPEND_KIND (c) = kind;
+ if (kind == OMP_CLAUSE_DEPEND_SINK)
+ nlist = cp_parser_omp_clause_depend_sink (parser, loc, list);
+ else
+ {
+ nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_DEPEND,
+ list, NULL);
+ for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
+ OMP_CLAUSE_DEPEND_KIND (c) = kind;
+ }
return nlist;
invalid_kind:
@@ -30432,17 +31019,48 @@ cp_parser_omp_clause_depend (cp_parser *parser, tree list)
map ( variable-list )
map-kind:
- alloc | to | from | tofrom */
+ alloc | to | from | tofrom
+
+ OpenMP 4.5:
+ map-kind:
+ alloc | to | from | tofrom | release | delete
+
+ map ( always [,] map-kind: variable-list ) */
static tree
cp_parser_omp_clause_map (cp_parser *parser, tree list)
{
tree nlist, c;
enum gomp_map_kind kind = GOMP_MAP_TOFROM;
+ bool always = false;
if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
return list;
+ 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 ("always", p) == 0)
+ {
+ int nth = 2;
+ if (cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_COMMA)
+ nth++;
+ if ((cp_lexer_peek_nth_token (parser->lexer, nth)->type == CPP_NAME
+ || (cp_lexer_peek_nth_token (parser->lexer, nth)->keyword
+ == RID_DELETE))
+ && (cp_lexer_peek_nth_token (parser->lexer, nth + 1)->type
+ == CPP_COLON))
+ {
+ always = true;
+ cp_lexer_consume_token (parser->lexer);
+ if (nth == 3)
+ cp_lexer_consume_token (parser->lexer);
+ }
+ }
+ }
+
if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
&& cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_COLON)
{
@@ -30452,11 +31070,13 @@ cp_parser_omp_clause_map (cp_parser *parser, tree list)
if (strcmp ("alloc", p) == 0)
kind = GOMP_MAP_ALLOC;
else if (strcmp ("to", p) == 0)
- kind = GOMP_MAP_TO;
+ kind = always ? GOMP_MAP_ALWAYS_TO : GOMP_MAP_TO;
else if (strcmp ("from", p) == 0)
- kind = GOMP_MAP_FROM;
+ kind = always ? GOMP_MAP_ALWAYS_FROM : GOMP_MAP_FROM;
else if (strcmp ("tofrom", p) == 0)
- kind = GOMP_MAP_TOFROM;
+ kind = always ? GOMP_MAP_ALWAYS_TOFROM : GOMP_MAP_TOFROM;
+ else if (strcmp ("release", p) == 0)
+ kind = GOMP_MAP_RELEASE;
else
{
cp_parser_error (parser, "invalid map kind");
@@ -30468,6 +31088,13 @@ cp_parser_omp_clause_map (cp_parser *parser, tree list)
cp_lexer_consume_token (parser->lexer);
cp_lexer_consume_token (parser->lexer);
}
+ else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_DELETE)
+ && cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_COLON)
+ {
+ kind = GOMP_MAP_DELETE;
+ cp_lexer_consume_token (parser->lexer);
+ cp_lexer_consume_token (parser->lexer);
+ }
nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_MAP, list,
NULL);
@@ -30710,7 +31337,7 @@ cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask,
c_name = "host";
break;
case PRAGMA_OACC_CLAUSE_IF:
- clauses = cp_parser_omp_clause_if (parser, clauses, here);
+ clauses = cp_parser_omp_clause_if (parser, clauses, here, false);
c_name = "if";
break;
case PRAGMA_OACC_CLAUSE_NUM_GANGS:
@@ -30777,7 +31404,7 @@ cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask,
cp_parser_skip_to_pragma_eol (parser, pragma_tok);
if (finish_p)
- return finish_omp_clauses (clauses);
+ return finish_omp_clauses (clauses, false);
return clauses;
}
@@ -30838,8 +31465,34 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
clauses);
c_name = "firstprivate";
break;
+ case PRAGMA_OMP_CLAUSE_GRAINSIZE:
+ clauses = cp_parser_omp_clause_grainsize (parser, clauses,
+ token->location);
+ c_name = "grainsize";
+ break;
+ case PRAGMA_OMP_CLAUSE_HINT:
+ clauses = cp_parser_omp_clause_hint (parser, clauses,
+ token->location);
+ c_name = "hint";
+ break;
+ case PRAGMA_OMP_CLAUSE_DEFAULTMAP:
+ clauses = cp_parser_omp_clause_defaultmap (parser, clauses,
+ token->location);
+ c_name = "defaultmap";
+ break;
+ case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR:
+ clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_USE_DEVICE_PTR,
+ clauses);
+ c_name = "use_device_ptr";
+ break;
+ case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR:
+ clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_IS_DEVICE_PTR,
+ clauses);
+ c_name = "is_device_ptr";
+ break;
case PRAGMA_OMP_CLAUSE_IF:
- clauses = cp_parser_omp_clause_if (parser, clauses, token->location);
+ clauses = cp_parser_omp_clause_if (parser, clauses, token->location,
+ true);
c_name = "if";
break;
case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
@@ -30856,6 +31509,11 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
clauses = cp_parser_omp_clause_nowait (parser, clauses, token->location);
c_name = "nowait";
break;
+ case PRAGMA_OMP_CLAUSE_NUM_TASKS:
+ clauses = cp_parser_omp_clause_num_tasks (parser, clauses,
+ token->location);
+ c_name = "num_tasks";
+ break;
case PRAGMA_OMP_CLAUSE_NUM_THREADS:
clauses = cp_parser_omp_clause_num_threads (parser, clauses,
token->location);
@@ -30866,6 +31524,11 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
token->location);
c_name = "ordered";
break;
+ case PRAGMA_OMP_CLAUSE_PRIORITY:
+ clauses = cp_parser_omp_clause_priority (parser, clauses,
+ token->location);
+ c_name = "priority";
+ break;
case PRAGMA_OMP_CLAUSE_PRIVATE:
clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_PRIVATE,
clauses);
@@ -30936,14 +31599,20 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
if (!first)
goto clause_not_first;
break;
+ case PRAGMA_OMP_CLAUSE_LINK:
+ clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_LINK, clauses);
+ c_name = "to";
+ break;
case PRAGMA_OMP_CLAUSE_TO:
- clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_TO,
- clauses);
+ if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0)
+ clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_TO_DECLARE,
+ clauses);
+ else
+ clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_TO, clauses);
c_name = "to";
break;
case PRAGMA_OMP_CLAUSE_FROM:
- clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_FROM,
- clauses);
+ clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_FROM, clauses);
c_name = "from";
break;
case PRAGMA_OMP_CLAUSE_UNIFORM:
@@ -30972,7 +31641,8 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
c_name = "linear";
break;
case PRAGMA_OMP_CLAUSE_DEPEND:
- clauses = cp_parser_omp_clause_depend (parser, clauses);
+ clauses = cp_parser_omp_clause_depend (parser, clauses,
+ token->location);
c_name = "depend";
break;
case PRAGMA_OMP_CLAUSE_MAP:
@@ -31004,6 +31674,23 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
token->location);
c_name = "simdlen";
break;
+ case PRAGMA_OMP_CLAUSE_NOGROUP:
+ clauses = cp_parser_omp_clause_nogroup (parser, clauses,
+ token->location);
+ c_name = "nogroup";
+ break;
+ case PRAGMA_OMP_CLAUSE_THREADS:
+ clauses
+ = cp_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_THREADS,
+ clauses, token->location);
+ c_name = "threads";
+ break;
+ case PRAGMA_OMP_CLAUSE_SIMD:
+ clauses
+ = cp_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_SIMD,
+ clauses, token->location);
+ c_name = "simd";
+ break;
case PRAGMA_CILK_CLAUSE_VECTORLENGTH:
clauses = cp_parser_cilk_simd_vectorlength (parser, clauses, true);
c_name = "simdlen";
@@ -31029,7 +31716,12 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
if (!(flag_cilkplus && pragma_tok == NULL))
cp_parser_skip_to_pragma_eol (parser, pragma_tok);
if (finish_p)
- return finish_omp_clauses (clauses);
+ {
+ if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)) != 0)
+ return finish_omp_clauses (clauses, false, true);
+ else
+ return finish_omp_clauses (clauses, true);
+ }
return clauses;
}
@@ -31522,12 +32214,19 @@ cp_parser_omp_barrier (cp_parser *parser, cp_token *pragma_tok)
/* OpenMP 2.5:
# pragma omp critical [(name)] new-line
+ structured-block
+
+ OpenMP 4.5:
+ # pragma omp critical [(name) [hint(expression)]] new-line
structured-block */
+#define OMP_CRITICAL_CLAUSE_MASK \
+ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
+
static tree
cp_parser_omp_critical (cp_parser *parser, cp_token *pragma_tok)
{
- tree stmt, name = NULL;
+ tree stmt, name = NULL_TREE, clauses = NULL_TREE;
if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
{
@@ -31542,11 +32241,16 @@ cp_parser_omp_critical (cp_parser *parser, cp_token *pragma_tok)
/*consume_paren=*/true);
if (name == error_mark_node)
name = NULL;
+
+ clauses = cp_parser_omp_all_clauses (parser,
+ OMP_CRITICAL_CLAUSE_MASK,
+ "#pragma omp critical", pragma_tok);
}
- cp_parser_require_pragma_eol (parser, pragma_tok);
+ else
+ cp_parser_require_pragma_eol (parser, pragma_tok);
stmt = cp_parser_omp_structured_block (parser);
- return c_finish_omp_critical (input_location, stmt, name);
+ return c_finish_omp_critical (input_location, stmt, name, clauses);
}
/* OpenMP 2.5:
@@ -31624,13 +32328,15 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl)
? PREINCREMENT_EXPR : PREDECREMENT_EXPR);
cp_lexer_consume_token (parser->lexer);
lhs = cp_parser_simple_cast_expression (parser);
- if (lhs != decl)
+ if (lhs != decl
+ && (!processing_template_decl || !cp_tree_equal (lhs, decl)))
return error_mark_node;
return build2 (op, TREE_TYPE (decl), decl, NULL_TREE);
}
lhs = cp_parser_primary_expression (parser, false, false, false, &idk);
- if (lhs != decl)
+ if (lhs != decl
+ && (!processing_template_decl || !cp_tree_equal (lhs, decl)))
return error_mark_node;
token = cp_lexer_peek_token (parser->lexer);
@@ -31656,7 +32362,8 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl)
lhs = cp_parser_binary_expression (parser, false, false,
PREC_ADDITIVE_EXPRESSION, NULL);
token = cp_lexer_peek_token (parser->lexer);
- decl_first = lhs == decl;
+ decl_first = (lhs == decl
+ || (processing_template_decl && cp_tree_equal (lhs, decl)));
if (decl_first)
lhs = NULL_TREE;
if (token->type != CPP_PLUS
@@ -31689,7 +32396,9 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl)
if (!decl_first)
{
- if (rhs != decl || op == MINUS_EXPR)
+ if ((rhs != decl
+ && (!processing_template_decl || !cp_tree_equal (rhs, decl)))
+ || op == MINUS_EXPR)
return error_mark_node;
rhs = build2 (op, TREE_TYPE (decl), lhs, decl);
}
@@ -31705,7 +32414,7 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl)
Return true if the resulting construct should have an
OMP_CLAUSE_PRIVATE added to it. */
-static bool
+static tree
cp_parser_omp_for_loop_init (cp_parser *parser,
enum tree_code code,
tree &this_pre_body,
@@ -31715,9 +32424,9 @@ cp_parser_omp_for_loop_init (cp_parser *parser,
tree &real_decl)
{
if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
- return false;
+ return NULL_TREE;
- bool add_private_clause = false;
+ tree add_private_clause = NULL_TREE;
/* See 2.5.1 (in OpenMP 3.0, similar wording is in 2.5 standard too):
@@ -31848,6 +32557,33 @@ cp_parser_omp_for_loop_init (cp_parser *parser,
cp_parser_parse_tentatively (parser);
decl = cp_parser_primary_expression (parser, false, false,
false, &idk);
+ cp_token *last_tok = cp_lexer_peek_token (parser->lexer);
+ if (!cp_parser_error_occurred (parser)
+ && decl
+ && (TREE_CODE (decl) == COMPONENT_REF
+ || (TREE_CODE (decl) == SCOPE_REF && TREE_TYPE (decl))))
+ {
+ cp_parser_abort_tentative_parse (parser);
+ cp_parser_parse_tentatively (parser);
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ tree name = cp_parser_id_expression (parser, /*template_p=*/false,
+ /*check_dependency_p=*/true,
+ /*template_p=*/NULL,
+ /*declarator_p=*/false,
+ /*optional_p=*/false);
+ if (name != error_mark_node
+ && last_tok == cp_lexer_peek_token (parser->lexer))
+ {
+ decl = cp_parser_lookup_name_simple (parser, name,
+ token->location);
+ if (TREE_CODE (decl) == FIELD_DECL)
+ add_private_clause = omp_privatize_field (decl);
+ }
+ cp_parser_abort_tentative_parse (parser);
+ cp_parser_parse_tentatively (parser);
+ decl = cp_parser_primary_expression (parser, false, false,
+ false, &idk);
+ }
if (!cp_parser_error_occurred (parser)
&& decl
&& DECL_P (decl)
@@ -31862,7 +32598,8 @@ cp_parser_omp_for_loop_init (cp_parser *parser,
decl, NOP_EXPR,
rhs,
tf_warning_or_error));
- add_private_clause = true;
+ if (!add_private_clause)
+ add_private_clause = decl;
}
else
{
@@ -31888,29 +32625,58 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
{
tree init, cond, incr, body, decl, pre_body = NULL_TREE, ret;
tree real_decl, initv, condv, incrv, declv;
- tree this_pre_body, cl;
+ tree this_pre_body, cl, ordered_cl = NULL_TREE;
location_t loc_first;
bool collapse_err = false;
- int i, collapse = 1, nbraces = 0;
+ int i, collapse = 1, ordered = 0, count, nbraces = 0;
vec<tree, va_gc> *for_block = make_tree_vector ();
for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl));
+ else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED
+ && OMP_CLAUSE_ORDERED_EXPR (cl))
+ {
+ ordered_cl = cl;
+ ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
+ }
+
+ if (ordered && ordered < collapse)
+ {
+ error_at (OMP_CLAUSE_LOCATION (ordered_cl),
+ "%<ordered%> clause parameter is less than %<collapse%>");
+ OMP_CLAUSE_ORDERED_EXPR (ordered_cl)
+ = build_int_cst (NULL_TREE, collapse);
+ ordered = collapse;
+ }
+ if (ordered)
+ {
+ for (tree *pc = &clauses; *pc; )
+ if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LINEAR)
+ {
+ error_at (OMP_CLAUSE_LOCATION (*pc),
+ "%<linear%> clause may not be specified together "
+ "with %<ordered%> clause with a parameter");
+ *pc = OMP_CLAUSE_CHAIN (*pc);
+ }
+ else
+ pc = &OMP_CLAUSE_CHAIN (*pc);
+ }
- gcc_assert (collapse >= 1);
+ gcc_assert (collapse >= 1 && ordered >= 0);
+ count = ordered ? ordered : collapse;
- declv = make_tree_vec (collapse);
- initv = make_tree_vec (collapse);
- condv = make_tree_vec (collapse);
- incrv = make_tree_vec (collapse);
+ declv = make_tree_vec (count);
+ initv = make_tree_vec (count);
+ condv = make_tree_vec (count);
+ incrv = make_tree_vec (count);
loc_first = cp_lexer_peek_token (parser->lexer)->location;
- for (i = 0; i < collapse; i++)
+ for (i = 0; i < count; i++)
{
int bracecount = 0;
- bool add_private_clause = false;
+ tree add_private_clause = NULL_TREE;
location_t loc;
if (code != CILK_FOR
@@ -31934,9 +32700,9 @@ 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, code,
- this_pre_body, for_block,
- init, decl, real_decl);
+ = cp_parser_omp_for_loop_init (parser, code,
+ this_pre_body, for_block,
+ init, decl, real_decl);
cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
if (this_pre_body)
@@ -31985,13 +32751,13 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
OMP_CLAUSE_CHAIN (l) = clauses;
clauses = l;
}
- add_private_clause = false;
+ add_private_clause = NULL_TREE;
}
else
{
if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_PRIVATE
&& OMP_CLAUSE_DECL (*c) == real_decl)
- add_private_clause = false;
+ add_private_clause = NULL_TREE;
c = &OMP_CLAUSE_CHAIN (*c);
}
}
@@ -32017,13 +32783,22 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
}
if (c == NULL)
{
- c = build_omp_clause (loc, OMP_CLAUSE_PRIVATE);
- OMP_CLAUSE_DECL (c) = decl;
- c = finish_omp_clauses (c);
+ if (code != OMP_SIMD)
+ c = build_omp_clause (loc, OMP_CLAUSE_PRIVATE);
+ else if (collapse == 1)
+ c = build_omp_clause (loc, OMP_CLAUSE_LINEAR);
+ else
+ c = build_omp_clause (loc, OMP_CLAUSE_LASTPRIVATE);
+ OMP_CLAUSE_DECL (c) = add_private_clause;
+ c = finish_omp_clauses (c, true);
if (c)
{
OMP_CLAUSE_CHAIN (c) = clauses;
clauses = c;
+ /* For linear, signal that we need to fill up
+ the so far unknown linear step. */
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR)
+ OMP_CLAUSE_LINEAR_STEP (c) = NULL_TREE;
}
}
}
@@ -32040,7 +32815,8 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
until finish_omp_for. */
if (real_decl
&& ((processing_template_decl
- && !POINTER_TYPE_P (TREE_TYPE (real_decl)))
+ && (TREE_TYPE (real_decl) == NULL_TREE
+ || !POINTER_TYPE_P (TREE_TYPE (real_decl))))
|| CLASS_TYPE_P (TREE_TYPE (real_decl))))
incr = cp_parser_omp_for_incr (parser, real_decl);
else
@@ -32059,7 +32835,7 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
TREE_VEC_ELT (condv, i) = cond;
TREE_VEC_ELT (incrv, i) = incr;
- if (i == collapse - 1)
+ if (i == count - 1)
break;
/* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
@@ -32114,8 +32890,8 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
if (declv == NULL_TREE)
ret = NULL_TREE;
else
- ret = finish_omp_for (loc_first, code, declv, initv, condv, incrv, body,
- pre_body, clauses);
+ ret = finish_omp_for (loc_first, code, declv, NULL, initv, condv, incrv,
+ body, pre_body, clauses);
while (nbraces)
{
@@ -32158,7 +32934,7 @@ cp_omp_split_clauses (location_t loc, enum tree_code code,
c_omp_split_clauses (loc, code, mask, clauses, cclauses);
for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
if (cclauses[i])
- cclauses[i] = finish_omp_clauses (cclauses[i]);
+ cclauses[i] = finish_omp_clauses (cclauses[i], true);
}
/* OpenMP 4.0:
@@ -32167,6 +32943,7 @@ cp_omp_split_clauses (location_t loc, enum tree_code code,
#define OMP_SIMD_CLAUSE_MASK \
( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
@@ -32184,7 +32961,6 @@ cp_parser_omp_simd (cp_parser *parser, cp_token *pragma_tok,
strcat (p_name, " simd");
mask |= OMP_SIMD_CLAUSE_MASK;
- mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED);
clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
cclauses == NULL);
@@ -32192,6 +32968,15 @@ cp_parser_omp_simd (cp_parser *parser, cp_token *pragma_tok,
{
cp_omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses);
clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
+ tree c = find_omp_clause (cclauses[C_OMP_CLAUSE_SPLIT_FOR],
+ OMP_CLAUSE_ORDERED);
+ if (c && OMP_CLAUSE_ORDERED_EXPR (c))
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%<ordered%> clause with parameter may not be specified "
+ "on %qs construct", p_name);
+ OMP_CLAUSE_ORDERED_EXPR (c) = NULL_TREE;
+ }
}
sb = begin_omp_structured_block ();
@@ -32217,6 +33002,7 @@ cp_parser_omp_simd (cp_parser *parser, cp_token *pragma_tok,
( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
@@ -32235,6 +33021,9 @@ cp_parser_omp_for (cp_parser *parser, cp_token *pragma_tok,
mask |= OMP_FOR_CLAUSE_MASK;
if (cclauses)
mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
+ /* Composite distribute parallel for{, simd} disallows ordered clause. */
+ if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
+ mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED);
if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
{
@@ -32274,6 +33063,10 @@ cp_parser_omp_for (cp_parser *parser, cp_token *pragma_tok,
return NULL_TREE;
}
+ /* Composite distribute parallel for disallows linear clause. */
+ if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
+ mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR);
+
clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
cclauses == NULL);
if (cclauses)
@@ -32307,14 +33100,62 @@ cp_parser_omp_master (cp_parser *parser, cp_token *pragma_tok)
/* OpenMP 2.5:
# pragma omp ordered new-line
+ structured-block
+
+ OpenMP 4.5:
+ # pragma omp ordered ordered-clauses new-line
structured-block */
-static tree
-cp_parser_omp_ordered (cp_parser *parser, cp_token *pragma_tok)
+#define OMP_ORDERED_CLAUSE_MASK \
+ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
+
+#define OMP_ORDERED_DEPEND_CLAUSE_MASK \
+ (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
+
+static bool
+cp_parser_omp_ordered (cp_parser *parser, cp_token *pragma_tok,
+ enum pragma_context context)
{
- location_t loc = cp_lexer_peek_token (parser->lexer)->location;
- cp_parser_require_pragma_eol (parser, pragma_tok);
- return c_finish_omp_ordered (loc, cp_parser_omp_structured_block (parser));
+ location_t loc = pragma_tok->location;
+
+ if (context != pragma_stmt && context != pragma_compound)
+ {
+ cp_parser_error (parser, "expected declaration specifiers");
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ return false;
+ }
+
+ 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, "depend") == 0)
+ {
+ if (context == pragma_stmt)
+ {
+ error_at (pragma_tok->location, "%<#pragma omp ordered%> with "
+ "%<depend%> clause may only be used in compound "
+ "statements");
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ return false;
+ }
+ tree clauses
+ = cp_parser_omp_all_clauses (parser,
+ OMP_ORDERED_DEPEND_CLAUSE_MASK,
+ "#pragma omp ordered", pragma_tok);
+ c_finish_omp_ordered (loc, clauses, NULL_TREE);
+ return false;
+ }
+ }
+
+ tree clauses
+ = cp_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK,
+ "#pragma omp ordered", pragma_tok);
+ c_finish_omp_ordered (loc, clauses,
+ cp_parser_omp_structured_block (parser));
+ return true;
}
/* OpenMP 2.5:
@@ -32452,6 +33293,10 @@ cp_parser_omp_parallel (cp_parser *parser, cp_token *pragma_tok,
strcat (p_name, " parallel");
mask |= OMP_PARALLEL_CLAUSE_MASK;
+ /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
+ if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0
+ && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
+ mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN);
if (cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR))
{
@@ -32473,7 +33318,11 @@ cp_parser_omp_parallel (cp_parser *parser, cp_token *pragma_tok,
OMP_PARALLEL_COMBINED (stmt) = 1;
return stmt;
}
- else if (cclauses)
+ /* When combined with distribute, parallel has to be followed by for.
+ #pragma omp target parallel is allowed though. */
+ else if (cclauses
+ && (mask & (OMP_CLAUSE_MASK_1
+ << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
{
error_at (loc, "expected %<for%> after %qs", p_name);
cp_parser_skip_to_pragma_eol (parser, pragma_tok);
@@ -32484,7 +33333,7 @@ cp_parser_omp_parallel (cp_parser *parser, cp_token *pragma_tok,
cp_parser_skip_to_pragma_eol (parser, pragma_tok);
return NULL_TREE;
}
- else if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ else if (cclauses == NULL && 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);
@@ -32506,6 +33355,11 @@ cp_parser_omp_parallel (cp_parser *parser, cp_token *pragma_tok,
}
clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok);
+ if (cclauses)
+ {
+ cp_omp_split_clauses (loc, OMP_PARALLEL, mask, clauses, cclauses);
+ clauses = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
+ }
block = begin_omp_parallel ();
save = cp_parser_begin_omp_structured_block (parser);
@@ -32552,7 +33406,8 @@ cp_parser_omp_single (cp_parser *parser, cp_token *pragma_tok)
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
- | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND))
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY))
static tree
cp_parser_omp_task (cp_parser *parser, cp_token *pragma_tok)
@@ -32851,17 +33706,57 @@ cp_parser_omp_teams (cp_parser *parser, cp_token *pragma_tok,
#define OMP_TARGET_DATA_CLAUSE_MASK \
( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
- | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR))
static tree
cp_parser_omp_target_data (cp_parser *parser, cp_token *pragma_tok)
{
+ tree clauses
+ = cp_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
+ "#pragma omp target data", pragma_tok);
+ int map_seen = 0;
+ for (tree *pc = &clauses; *pc;)
+ {
+ if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
+ switch (OMP_CLAUSE_MAP_KIND (*pc))
+ {
+ case GOMP_MAP_TO:
+ case GOMP_MAP_ALWAYS_TO:
+ case GOMP_MAP_FROM:
+ case GOMP_MAP_ALWAYS_FROM:
+ case GOMP_MAP_TOFROM:
+ case GOMP_MAP_ALWAYS_TOFROM:
+ case GOMP_MAP_ALLOC:
+ map_seen = 3;
+ break;
+ case GOMP_MAP_FIRSTPRIVATE_POINTER:
+ break;
+ default:
+ map_seen |= 1;
+ error_at (OMP_CLAUSE_LOCATION (*pc),
+ "%<#pragma omp target data%> with map-type other "
+ "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
+ "on %<map%> clause");
+ *pc = OMP_CLAUSE_CHAIN (*pc);
+ continue;
+ }
+ pc = &OMP_CLAUSE_CHAIN (*pc);
+ }
+
+ if (map_seen != 3)
+ {
+ if (map_seen == 0)
+ error_at (pragma_tok->location,
+ "%<#pragma omp target data%> must contain at least "
+ "one %<map%> clause");
+ return NULL_TREE;
+ }
+
tree stmt = make_node (OMP_TARGET_DATA);
TREE_TYPE (stmt) = void_type_node;
+ OMP_TARGET_DATA_CLAUSES (stmt) = clauses;
- OMP_TARGET_DATA_CLAUSES (stmt)
- = cp_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
- "#pragma omp target data", pragma_tok);
keep_next_level (true);
OMP_TARGET_DATA_BODY (stmt) = cp_parser_omp_structured_block (parser);
@@ -32869,6 +33764,180 @@ cp_parser_omp_target_data (cp_parser *parser, cp_token *pragma_tok)
return add_stmt (stmt);
}
+/* OpenMP 4.5:
+ # pragma omp target enter data target-enter-data-clause[optseq] new-line
+ structured-block */
+
+#define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
+ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
+
+static tree
+cp_parser_omp_target_enter_data (cp_parser *parser, cp_token *pragma_tok,
+ enum pragma_context context)
+{
+ bool data_seen = false;
+ 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, "data") == 0)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ data_seen = true;
+ }
+ }
+ if (!data_seen)
+ {
+ cp_parser_error (parser, "expected %<data%>");
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ return NULL_TREE;
+ }
+
+ if (context == pragma_stmt)
+ {
+ error_at (pragma_tok->location,
+ "%<#pragma omp target enter data%> may only be "
+ "used in compound statements");
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ return NULL_TREE;
+ }
+
+ tree clauses
+ = cp_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK,
+ "#pragma omp target enter data", pragma_tok);
+ int map_seen = 0;
+ for (tree *pc = &clauses; *pc;)
+ {
+ if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
+ switch (OMP_CLAUSE_MAP_KIND (*pc))
+ {
+ case GOMP_MAP_TO:
+ case GOMP_MAP_ALWAYS_TO:
+ case GOMP_MAP_ALLOC:
+ map_seen = 3;
+ break;
+ case GOMP_MAP_FIRSTPRIVATE_POINTER:
+ break;
+ default:
+ map_seen |= 1;
+ error_at (OMP_CLAUSE_LOCATION (*pc),
+ "%<#pragma omp target enter data%> with map-type other "
+ "than %<to%> or %<alloc%> on %<map%> clause");
+ *pc = OMP_CLAUSE_CHAIN (*pc);
+ continue;
+ }
+ pc = &OMP_CLAUSE_CHAIN (*pc);
+ }
+
+ if (map_seen != 3)
+ {
+ if (map_seen == 0)
+ error_at (pragma_tok->location,
+ "%<#pragma omp target enter data%> must contain at least "
+ "one %<map%> clause");
+ return NULL_TREE;
+ }
+
+ tree stmt = make_node (OMP_TARGET_ENTER_DATA);
+ TREE_TYPE (stmt) = void_type_node;
+ OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses;
+ SET_EXPR_LOCATION (stmt, pragma_tok->location);
+ return add_stmt (stmt);
+}
+
+/* OpenMP 4.5:
+ # pragma omp target exit data target-enter-data-clause[optseq] new-line
+ structured-block */
+
+#define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
+ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
+
+static tree
+cp_parser_omp_target_exit_data (cp_parser *parser, cp_token *pragma_tok,
+ enum pragma_context context)
+{
+ bool data_seen = false;
+ 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, "data") == 0)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ data_seen = true;
+ }
+ }
+ if (!data_seen)
+ {
+ cp_parser_error (parser, "expected %<data%>");
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ return NULL_TREE;
+ }
+
+ if (context == pragma_stmt)
+ {
+ error_at (pragma_tok->location,
+ "%<#pragma omp target exit data%> may only be "
+ "used in compound statements");
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ return NULL_TREE;
+ }
+
+ tree clauses
+ = cp_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK,
+ "#pragma omp target exit data", pragma_tok);
+ int map_seen = 0;
+ for (tree *pc = &clauses; *pc;)
+ {
+ if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
+ switch (OMP_CLAUSE_MAP_KIND (*pc))
+ {
+ case GOMP_MAP_FROM:
+ case GOMP_MAP_ALWAYS_FROM:
+ case GOMP_MAP_RELEASE:
+ case GOMP_MAP_DELETE:
+ map_seen = 3;
+ break;
+ case GOMP_MAP_FIRSTPRIVATE_POINTER:
+ break;
+ default:
+ map_seen |= 1;
+ error_at (OMP_CLAUSE_LOCATION (*pc),
+ "%<#pragma omp target exit data%> with map-type other "
+ "than %<from%>, %<release%> or %<delete%> on %<map%>"
+ " clause");
+ *pc = OMP_CLAUSE_CHAIN (*pc);
+ continue;
+ }
+ pc = &OMP_CLAUSE_CHAIN (*pc);
+ }
+
+ if (map_seen != 3)
+ {
+ if (map_seen == 0)
+ error_at (pragma_tok->location,
+ "%<#pragma omp target exit data%> must contain at least "
+ "one %<map%> clause");
+ return NULL_TREE;
+ }
+
+ tree stmt = make_node (OMP_TARGET_EXIT_DATA);
+ TREE_TYPE (stmt) = void_type_node;
+ OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses;
+ SET_EXPR_LOCATION (stmt, pragma_tok->location);
+ return add_stmt (stmt);
+}
+
/* OpenMP 4.0:
# pragma omp target update target-update-clause[optseq] new-line */
@@ -32876,7 +33945,9 @@ cp_parser_omp_target_data (cp_parser *parser, cp_token *pragma_tok)
( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
- | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
static bool
cp_parser_omp_target_update (cp_parser *parser, cp_token *pragma_tok,
@@ -32918,12 +33989,20 @@ cp_parser_omp_target_update (cp_parser *parser, cp_token *pragma_tok,
#define OMP_TARGET_CLAUSE_MASK \
( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
- | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR))
static bool
cp_parser_omp_target (cp_parser *parser, cp_token *pragma_tok,
enum pragma_context context)
{
+ tree *pc = NULL, stmt;
+
if (context != pragma_stmt && context != pragma_compound)
{
cp_parser_error (parser, "expected declaration specifiers");
@@ -32935,8 +34014,15 @@ cp_parser_omp_target (cp_parser *parser, cp_token *pragma_tok,
{
tree id = cp_lexer_peek_token (parser->lexer)->u.value;
const char *p = IDENTIFIER_POINTER (id);
+ enum tree_code ccode = ERROR_MARK;
if (strcmp (p, "teams") == 0)
+ ccode = OMP_TEAMS;
+ else if (strcmp (p, "parallel") == 0)
+ ccode = OMP_PARALLEL;
+ else if (strcmp (p, "simd") == 0)
+ ccode = OMP_SIMD;
+ if (ccode != ERROR_MARK)
{
tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT];
char p_name[sizeof ("#pragma omp target teams distribute "
@@ -32946,16 +34032,49 @@ cp_parser_omp_target (cp_parser *parser, cp_token *pragma_tok,
strcpy (p_name, "#pragma omp target");
if (!flag_openmp) /* flag_openmp_simd */
{
- tree stmt = cp_parser_omp_teams (parser, pragma_tok, p_name,
- OMP_TARGET_CLAUSE_MASK,
- cclauses);
+ tree stmt;
+ switch (ccode)
+ {
+ case OMP_TEAMS:
+ stmt = cp_parser_omp_teams (parser, pragma_tok, p_name,
+ OMP_TARGET_CLAUSE_MASK,
+ cclauses);
+ break;
+ case OMP_PARALLEL:
+ stmt = cp_parser_omp_parallel (parser, pragma_tok, p_name,
+ OMP_TARGET_CLAUSE_MASK,
+ cclauses);
+ break;
+ case OMP_SIMD:
+ stmt = cp_parser_omp_simd (parser, pragma_tok, p_name,
+ OMP_TARGET_CLAUSE_MASK,
+ cclauses);
+ break;
+ default:
+ gcc_unreachable ();
+ }
return stmt != NULL_TREE;
}
keep_next_level (true);
- tree sb = begin_omp_structured_block ();
+ tree sb = begin_omp_structured_block (), ret;
unsigned save = cp_parser_begin_omp_structured_block (parser);
- tree ret = cp_parser_omp_teams (parser, pragma_tok, p_name,
- OMP_TARGET_CLAUSE_MASK, cclauses);
+ switch (ccode)
+ {
+ case OMP_TEAMS:
+ ret = cp_parser_omp_teams (parser, pragma_tok, p_name,
+ OMP_TARGET_CLAUSE_MASK, cclauses);
+ break;
+ case OMP_PARALLEL:
+ ret = cp_parser_omp_parallel (parser, pragma_tok, p_name,
+ OMP_TARGET_CLAUSE_MASK, cclauses);
+ break;
+ case OMP_SIMD:
+ ret = cp_parser_omp_simd (parser, pragma_tok, p_name,
+ OMP_TARGET_CLAUSE_MASK, cclauses);
+ break;
+ default:
+ gcc_unreachable ();
+ }
cp_parser_end_omp_structured_block (parser, save);
tree body = finish_omp_structured_block (sb);
if (ret == NULL_TREE)
@@ -32964,8 +34083,10 @@ cp_parser_omp_target (cp_parser *parser, cp_token *pragma_tok,
TREE_TYPE (stmt) = void_type_node;
OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
OMP_TARGET_BODY (stmt) = body;
+ OMP_TARGET_COMBINED (stmt) = 1;
add_stmt (stmt);
- return true;
+ pc = &OMP_TARGET_CLAUSES (stmt);
+ goto check_clauses;
}
else if (!flag_openmp) /* flag_openmp_simd */
{
@@ -32978,6 +34099,18 @@ cp_parser_omp_target (cp_parser *parser, cp_token *pragma_tok,
cp_parser_omp_target_data (parser, pragma_tok);
return true;
}
+ else if (strcmp (p, "enter") == 0)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ cp_parser_omp_target_enter_data (parser, pragma_tok, context);
+ return false;
+ }
+ else if (strcmp (p, "exit") == 0)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ cp_parser_omp_target_exit_data (parser, pragma_tok, context);
+ return false;
+ }
else if (strcmp (p, "update") == 0)
{
cp_lexer_consume_token (parser->lexer);
@@ -32985,17 +34118,44 @@ cp_parser_omp_target (cp_parser *parser, cp_token *pragma_tok,
}
}
- tree stmt = make_node (OMP_TARGET);
+ stmt = make_node (OMP_TARGET);
TREE_TYPE (stmt) = void_type_node;
OMP_TARGET_CLAUSES (stmt)
= cp_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK,
"#pragma omp target", pragma_tok);
+ pc = &OMP_TARGET_CLAUSES (stmt);
keep_next_level (true);
OMP_TARGET_BODY (stmt) = cp_parser_omp_structured_block (parser);
SET_EXPR_LOCATION (stmt, pragma_tok->location);
add_stmt (stmt);
+
+check_clauses:
+ while (*pc)
+ {
+ if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
+ switch (OMP_CLAUSE_MAP_KIND (*pc))
+ {
+ case GOMP_MAP_TO:
+ case GOMP_MAP_ALWAYS_TO:
+ case GOMP_MAP_FROM:
+ case GOMP_MAP_ALWAYS_FROM:
+ case GOMP_MAP_TOFROM:
+ case GOMP_MAP_ALWAYS_TOFROM:
+ case GOMP_MAP_ALLOC:
+ case GOMP_MAP_FIRSTPRIVATE_POINTER:
+ break;
+ default:
+ error_at (OMP_CLAUSE_LOCATION (*pc),
+ "%<#pragma omp target%> with map-type other "
+ "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
+ "on %<map%> clause");
+ *pc = OMP_CLAUSE_CHAIN (*pc);
+ continue;
+ }
+ pc = &OMP_CLAUSE_CHAIN (*pc);
+ }
return true;
}
@@ -33009,7 +34169,7 @@ cp_parser_oacc_cache (cp_parser *parser, cp_token *pragma_tok)
tree stmt, clauses;
clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE__CACHE_, NULL_TREE);
- clauses = finish_omp_clauses (clauses);
+ clauses = finish_omp_clauses (clauses, false);
cp_parser_require_pragma_eol (parser, cp_lexer_peek_token (parser->lexer));
@@ -33463,13 +34623,65 @@ cp_parser_late_parsing_omp_declare_simd (cp_parser *parser, tree attrs)
/* OpenMP 4.0:
# pragma omp declare target new-line
declarations and definitions
- # pragma omp end declare target new-line */
+ # pragma omp end declare target new-line
+
+ OpenMP 4.5:
+ # pragma omp declare target ( extended-list ) new-line
+
+ # pragma omp declare target declare-target-clauses[seq] new-line */
+
+#define OMP_DECLARE_TARGET_CLAUSE_MASK \
+ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK))
static void
cp_parser_omp_declare_target (cp_parser *parser, cp_token *pragma_tok)
{
- cp_parser_skip_to_pragma_eol (parser, pragma_tok);
- scope_chain->omp_declare_target_attribute++;
+ tree clauses = NULL_TREE;
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ clauses
+ = cp_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
+ "#pragma omp declare target", pragma_tok);
+ else if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
+ {
+ clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_TO_DECLARE,
+ clauses);
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ }
+ else
+ {
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ scope_chain->omp_declare_target_attribute++;
+ return;
+ }
+ if (scope_chain->omp_declare_target_attribute)
+ error_at (pragma_tok->location,
+ "%<#pragma omp declare target%> with clauses in between "
+ "%<#pragma omp declare target%> without clauses and "
+ "%<#pragma omp end declare target%>");
+ for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
+ {
+ tree t = OMP_CLAUSE_DECL (c), id;
+ tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
+ tree at2 = lookup_attribute ("omp declare target link",
+ DECL_ATTRIBUTES (t));
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
+ {
+ id = get_identifier ("omp declare target link");
+ std::swap (at1, at2);
+ }
+ else
+ id = get_identifier ("omp declare target");
+ if (at2)
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qD specified both in declare target %<link%> and %<to%>"
+ " clauses", t);
+ continue;
+ }
+ if (!at1)
+ DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
+ }
}
static void
@@ -33957,6 +35169,97 @@ cp_parser_omp_declare (cp_parser *parser, cp_token *pragma_tok,
cp_parser_require_pragma_eol (parser, pragma_tok);
}
+/* OpenMP 4.5:
+ #pragma omp taskloop taskloop-clause[optseq] new-line
+ for-loop
+
+ #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
+ for-loop */
+
+#define OMP_TASKLOOP_CLAUSE_MASK \
+ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY))
+
+static tree
+cp_parser_omp_taskloop (cp_parser *parser, cp_token *pragma_tok,
+ char *p_name, omp_clause_mask mask, tree *cclauses)
+{
+ tree clauses, sb, ret;
+ unsigned int save;
+ location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+
+ strcat (p_name, " taskloop");
+ mask |= OMP_TASKLOOP_CLAUSE_MASK;
+
+ 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, "simd") == 0)
+ {
+ tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
+ if (cclauses == NULL)
+ cclauses = cclauses_buf;
+
+ cp_lexer_consume_token (parser->lexer);
+ if (!flag_openmp) /* flag_openmp_simd */
+ return cp_parser_omp_simd (parser, pragma_tok, p_name, mask,
+ cclauses);
+ sb = begin_omp_structured_block ();
+ save = cp_parser_begin_omp_structured_block (parser);
+ ret = cp_parser_omp_simd (parser, pragma_tok, p_name, mask,
+ cclauses);
+ cp_parser_end_omp_structured_block (parser, save);
+ tree body = finish_omp_structured_block (sb);
+ if (ret == NULL)
+ return ret;
+ ret = make_node (OMP_TASKLOOP);
+ TREE_TYPE (ret) = void_type_node;
+ OMP_FOR_BODY (ret) = body;
+ OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
+ SET_EXPR_LOCATION (ret, loc);
+ add_stmt (ret);
+ return ret;
+ }
+ }
+ if (!flag_openmp) /* flag_openmp_simd */
+ {
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ return NULL_TREE;
+ }
+
+ clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
+ cclauses == NULL);
+ if (cclauses)
+ {
+ cp_omp_split_clauses (loc, OMP_TASKLOOP, mask, clauses, cclauses);
+ clauses = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
+ }
+
+ sb = begin_omp_structured_block ();
+ save = cp_parser_begin_omp_structured_block (parser);
+
+ ret = cp_parser_omp_for_loop (parser, OMP_TASKLOOP, clauses, cclauses);
+
+ cp_parser_end_omp_structured_block (parser, save);
+ add_stmt (finish_omp_structured_block (sb));
+
+ return ret;
+}
+
/* Main entry point to OpenMP statement pragmas. */
static void
@@ -34012,9 +35315,6 @@ cp_parser_omp_construct (cp_parser *parser, cp_token *pragma_tok)
case PRAGMA_OMP_MASTER:
stmt = cp_parser_omp_master (parser, pragma_tok);
break;
- case PRAGMA_OMP_ORDERED:
- stmt = cp_parser_omp_ordered (parser, pragma_tok);
- break;
case PRAGMA_OMP_PARALLEL:
strcpy (p_name, "#pragma omp");
stmt = cp_parser_omp_parallel (parser, pragma_tok, p_name, mask, NULL);
@@ -34036,6 +35336,10 @@ cp_parser_omp_construct (cp_parser *parser, cp_token *pragma_tok)
case PRAGMA_OMP_TASKGROUP:
stmt = cp_parser_omp_taskgroup (parser, pragma_tok);
break;
+ case PRAGMA_OMP_TASKLOOP:
+ strcpy (p_name, "#pragma omp");
+ stmt = cp_parser_omp_taskloop (parser, pragma_tok, p_name, mask, NULL);
+ break;
case PRAGMA_OMP_TEAMS:
strcpy (p_name, "#pragma omp");
stmt = cp_parser_omp_teams (parser, pragma_tok, p_name, mask, NULL);
@@ -34424,6 +35728,8 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context)
{
cp_token *pragma_tok;
unsigned int id;
+ tree stmt;
+ bool ret;
pragma_tok = cp_lexer_consume_token (parser->lexer);
gcc_assert (pragma_tok->type == CPP_PRAGMA);
@@ -34555,21 +35861,32 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context)
case PRAGMA_OMP_DISTRIBUTE:
case PRAGMA_OMP_FOR:
case PRAGMA_OMP_MASTER:
- case PRAGMA_OMP_ORDERED:
case PRAGMA_OMP_PARALLEL:
case PRAGMA_OMP_SECTIONS:
case PRAGMA_OMP_SIMD:
case PRAGMA_OMP_SINGLE:
case PRAGMA_OMP_TASK:
case PRAGMA_OMP_TASKGROUP:
+ case PRAGMA_OMP_TASKLOOP:
case PRAGMA_OMP_TEAMS:
if (context != pragma_stmt && context != pragma_compound)
goto bad_stmt;
+ stmt = push_omp_privatization_clauses (false);
cp_parser_omp_construct (parser, pragma_tok);
+ pop_omp_privatization_clauses (stmt);
return true;
+ case PRAGMA_OMP_ORDERED:
+ stmt = push_omp_privatization_clauses (false);
+ ret = cp_parser_omp_ordered (parser, pragma_tok, context);
+ pop_omp_privatization_clauses (stmt);
+ return ret;
+
case PRAGMA_OMP_TARGET:
- return cp_parser_omp_target (parser, pragma_tok, context);
+ stmt = push_omp_privatization_clauses (false);
+ ret = cp_parser_omp_target (parser, pragma_tok, context);
+ pop_omp_privatization_clauses (stmt);
+ return ret;
case PRAGMA_OMP_END_DECLARE_TARGET:
cp_parser_omp_end_declare_target (parser, pragma_tok);
@@ -34610,7 +35927,9 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context)
"%<#pragma simd%> must be inside a function");
break;
}
+ stmt = push_omp_privatization_clauses (false);
cp_parser_cilk_simd (parser, pragma_tok);
+ pop_omp_privatization_clauses (stmt);
return true;
case PRAGMA_CILK_GRAINSIZE:
@@ -34990,7 +36309,7 @@ cp_parser_cilk_for (cp_parser *parser, tree grain)
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);
+ clauses = finish_omp_clauses (clauses, false);
tree ret = cp_parser_omp_for_loop (parser, CILK_FOR, clauses, NULL);
if (ret)