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" }

Reply via email to