aboutsummaryrefslogtreecommitdiff
path: root/gcc/c/c-parser.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/c/c-parser.cc')
-rw-r--r--gcc/c/c-parser.cc102
1 files changed, 89 insertions, 13 deletions
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index 134d3ed..703f957 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -14598,6 +14598,8 @@ c_parser_omp_clause_name (c_parser *parser)
result = PRAGMA_OMP_CLAUSE_IN_REDUCTION;
else if (!strcmp ("inbranch", p))
result = PRAGMA_OMP_CLAUSE_INBRANCH;
+ else if (!strcmp ("indirect", p))
+ result = PRAGMA_OMP_CLAUSE_INDIRECT;
else if (!strcmp ("independent", p))
result = PRAGMA_OACC_CLAUSE_INDEPENDENT;
else if (!strcmp ("is_device_ptr", p))
@@ -15474,6 +15476,47 @@ c_parser_omp_clause_final (c_parser *parser, tree list)
return list;
}
+/* OpenMP 5.1:
+ indirect [( expression )]
+*/
+
+static tree
+c_parser_omp_clause_indirect (c_parser *parser, tree list)
+{
+ location_t location = c_parser_peek_token (parser)->location;
+ tree t;
+
+ if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
+ {
+ matching_parens parens;
+ if (!parens.require_open (parser))
+ return list;
+
+ location_t loc = c_parser_peek_token (parser)->location;
+ c_expr expr = c_parser_expr_no_commas (parser, NULL);
+ expr = convert_lvalue_to_rvalue (loc, expr, true, true);
+ t = c_objc_common_truthvalue_conversion (loc, expr.value);
+ t = c_fully_fold (t, false, NULL);
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
+ || TREE_CODE (t) != INTEGER_CST)
+ {
+ c_parser_error (parser, "expected constant logical expression");
+ return list;
+ }
+ parens.skip_until_found_close (parser);
+ }
+ else
+ t = integer_one_node;
+
+ check_no_duplicate_clause (list, OMP_CLAUSE_INDIRECT, "indirect");
+
+ tree c = build_omp_clause (location, OMP_CLAUSE_INDIRECT);
+ OMP_CLAUSE_INDIRECT_EXPR (c) = t;
+ OMP_CLAUSE_CHAIN (c) = list;
+
+ return c;
+}
+
/* OpenACC, OpenMP 2.5:
if ( expression )
@@ -19035,6 +19078,10 @@ c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
true, clauses);
c_name = "in_reduction";
break;
+ case PRAGMA_OMP_CLAUSE_INDIRECT:
+ clauses = c_parser_omp_clause_indirect (parser, clauses);
+ c_name = "indirect";
+ break;
case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
clauses = c_parser_omp_clause_lastprivate (parser, clauses);
c_name = "lastprivate";
@@ -24608,14 +24655,16 @@ c_maybe_parse_omp_decl (tree decl, tree d)
( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ENTER) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
- | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INDIRECT))
static void
c_parser_omp_declare_target (c_parser *parser)
{
tree clauses = NULL_TREE;
int device_type = 0;
- bool only_device_type = true;
+ bool indirect = false;
+ bool only_device_type_or_indirect = true;
if (c_parser_next_token_is (parser, CPP_NAME)
|| (c_parser_next_token_is (parser, CPP_COMMA)
&& c_parser_peek_2nd_token (parser)->type == CPP_NAME))
@@ -24633,22 +24682,27 @@ c_parser_omp_declare_target (c_parser *parser)
{
bool attr_syntax = parser->in_omp_attribute_pragma != NULL;
c_parser_skip_to_pragma_eol (parser);
- c_omp_declare_target_attr attr = { attr_syntax, -1 };
+ c_omp_declare_target_attr attr = { attr_syntax, -1, 0 };
vec_safe_push (current_omp_declare_target_attribute, attr);
return;
}
for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
- if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
- device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
- for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
{
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
+ device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INDIRECT)
+ indirect |= !integer_zerop (OMP_CLAUSE_INDIRECT_EXPR (c));
+ }
+ for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
+ {
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE
+ || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INDIRECT)
continue;
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));
- only_device_type = false;
+ only_device_type_or_indirect = false;
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
{
id = get_identifier ("omp declare target link");
@@ -24710,10 +24764,25 @@ c_parser_omp_declare_target (c_parser *parser)
= tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
}
}
+ if (indirect)
+ {
+ tree at4 = lookup_attribute ("omp declare target indirect",
+ DECL_ATTRIBUTES (t));
+ if (at4 == NULL_TREE)
+ {
+ id = get_identifier ("omp declare target indirect");
+ DECL_ATTRIBUTES (t)
+ = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
+ }
+ }
}
- if (device_type && only_device_type)
+ if ((device_type || indirect) && only_device_type_or_indirect)
error_at (OMP_CLAUSE_LOCATION (clauses),
- "directive with only %<device_type%> clause");
+ "directive with only %<device_type%> or %<indirect%> clauses");
+ if (indirect && device_type && device_type != OMP_CLAUSE_DEVICE_TYPE_ANY)
+ error_at (OMP_CLAUSE_LOCATION (clauses),
+ "%<device_type%> clause must specify 'any' when used with "
+ "an %<indirect%> clause");
}
/* OpenMP 5.1
@@ -24722,7 +24791,8 @@ c_parser_omp_declare_target (c_parser *parser)
#pragma omp begin declare target clauses[optseq] new-line */
#define OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK \
- (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE)
+ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INDIRECT))
static void
c_parser_omp_begin (c_parser *parser)
@@ -24746,10 +24816,16 @@ c_parser_omp_begin (c_parser *parser)
OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK,
"#pragma omp begin declare target");
int device_type = 0;
+ int indirect = 0;
for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
- if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
- device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
- c_omp_declare_target_attr attr = { attr_syntax, device_type };
+ {
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
+ device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INDIRECT)
+ indirect |= !integer_zerop (OMP_CLAUSE_INDIRECT_EXPR (c));
+ }
+ c_omp_declare_target_attr attr = { attr_syntax, device_type,
+ indirect };
vec_safe_push (current_omp_declare_target_attribute, attr);
}
else