This patch is the C++ changes matching the C ones of patch 4. In
finish_omp_clauses, the gang, worker, & vector clauses are handled the same as
OpenMP's 'num_threads' clause. One change to num_threads is the augmentation of
a diagnostic to add %<...%> markers to the clause name.
nathan
2015-10-20 Cesar Philippidis <ce...@codesourcery.com>
Thomas Schwinge <tho...@codesourcery.com>
James Norris <jnor...@codesourcery.com>
Joseph Myers <jos...@codesourcery.com>
Julian Brown <jul...@codesourcery.com>
Nathan Sidwell <nat...@codesourcery.com>
* parser.c (cp_parser_omp_clause_name): Add auto, gang, seq,
vector, worker.
(cp_parser_oacc_simple_clause): New.
(cp_parser_oacc_shape_clause): New.
(cp_parser_oacc_all_clauses): Add auto, gang, seq, vector, worker.
(OACC_LOOP_CLAUSE_MASK): Likewise.
* semantics.c (finish_omp_clauses): Add auto, gang, seq, vector,
worker.
2015-10-20 Nathan Sidwell <nat...@codesourcery.com>
gcc/testsuite/
* g++.dg/g++.dg/gomp/pr33372-1.C: Adjust diagnostic.
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c (revision 228969)
+++ gcc/cp/parser.c (working copy)
@@ -29058,7 +29058,9 @@ cp_parser_omp_clause_name (cp_parser *pa
{
pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;
- if (cp_lexer_next_token_is_keyword (parser->lexer, RID_IF))
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_AUTO))
+ result = PRAGMA_OACC_CLAUSE_AUTO;
+ else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_IF))
result = PRAGMA_OMP_CLAUSE_IF;
else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_DEFAULT))
result = PRAGMA_OMP_CLAUSE_DEFAULT;
@@ -29116,7 +29118,9 @@ cp_parser_omp_clause_name (cp_parser *pa
result = PRAGMA_OMP_CLAUSE_FROM;
break;
case 'g':
- if (!strcmp ("grainsize", p))
+ if (!strcmp ("gang", p))
+ result = PRAGMA_OACC_CLAUSE_GANG;
+ else if (!strcmp ("grainsize", p))
result = PRAGMA_OMP_CLAUSE_GRAINSIZE;
break;
case 'h':
@@ -29206,6 +29210,8 @@ cp_parser_omp_clause_name (cp_parser *pa
result = PRAGMA_OMP_CLAUSE_SECTIONS;
else if (!strcmp ("self", p))
result = PRAGMA_OACC_CLAUSE_SELF;
+ else if (!strcmp ("seq", p))
+ result = PRAGMA_OACC_CLAUSE_SEQ;
else if (!strcmp ("shared", p))
result = PRAGMA_OMP_CLAUSE_SHARED;
else if (!strcmp ("simd", p))
@@ -29232,7 +29238,9 @@ cp_parser_omp_clause_name (cp_parser *pa
result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR;
break;
case 'v':
- if (!strcmp ("vector_length", p))
+ if (!strcmp ("vector", p))
+ result = PRAGMA_OACC_CLAUSE_VECTOR;
+ else if (!strcmp ("vector_length", p))
result = PRAGMA_OACC_CLAUSE_VECTOR_LENGTH;
else if (flag_cilkplus && !strcmp ("vectorlength", p))
result = PRAGMA_CILK_CLAUSE_VECTORLENGTH;
@@ -29240,6 +29248,8 @@ cp_parser_omp_clause_name (cp_parser *pa
case 'w':
if (!strcmp ("wait", p))
result = PRAGMA_OACC_CLAUSE_WAIT;
+ else if (!strcmp ("worker", p))
+ result = PRAGMA_OACC_CLAUSE_WORKER;
break;
}
}
@@ -29576,6 +29586,160 @@ cp_parser_oacc_data_clause_deviceptr (cp
return list;
}
+/* OpenACC 2.0:
+ auto
+ independent
+ nohost
+ seq */
+
+static tree
+cp_parser_oacc_simple_clause (cp_parser *ARG_UNUSED (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;
+}
+
+/* OpenACC:
+ gang [( gang_expr_list )]
+ worker [( expression )]
+ vector [( expression )] */
+
+static tree
+cp_parser_oacc_shape_clause (cp_parser *parser, pragma_omp_clause c_kind,
+ const char *str, tree list)
+{
+ omp_clause_code kind;
+ const char *id = "num";
+ cp_lexer *lexer = parser->lexer;
+
+ switch (c_kind)
+ {
+ default:
+ gcc_unreachable ();
+ case PRAGMA_OACC_CLAUSE_GANG:
+ kind = OMP_CLAUSE_GANG;
+ break;
+ case PRAGMA_OACC_CLAUSE_VECTOR:
+ kind = OMP_CLAUSE_VECTOR;
+ id = "length";
+ break;
+ case PRAGMA_OACC_CLAUSE_WORKER:
+ kind = OMP_CLAUSE_WORKER;
+ break;
+ }
+
+ tree op0 = NULL_TREE, op1 = NULL_TREE;
+ location_t loc = cp_lexer_peek_token (lexer)->location;
+
+ if (cp_lexer_next_token_is (lexer, CPP_OPEN_PAREN))
+ {
+ tree *op_to_parse = &op0;
+ cp_lexer_consume_token (lexer);
+
+ do
+ {
+ if (cp_lexer_next_token_is (lexer, CPP_NAME)
+ || cp_lexer_next_token_is (lexer, CPP_KEYWORD))
+ {
+ tree name_kind = cp_lexer_peek_token (lexer)->u.value;
+ const char *p = IDENTIFIER_POINTER (name_kind);
+ if (kind == OMP_CLAUSE_GANG && strcmp ("static", p) == 0)
+ {
+ cp_lexer_consume_token (lexer);
+ if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
+ {
+ cp_parser_skip_to_closing_parenthesis (parser, false,
+ false, true);
+ return list;
+ }
+ op_to_parse = &op1;
+ if (cp_lexer_next_token_is (lexer, CPP_MULT))
+ {
+ if (*op_to_parse != NULL_TREE)
+ {
+ cp_parser_error (parser,
+ "duplicate %<num%> argument");
+ cp_parser_skip_to_closing_parenthesis (parser,
+ false, false,
+ true);
+ return list;
+ }
+ cp_lexer_consume_token (lexer);
+ *op_to_parse = integer_minus_one_node;
+ if (cp_lexer_next_token_is (lexer, CPP_COMMA))
+ cp_lexer_consume_token (lexer);
+ continue;
+ }
+ }
+ else if (strcmp (id, p) == 0)
+ {
+ op_to_parse = &op0;
+ cp_lexer_consume_token (lexer);
+ if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
+ {
+ cp_parser_skip_to_closing_parenthesis (parser, false,
+ false, true);
+ return list;
+ }
+ }
+ else
+ {
+ if (kind == OMP_CLAUSE_GANG)
+ cp_parser_error (parser,
+ "expected %<%num%> or %<static%>");
+ else if (kind == OMP_CLAUSE_VECTOR)
+ cp_parser_error (parser, "expected %<length%>");
+ else
+ cp_parser_error (parser, "expected %<num%>");
+ cp_parser_skip_to_closing_parenthesis (parser, false, false,
+ true);
+ return list;
+ }
+ }
+
+ if (*op_to_parse != NULL_TREE)
+ {
+ cp_parser_error (parser, "duplicate operand to clause");
+ cp_parser_skip_to_closing_parenthesis (parser, false, false,
+ true);
+ return list;
+ }
+
+ tree expr = cp_parser_assignment_expression (parser, NULL, false,
+ false);
+ if (expr == error_mark_node)
+ {
+ cp_parser_skip_to_closing_parenthesis (parser, false, false,
+ true);
+ return list;
+ }
+
+ mark_exp_read (expr);
+ *op_to_parse = expr;
+ op_to_parse = &op0;
+
+ if (cp_lexer_next_token_is (lexer, CPP_COMMA))
+ cp_lexer_consume_token (lexer);
+ }
+ while (!cp_lexer_next_token_is (lexer, CPP_CLOSE_PAREN));
+ cp_lexer_consume_token (lexer);
+ }
+
+ check_no_duplicate_clause (list, kind, str, loc);
+
+ tree c = build_omp_clause (loc, kind);
+ if (op0)
+ OMP_CLAUSE_OPERAND (c, 0) = op0;
+ if (op1)
+ OMP_CLAUSE_OPERAND (c, 1) = op1;
+ OMP_CLAUSE_CHAIN (c) = list;
+ return c;
+}
+
/* OpenACC:
vector_length ( expression ) */
@@ -31300,6 +31464,11 @@ cp_parser_oacc_all_clauses (cp_parser *p
clauses = cp_parser_oacc_clause_async (parser, clauses);
c_name = "async";
break;
+ case PRAGMA_OACC_CLAUSE_AUTO:
+ clauses = cp_parser_oacc_simple_clause (parser, OMP_CLAUSE_AUTO,
+ clauses, here);
+ c_name = "auto";
+ break;
case PRAGMA_OACC_CLAUSE_COLLAPSE:
clauses = cp_parser_omp_clause_collapse (parser, clauses, here);
c_name = "collapse";
@@ -31332,6 +31501,11 @@ cp_parser_oacc_all_clauses (cp_parser *p
clauses = cp_parser_oacc_data_clause_deviceptr (parser, clauses);
c_name = "deviceptr";
break;
+ case PRAGMA_OACC_CLAUSE_GANG:
+ c_name = "gang";
+ clauses = cp_parser_oacc_shape_clause (parser, c_kind, c_name,
+ clauses);
+ break;
case PRAGMA_OACC_CLAUSE_HOST:
clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
c_name = "host";
@@ -31376,6 +31550,16 @@ cp_parser_oacc_all_clauses (cp_parser *p
clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
c_name = "self";
break;
+ case PRAGMA_OACC_CLAUSE_SEQ:
+ clauses = cp_parser_oacc_simple_clause (parser, OMP_CLAUSE_SEQ,
+ clauses, here);
+ c_name = "seq";
+ break;
+ case PRAGMA_OACC_CLAUSE_VECTOR:
+ c_name = "vector";
+ clauses = cp_parser_oacc_shape_clause (parser, c_kind, c_name,
+ clauses);
+ break;
case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH:
clauses = cp_parser_oacc_clause_vector_length (parser, clauses);
c_name = "vector_length";
@@ -31384,6 +31568,11 @@ cp_parser_oacc_all_clauses (cp_parser *p
clauses = cp_parser_oacc_clause_wait (parser, clauses);
c_name = "wait";
break;
+ case PRAGMA_OACC_CLAUSE_WORKER:
+ c_name = "worker";
+ clauses = cp_parser_oacc_shape_clause (parser, c_kind, c_name,
+ clauses);
+ break;
default:
cp_parser_error (parser, "expected %<#pragma acc%> clause");
goto saw_error;
@@ -34333,6 +34522,11 @@ cp_parser_oacc_kernels (cp_parser *parse
#define OACC_LOOP_CLAUSE_MASK \
( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION))
static tree
Index: gcc/cp/semantics.c
===================================================================
--- gcc/cp/semantics.c (revision 228969)
+++ gcc/cp/semantics.c (working copy)
@@ -5904,6 +5904,37 @@ finish_omp_clauses (tree clauses, bool a
bitmap_set_bit (&firstprivate_head, DECL_UID (t));
goto handle_field_decl;
+ case OMP_CLAUSE_GANG:
+ case OMP_CLAUSE_VECTOR:
+ case OMP_CLAUSE_WORKER:
+ /* Operand 0 is the num: or length: argument. */
+ t = OMP_CLAUSE_OPERAND (c, 0);
+ if (t == NULL_TREE)
+ break;
+
+ t = maybe_convert_cond (t);
+ if (t == error_mark_node)
+ remove = true;
+ else if (!processing_template_decl)
+ t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ OMP_CLAUSE_OPERAND (c, 0) = t;
+
+ if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_GANG)
+ break;
+
+ /* Ooperand 1 is the gang static: argument. */
+ t = OMP_CLAUSE_OPERAND (c, 1);
+ if (t == NULL_TREE)
+ break;
+
+ t = maybe_convert_cond (t);
+ if (t == error_mark_node)
+ remove = true;
+ else if (!processing_template_decl)
+ t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ OMP_CLAUSE_OPERAND (c, 1) = t;
+ break;
+
case OMP_CLAUSE_LASTPRIVATE:
t = omp_clause_decl_field (OMP_CLAUSE_DECL (c));
if (t)
@@ -5959,32 +5990,58 @@ finish_omp_clauses (tree clauses, bool a
break;
case OMP_CLAUSE_NUM_THREADS:
- t = OMP_CLAUSE_NUM_THREADS_EXPR (c);
- if (t == error_mark_node)
- remove = true;
- else if (!type_dependent_expression_p (t)
- && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
- {
- error ("num_threads expression must be integral");
- remove = true;
- }
- else
- {
- t = mark_rvalue_use (t);
- if (!processing_template_decl)
- {
- t = maybe_constant_value (t);
- if (TREE_CODE (t) == INTEGER_CST
- && tree_int_cst_sgn (t) != 1)
- {
- warning_at (OMP_CLAUSE_LOCATION (c), 0,
- "%<num_threads%> value must be positive");
- t = integer_one_node;
- }
- t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
- }
- OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
- }
+ case OMP_CLAUSE_NUM_GANGS:
+ case OMP_CLAUSE_NUM_WORKERS:
+ case OMP_CLAUSE_VECTOR_LENGTH:
+ {
+ const char *name = NULL;
+
+ switch (OMP_CLAUSE_CODE (c))
+ {
+ case OMP_CLAUSE_NUM_THREADS:
+ name = "num_threads";
+ break;
+ case OMP_CLAUSE_NUM_GANGS:
+ name = "num_gangs";
+ break;
+ case OMP_CLAUSE_NUM_WORKERS:
+ name = "num_workers";
+ break;
+ case OMP_CLAUSE_VECTOR_LENGTH:
+ name = "vector_length";
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ t = OMP_CLAUSE_OPERAND (c, 0);
+ if (t == error_mark_node)
+ remove = true;
+ else if (!type_dependent_expression_p (t)
+ && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%<%s%> expression must be integral", name);
+ remove = true;
+ }
+ else
+ {
+ t = mark_rvalue_use (t);
+ if (!processing_template_decl)
+ {
+ t = maybe_constant_value (t);
+ if (TREE_CODE (t) == INTEGER_CST
+ && tree_int_cst_sgn (t) != 1)
+ {
+ warning_at (OMP_CLAUSE_LOCATION (c), 0,
+ "%<%s%> value must be positive", name);
+ t = integer_one_node;
+ }
+ t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ }
+ OMP_CLAUSE_OPERAND (c, 0) = t;
+ }
+ }
break;
case OMP_CLAUSE_SCHEDULE:
@@ -6103,16 +6160,6 @@ finish_omp_clauses (tree clauses, bool a
}
break;
- case OMP_CLAUSE_VECTOR_LENGTH:
- t = OMP_CLAUSE_VECTOR_LENGTH_EXPR (c);
- t = maybe_convert_cond (t);
- if (t == error_mark_node)
- remove = true;
- else if (!processing_template_decl)
- t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
- OMP_CLAUSE_VECTOR_LENGTH_EXPR (c) = t;
- break;
-
case OMP_CLAUSE_WAIT:
t = OMP_CLAUSE_WAIT_EXPR (c);
if (t == error_mark_node)
@@ -6687,6 +6734,8 @@ finish_omp_clauses (tree clauses, bool a
case OMP_CLAUSE_SIMD:
case OMP_CLAUSE_DEFAULTMAP:
case OMP_CLAUSE__CILK_FOR_COUNT_:
+ case OMP_CLAUSE_AUTO:
+ case OMP_CLAUSE_SEQ:
break;
case OMP_CLAUSE_INBRANCH:
Index: gcc/testsuite/g++.dg/gomp/pr33372-1.C
===================================================================
--- gcc/testsuite/g++.dg/gomp/pr33372-1.C (revision 229101)
+++ gcc/testsuite/g++.dg/gomp/pr33372-1.C (working copy)
@@ -6,7 +6,7 @@ template <typename T>
void f ()
{
extern T n ();
-#pragma omp parallel num_threads(n) // { dg-error "num_threads expression must be integral" }
+#pragma omp parallel num_threads(n) // { dg-error "'num_threads' expression must be integral" }
;
#pragma omp parallel for schedule(static, n)
for (int i = 0; i < 10; i++) // { dg-error "chunk size expression must be integral" }