This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gomp4] Fix up C #pragma omp declare simd parsing


Hi!

This is the C FE counterpart of the
http://gcc.gnu.org/ml/gcc-patches/2013-07/msg00520.html
changes.  The OpenMP 4.0 standard in the end requires that the #pragma omp
declare simd clauses are parsed at the scope of the function parameters,
but lexically comes before the function return type, so we need to remember
it and parse only later.  The C++ FE had support for saving tokens and
parsing them later, but the C FE didn't.

So, while most of the patch is just OpenMP specific stuff, the struct
c_parser, c_parser_consume_{token,pragma} and c_parse_file changes affect
all C users.  I've bootstrapped/regtested just those changes alone
and didn't find measurable differences, both in bootstrap time and on some
larger C sources.  I'll need this support also for #pragma omp declare
reduction parsing later on.

Additionally, while for the function definitions arguments are pushed again
into scope, for function prototypes this doesn't happen, so I had to write
utility functions in c-decl.c to do that temporarily and undo that
afterwards.

Joseph, any comments?

2013-07-20  Jakub Jelinek  <jakub@redhat.com>

	* c-typeck.c (c_finish_omp_declare_simd): Moved to...
	* c-parser.c (c_finish_omp_declare_simd): ... here.  Add
	first c_parser * argument and change last argument to vec<c_token>.
	Parse clauses here from the saved c_tokens.
	(struct c_parser): Change tokens to c_token *.
	Add tokens_buf field.  Change tokens_avail type to unsigned int.
	(c_parser_consume_token): If parser->tokens isn't
	&parser->tokens_buf[0], increment parser->tokens.
	(c_parser_consume_pragma): Likewise
	(c_parser_declaration_or_fndef): Change last argument to vec<c_token>.
	Pass parser as first argument to c_finish_omp_declare_simd.  For
	prototypes, fix code indentation and call temp_store_parm_decls
	and temp_pop_parm_decls around c_finish_omp_declare_simd.
	(c_parser_omp_variable_list): Remove declare_simd argument, call
	lookup_name unconditionally.
	(c_parser_omp_var_list_parens, c_parser_omp_clause_reduction,
	c_parser_omp_clause_depend, c_parser_omp_clause_map,
	c_parser_omp_clause_uniform): Adjust c_parser_omp_variable_list
	callers.
	(c_parser_omp_clause_aligned, c_parser_omp_clause_linear): Likewise.
	Remove declare_simd argument.
	(c_parser_omp_all_clauses): Remove declare_simd argument.  Adjust
	c_parser_omp_clause_aligned and c_parser_omp_clause_linear callers.
	(c_parser_omp_declare_simd): Don't parse declare simd clauses here,
	instead push the clause c_tokens starting with simd token up to
	CPP_PRAGMA_EOL for each #pragma omp declare simd into a vector.
	(c_parser_omp_declare): Don't consume simd token here.
	(c_parse_file): Initialize tparser.tokens and the_parser->tokens here.
	* c-decl.c (temp_store_parm_decls, temp_pop_parm_decls): New
	functions.
	* c-tree.h (temp_store_parm_decls, temp_pop_parm_decls): New
	prototypes.
	(c_finish_omp_declare_simd): Remove prototype.

	* gcc.dg/gomp/declare-simd-1.c (f16, f17, f18): New tests.

--- gcc/c/c-typeck.c.jj	2013-07-14 19:43:18.000000000 +0200
+++ gcc/c/c-typeck.c	2013-07-19 22:30:39.552293476 +0200
@@ -11587,84 +11587,6 @@ c_finish_omp_clauses (tree clauses)
   return clauses;
 }
 
-/* Finalize #pragma omp declare simd clauses after FNDECL has been parsed,
-   and put that into "omp declare simd" attribute.  */
-
-void
-c_finish_omp_declare_simd (tree fndecl, tree parms, vec<tree> clauses)
-{
-  tree cl;
-  int i;
-
-  if (clauses[0] == error_mark_node)
-    return;
-  if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
-    {
-      error ("%<#pragma omp declare simd%> not immediately followed by "
-	     "a function declaration or definition");
-      clauses[0] = error_mark_node;
-      return;
-    }
-  if (clauses[0] == integer_zero_node)
-    {
-      error_at (DECL_SOURCE_LOCATION (fndecl),
-		"%<#pragma omp declare simd%> not immediately followed by "
-		"a single function declaration or definition");
-      clauses[0] = error_mark_node;
-      return;
-    }
-
-  if (parms == NULL_TREE)
-    parms = DECL_ARGUMENTS (fndecl);
-
-  FOR_EACH_VEC_ELT (clauses, i, cl)
-    {
-      tree c, *pc, decl, name;
-      for (pc = &cl, c = cl; c; c = *pc)
-	{
-	  bool remove = false;
-	  switch (OMP_CLAUSE_CODE (c))
-	    {
-	    case OMP_CLAUSE_UNIFORM:
-	    case OMP_CLAUSE_LINEAR:
-	    case OMP_CLAUSE_ALIGNED:
-	    case OMP_CLAUSE_REDUCTION:
-	      name = OMP_CLAUSE_DECL (c);
-	      if (name == error_mark_node)
-		remove = true;
-	      else
-		{
-		  for (decl = parms; decl; decl = TREE_CHAIN (decl))
-		    if (DECL_NAME (decl) == name)
-		      break;
-		  if (decl == NULL_TREE)
-		    {
-		      error_at (OMP_CLAUSE_LOCATION (c),
-				"%qE is not a function parameter", name);
-		      remove = true;
-		    }
-		  else
-		    OMP_CLAUSE_DECL (c) = decl;
-		}
-	      break;
-	    default:
-	      break;
-	    }
-	  if (remove)
-	    *pc = OMP_CLAUSE_CHAIN (c);
-	  else
-	    pc = &OMP_CLAUSE_CHAIN (c);
-	}
-      cl = c_finish_omp_clauses (cl);
-      cl = c_omp_declare_simd_clauses_to_numbers (parms, cl);
-      c = build_tree_list (get_identifier ("omp declare simd"), cl);
-      TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl);
-      DECL_ATTRIBUTES (fndecl) = c;
-    }
-
-  clauses[0] = integer_zero_node;
-}
-
 /* Create a transaction node.  */
 
 tree
--- gcc/c/c-parser.c.jj	2013-07-08 10:08:48.000000000 +0200
+++ gcc/c/c-parser.c	2013-07-20 01:23:38.992911552 +0200
@@ -163,9 +163,12 @@ typedef struct GTY (()) c_token {
    tokens of look-ahead; more are not needed for C.  */
 typedef struct GTY(()) c_parser {
   /* The look-ahead tokens.  */
-  c_token tokens[2];
-  /* How many look-ahead tokens are available (0, 1 or 2).  */
-  short tokens_avail;
+  c_token * GTY((skip)) tokens;
+  /* Buffer for look-ahead tokens.  */
+  c_token tokens_buf[2];
+  /* How many look-ahead tokens are available (0, 1 or 2, or
+     more if parsing from pre-lexed tokens).  */
+  unsigned int tokens_avail;
   /* True if a syntax error is being recovered from; false otherwise.
      c_parser_error sets this flag.  It should clear this flag when
      enough tokens have been consumed to recover from the error.  */
@@ -737,7 +740,9 @@ c_parser_consume_token (c_parser *parser
   gcc_assert (parser->tokens[0].type != CPP_EOF);
   gcc_assert (!parser->in_pragma || parser->tokens[0].type != CPP_PRAGMA_EOL);
   gcc_assert (parser->error || parser->tokens[0].type != CPP_PRAGMA);
-  if (parser->tokens_avail == 2)
+  if (parser->tokens != &parser->tokens_buf[0])
+    parser->tokens++;
+  else if (parser->tokens_avail == 2)
     parser->tokens[0] = parser->tokens[1];
   parser->tokens_avail--;
 }
@@ -751,7 +756,9 @@ c_parser_consume_pragma (c_parser *parse
   gcc_assert (!parser->in_pragma);
   gcc_assert (parser->tokens_avail >= 1);
   gcc_assert (parser->tokens[0].type == CPP_PRAGMA);
-  if (parser->tokens_avail == 2)
+  if (parser->tokens != &parser->tokens_buf[0])
+    parser->tokens++;
+  else if (parser->tokens_avail == 2)
     parser->tokens[0] = parser->tokens[1];
   parser->tokens_avail--;
   parser->in_pragma = true;
@@ -1113,7 +1120,7 @@ enum c_parser_prec {
 static void c_parser_external_declaration (c_parser *);
 static void c_parser_asm_definition (c_parser *);
 static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
-					   bool, bool, tree *, vec<tree>);
+					   bool, bool, tree *, vec<c_token>);
 static void c_parser_static_assert_declaration_no_semi (c_parser *);
 static void c_parser_static_assert_declaration (c_parser *);
 static void c_parser_declspecs (c_parser *, struct c_declspecs *, bool, bool,
@@ -1374,6 +1381,8 @@ c_parser_external_declaration (c_parser
     }
 }
 
+static void c_finish_omp_declare_simd (c_parser *, tree, tree, vec<c_token>);
+
 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
    6.7, 6.9.1).  If FNDEF_OK is true, a function definition is
    accepted; otherwise (old-style parameter declarations) only other
@@ -1450,7 +1459,7 @@ c_parser_declaration_or_fndef (c_parser
 			       bool static_assert_ok, bool empty_ok,
 			       bool nested, bool start_attr_ok,
 			       tree *objc_foreach_object_declaration,
-			       vec<tree> omp_declare_simd_clauses)
+			       vec<c_token> omp_declare_simd_clauses)
 {
   struct c_declspecs *specs;
   tree prefix_attrs;
@@ -1621,7 +1630,7 @@ c_parser_declaration_or_fndef (c_parser
       if (declarator == NULL)
 	{
 	  if (omp_declare_simd_clauses.exists ())
-	    c_finish_omp_declare_simd (NULL_TREE, NULL_TREE,
+	    c_finish_omp_declare_simd (parser, NULL_TREE, NULL_TREE,
 				       omp_declare_simd_clauses);
 	  c_parser_skip_to_end_of_block_or_statement (parser);
 	  return;
@@ -1660,7 +1669,7 @@ c_parser_declaration_or_fndef (c_parser
 	      if (!d)
 		d = error_mark_node;
 	      if (omp_declare_simd_clauses.exists ())
-		c_finish_omp_declare_simd (d, NULL_TREE,
+		c_finish_omp_declare_simd (parser, d, NULL_TREE,
 					   omp_declare_simd_clauses);
 	      start_init (d, asm_name, global_bindings_p ());
 	      init_loc = c_parser_peek_token (parser)->location;
@@ -1684,17 +1693,21 @@ c_parser_declaration_or_fndef (c_parser
 		  if (d && TREE_CODE (d) == FUNCTION_DECL)
 		    {
 		      struct c_declarator *ce = declarator;
-			while (ce != NULL)
-			  if (ce->kind == cdk_function)
-			    {
-			      parms = ce->u.arg_info->parms;
-			      break;
-			    }
-			  else
-			    ce = ce->declarator;
+		      while (ce != NULL)
+			if (ce->kind == cdk_function)
+			  {
+			    parms = ce->u.arg_info->parms;
+			    break;
+			  }
+			else
+			  ce = ce->declarator;
 		    }
-		  c_finish_omp_declare_simd (d, parms,
+		  if (parms)
+		    temp_store_parm_decls (d, parms);
+		  c_finish_omp_declare_simd (parser, d, parms,
 					     omp_declare_simd_clauses);
+		  if (parms)
+		    temp_pop_parm_decls ();
 		}
 	      if (d)
 		finish_decl (d, UNKNOWN_LOCATION, NULL_TREE,
@@ -1788,7 +1801,7 @@ c_parser_declaration_or_fndef (c_parser
 				       true, false, NULL, vNULL);
       store_parm_decls ();
       if (omp_declare_simd_clauses.exists ())
-	c_finish_omp_declare_simd (current_function_decl, NULL_TREE,
+	c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE,
 				   omp_declare_simd_clauses);
       DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
 	= c_parser_peek_token (parser)->location;
@@ -9058,8 +9071,7 @@ check_no_duplicate_clause (tree clauses,
 static tree
 c_parser_omp_variable_list (c_parser *parser,
 			    location_t clause_loc,
-			    enum omp_clause_code kind,
-			    tree list, bool declare_simd)
+			    enum omp_clause_code kind, tree list)
 {
   if (c_parser_next_token_is_not (parser, CPP_NAME)
       || c_parser_peek_token (parser)->id_kind != C_ID_ID)
@@ -9068,12 +9080,7 @@ c_parser_omp_variable_list (c_parser *pa
   while (c_parser_next_token_is (parser, CPP_NAME)
 	 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
     {
-      tree t;
-
-      if (declare_simd)
-	t = c_parser_peek_token (parser)->value;
-      else
-	t = lookup_name (c_parser_peek_token (parser)->value);
+      tree t = lookup_name (c_parser_peek_token (parser)->value);
 
       if (t == NULL_TREE)
 	{
@@ -9161,7 +9168,7 @@ c_parser_omp_var_list_parens (c_parser *
 
   if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
     {
-      list = c_parser_omp_variable_list (parser, loc, kind, list, false);
+      list = c_parser_omp_variable_list (parser, loc, kind, list);
       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
     }
   return list;
@@ -9523,7 +9530,7 @@ c_parser_omp_clause_reduction (c_parser
 	  tree nl, c;
 
 	  nl = c_parser_omp_variable_list (parser, clause_loc,
-					   OMP_CLAUSE_REDUCTION, list, false);
+					   OMP_CLAUSE_REDUCTION, list);
 	  for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
 	    OMP_CLAUSE_REDUCTION_CODE (c) = code;
 
@@ -9781,7 +9788,7 @@ c_parser_omp_clause_thread_limit (c_pars
    aligned ( variable-list : constant-expression ) */
 
 static tree
-c_parser_omp_clause_aligned (c_parser *parser, tree list, bool declare_simd)
+c_parser_omp_clause_aligned (c_parser *parser, tree list)
 {
   location_t clause_loc = c_parser_peek_token (parser)->location;
   tree nl, c;
@@ -9790,7 +9797,7 @@ c_parser_omp_clause_aligned (c_parser *p
     return list;
 
   nl = c_parser_omp_variable_list (parser, clause_loc,
-				   OMP_CLAUSE_ALIGNED, list, declare_simd);
+				   OMP_CLAUSE_ALIGNED, list);
 
   if (c_parser_next_token_is (parser, CPP_COLON))
     {
@@ -9820,7 +9827,7 @@ c_parser_omp_clause_aligned (c_parser *p
    linear ( variable-list : expression ) */
 
 static tree
-c_parser_omp_clause_linear (c_parser *parser, tree list, bool declare_simd)
+c_parser_omp_clause_linear (c_parser *parser, tree list)
 {
   location_t clause_loc = c_parser_peek_token (parser)->location;
   tree nl, c, step;
@@ -9829,7 +9836,7 @@ c_parser_omp_clause_linear (c_parser *pa
     return list;
 
   nl = c_parser_omp_variable_list (parser, clause_loc,
-				   OMP_CLAUSE_LINEAR, list, declare_simd);
+				   OMP_CLAUSE_LINEAR, list);
 
   if (c_parser_next_token_is (parser, CPP_COLON))
     {
@@ -9965,7 +9972,7 @@ c_parser_omp_clause_depend (c_parser *pa
     goto resync_fail;
 
   nl = c_parser_omp_variable_list (parser, clause_loc,
-				   OMP_CLAUSE_DEPEND, list, false);
+				   OMP_CLAUSE_DEPEND, list);
 
   for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
     OMP_CLAUSE_DEPEND_KIND (c) = kind;
@@ -10020,8 +10027,7 @@ c_parser_omp_clause_map (c_parser *parse
       c_parser_consume_token (parser);
     }
 
-  nl = c_parser_omp_variable_list (parser, clause_loc,
-				   OMP_CLAUSE_MAP, list, false);
+  nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_MAP, list);
 
   for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
     OMP_CLAUSE_MAP_KIND (c) = kind;
@@ -10181,7 +10187,7 @@ c_parser_omp_clause_uniform (c_parser *p
   if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
     {
       list = c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_UNIFORM,
-					 list, true);
+					 list);
       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
     }
   return list;
@@ -10193,8 +10199,7 @@ c_parser_omp_clause_uniform (c_parser *p
 
 static tree
 c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
-			  const char *where, bool finish_p = true,
-			  bool declare_simd = false)
+			  const char *where, bool finish_p = true)
 {
   tree clauses = NULL;
   bool first = true;
@@ -10350,12 +10355,11 @@ c_parser_omp_all_clauses (c_parser *pars
 	  c_name = "thread_limit";
 	  break;
 	case PRAGMA_OMP_CLAUSE_ALIGNED:
-	  clauses = c_parser_omp_clause_aligned (parser, clauses,
-						 declare_simd);
+	  clauses = c_parser_omp_clause_aligned (parser, clauses);
 	  c_name = "aligned";
 	  break;
 	case PRAGMA_OMP_CLAUSE_LINEAR:
-	  clauses = c_parser_omp_clause_linear (parser, clauses, declare_simd);
+	  clauses = c_parser_omp_clause_linear (parser, clauses);
 	  c_name = "linear";
 	  break;
 	case PRAGMA_OMP_CLAUSE_DEPEND:
@@ -11976,10 +11980,21 @@ c_parser_omp_target (c_parser *parser, e
 static void
 c_parser_omp_declare_simd (c_parser *parser, enum pragma_context context)
 {
-  vec<tree> clauses = vNULL;
-  tree cl = c_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
-				      "#pragma omp declare simd", false, true);
-  clauses.safe_push (cl);
+  vec<c_token> clauses = vNULL;
+  while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
+    {
+      c_token *token = c_parser_peek_token (parser);
+      if (token->type == CPP_EOF)
+	{
+	  c_parser_skip_to_pragma_eol (parser);
+	  clauses.release ();
+	  return;
+	}
+      clauses.safe_push (*token);
+      c_parser_consume_token (parser);
+    }
+  clauses.safe_push (*c_parser_peek_token (parser));
+  c_parser_skip_to_pragma_eol (parser);
 
   while (c_parser_next_token_is (parser, CPP_PRAGMA))
     {
@@ -11998,12 +12013,29 @@ c_parser_omp_declare_simd (c_parser *par
 	  return;
 	}
       c_parser_consume_pragma (parser);
-      c_parser_consume_token (parser);
-      cl = c_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
-				     "#pragma omp declare simd", false, true);
-      clauses.safe_push (cl);
+      while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
+	{
+	  c_token *token = c_parser_peek_token (parser);
+	  if (token->type == CPP_EOF)
+	    {
+	      c_parser_skip_to_pragma_eol (parser);
+	      clauses.release ();
+	      return;
+	    }
+	  clauses.safe_push (*token);
+	  c_parser_consume_token (parser);
+	}
+      clauses.safe_push (*c_parser_peek_token (parser));
+      c_parser_skip_to_pragma_eol (parser);
     }
 
+  /* Make sure nothing tries to read past the end of the tokens.  */
+  c_token eof_token;
+  memset (&eof_token, 0, sizeof (eof_token));
+  eof_token.type = CPP_EOF;
+  clauses.safe_push (eof_token);
+  clauses.safe_push (eof_token);
+
   switch (context)
     {
     case pragma_external:
@@ -12062,6 +12094,65 @@ c_parser_omp_declare_simd (c_parser *par
   clauses.release ();
 }
 
+/* Finalize #pragma omp declare simd clauses after FNDECL has been parsed,
+   and put that into "omp declare simd" attribute.  */
+
+static void
+c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms,
+			   vec<c_token> clauses)
+{
+  /* Normally first token is CPP_NAME "simd".  CPP_EOF there indicates
+     error has been reported and CPP_PRAGMA that c_finish_omp_declare_simd
+     has already processed the tokens.  */
+  if (clauses[0].type == CPP_EOF)
+    return;
+  if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
+    {
+      error ("%<#pragma omp declare simd%> not immediately followed by "
+	     "a function declaration or definition");
+      clauses[0].type = CPP_EOF;
+      return;
+    }
+  if (clauses[0].type != CPP_NAME)
+    {
+      error_at (DECL_SOURCE_LOCATION (fndecl),
+		"%<#pragma omp declare simd%> not immediately followed by "
+		"a single function declaration or definition");
+      clauses[0].type = CPP_EOF;
+      return;
+    }
+
+  if (parms == NULL_TREE)
+    parms = DECL_ARGUMENTS (fndecl);
+
+  unsigned int tokens_avail = parser->tokens_avail;
+  gcc_assert (parser->tokens == &parser->tokens_buf[0]);
+  parser->tokens = clauses.address ();
+  parser->tokens_avail = clauses.length ();
+
+  /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end.  */
+  while (parser->tokens_avail > 3)
+    {
+      c_token *token = c_parser_peek_token (parser);
+      gcc_assert (token->type == CPP_NAME
+		  && strcmp (IDENTIFIER_POINTER (token->value), "simd") == 0);
+      c_parser_consume_token (parser);
+      parser->in_pragma = true;
+
+      tree c = c_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
+					 "#pragma omp declare simd");
+      c = c_omp_declare_simd_clauses_to_numbers (parms, c);
+      c = build_tree_list (get_identifier ("omp declare simd"), c);
+      TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl);
+      DECL_ATTRIBUTES (fndecl) = c;
+    }
+
+  parser->tokens = &parser->tokens_buf[0];
+  parser->tokens_avail = tokens_avail;
+  clauses[0].type = CPP_PRAGMA;
+}
+
+
 /* OpenMP 4.0:
    # pragma omp declare target new-line
    declarations and definitions
@@ -12124,7 +12215,8 @@ c_parser_omp_declare (c_parser *parser,
       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
       if (strcmp (p, "simd") == 0)
 	{
-	  c_parser_consume_token (parser);
+	  /* c_parser_consume_token (parser); done in
+	     c_parser_omp_declare_simd.  */
 	  c_parser_omp_declare_simd (parser, context);
 	  return;
 	}
@@ -12495,6 +12587,7 @@ c_parse_file (void)
   c_parser tparser;
 
   memset (&tparser, 0, sizeof tparser);
+  tparser.tokens = &tparser.tokens_buf[0];
   the_parser = &tparser;
 
   if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS)
@@ -12502,6 +12595,8 @@ c_parse_file (void)
 
   the_parser = ggc_alloc_c_parser ();
   *the_parser = tparser;
+  if (tparser.tokens == &tparser.tokens_buf[0])
+    the_parser->tokens = &the_parser->tokens_buf[0];
 
   /* Initialize EH, if we've been told to do so.  */
   if (flag_exceptions)
--- gcc/c/c-tree.h.jj	2013-06-04 20:55:40.000000000 +0200
+++ gcc/c/c-tree.h	2013-07-19 22:31:08.685298840 +0200
@@ -526,6 +526,8 @@ extern tree start_struct (location_t, en
 			  struct c_struct_parse_info **);
 extern void store_parm_decls (void);
 extern void store_parm_decls_from (struct c_arg_info *);
+extern void temp_store_parm_decls (tree, tree);
+extern void temp_pop_parm_decls (void);
 extern tree xref_tag (enum tree_code, tree);
 extern struct c_typespec parser_xref_tag (location_t, enum tree_code, tree);
 extern struct c_parm *build_c_parm (struct c_declspecs *, tree,
@@ -642,7 +644,6 @@ extern void c_finish_omp_taskgroup (loca
 extern void c_finish_omp_cancel (location_t, tree);
 extern void c_finish_omp_cancellation_point (location_t, tree);
 extern tree c_finish_omp_clauses (tree);
-extern void c_finish_omp_declare_simd (tree, tree, vec<tree>);
 extern tree c_build_va_arg (location_t, tree, tree);
 extern tree c_finish_transaction (location_t, tree, int);
 extern bool c_tree_equal (tree, tree);
--- gcc/c/c-decl.c.jj	2013-07-08 10:08:48.000000000 +0200
+++ gcc/c/c-decl.c	2013-07-20 02:30:12.904762092 +0200
@@ -8353,6 +8353,44 @@ store_parm_decls (void)
   if (arg_info->pending_sizes)
     add_stmt (arg_info->pending_sizes);
 }
+
+/* Store PARM_DECLs in PARMS into scope temporarily.  Used for
+   c_finish_omp_declare_simd for function prototypes.  No diagnostics
+   should be done.  */
+
+void
+temp_store_parm_decls (tree fndecl, tree parms)
+{
+  push_scope ();
+  for (tree p = parms; p; p = DECL_CHAIN (p))
+    {
+      DECL_CONTEXT (p) = fndecl;
+      if (DECL_NAME (p))
+	bind (DECL_NAME (p), p, current_scope,
+	      /*invisible=*/false, /*nested=*/false,
+	      UNKNOWN_LOCATION);
+    }
+}
+
+/* Undo what temp_store_parm_decls did.  */
+
+void
+temp_pop_parm_decls (void)
+{
+  /* Clear all bindings in this temporary scope, so that
+     pop_scope doesn't create a BLOCK.  */
+  struct c_binding *b = current_scope->bindings;
+  current_scope->bindings = NULL;
+  for (; b; b = free_binding_and_advance (b))
+    {
+      gcc_assert (TREE_CODE (b->decl) == PARM_DECL);
+      gcc_assert (I_SYMBOL_BINDING (b->id) == b);
+      I_SYMBOL_BINDING (b->id) = b->shadowed;
+      if (b->shadowed && b->shadowed->u.type)
+	TREE_TYPE (b->shadowed->decl) = b->shadowed->u.type;
+    }
+  pop_scope ();
+}
 
 
 /* Finish up a function declaration and compile that function
--- gcc/testsuite/gcc.dg/gomp/declare-simd-1.c.jj	2013-06-04 20:57:49.000000000 +0200
+++ gcc/testsuite/gcc.dg/gomp/declare-simd-1.c	2013-07-20 02:48:35.622014339 +0200
@@ -80,3 +80,21 @@ f15 (int a, int *b, int c)
 
 #pragma omp declare simd uniform (d) aligned (e : 8 * sizeof (int)) linear (f : 4) simdlen (8)
 int f15 (int d, int *e, int f);
+
+#pragma omp declare simd aligned (g : sizeof (*g)) linear (h : 2 * sizeof (g[0]) + sizeof (h)) simdlen (4)
+int f16 (long *g, int h);
+
+#pragma omp declare simd aligned (h : sizeof (*h)) linear (g : 2 * sizeof (h[0]) + sizeof (g)) simdlen (4)
+int f17 (int g, long *h)
+{
+  return g + h[0];
+}
+
+#pragma omp declare simd aligned (i : sizeof (*i)) linear (j : 2 * sizeof (i[0]) + sizeof (j)) simdlen (4)
+int
+f18 (j, i)
+     long *i;
+     int j;
+{
+  return j + i[0];
+}

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]