1 /* Parser for C and Objective-C.
2    Copyright (C) 1987-2020 Free Software Foundation, Inc.
3 
4    Parser actions based on the old Bison parser; structure somewhat
5    influenced by and fragments based on the C++ parser.
6 
7 This file is part of GCC.
8 
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
13 
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3.  If not see
21 <http://www.gnu.org/licenses/>.  */
22 
23 /* TODO:
24 
25    Make sure all relevant comments, and all relevant code from all
26    actions, brought over from old parser.  Verify exact correspondence
27    of syntax accepted.
28 
29    Add testcases covering every input symbol in every state in old and
30    new parsers.
31 
32    Include full syntax for GNU C, including erroneous cases accepted
33    with error messages, in syntax productions in comments.
34 
35    Make more diagnostics in the front end generally take an explicit
36    location rather than implicitly using input_location.  */
37 
38 #include "config.h"
39 #define INCLUDE_UNIQUE_PTR
40 #include "system.h"
41 #include "coretypes.h"
42 #include "target.h"
43 #include "function.h"
44 #include "c-tree.h"
45 #include "timevar.h"
46 #include "stringpool.h"
47 #include "cgraph.h"
48 #include "attribs.h"
49 #include "stor-layout.h"
50 #include "varasm.h"
51 #include "trans-mem.h"
52 #include "c-family/c-pragma.h"
53 #include "c-lang.h"
54 #include "c-family/c-objc.h"
55 #include "plugin.h"
56 #include "omp-general.h"
57 #include "omp-offload.h"
58 #include "builtins.h"
59 #include "gomp-constants.h"
60 #include "c-family/c-indentation.h"
61 #include "gimple-expr.h"
62 #include "context.h"
63 #include "gcc-rich-location.h"
64 #include "c-parser.h"
65 #include "gimple-parser.h"
66 #include "read-rtl-function.h"
67 #include "run-rtl-passes.h"
68 #include "intl.h"
69 #include "c-family/name-hint.h"
70 #include "tree-iterator.h"
71 #include "memmodel.h"
72 
73 /* We need to walk over decls with incomplete struct/union/enum types
74    after parsing the whole translation unit.
75    In finish_decl(), if the decl is static, has incomplete
76    struct/union/enum type, it is appeneded to incomplete_record_decls.
77    In c_parser_translation_unit(), we iterate over incomplete_record_decls
78    and report error if any of the decls are still incomplete.  */
79 
80 vec<tree> incomplete_record_decls;
81 
82 void
set_c_expr_source_range(c_expr * expr,location_t start,location_t finish)83 set_c_expr_source_range (c_expr *expr,
84 			 location_t start, location_t finish)
85 {
86   expr->src_range.m_start = start;
87   expr->src_range.m_finish = finish;
88   if (expr->value)
89     set_source_range (expr->value, start, finish);
90 }
91 
92 void
set_c_expr_source_range(c_expr * expr,source_range src_range)93 set_c_expr_source_range (c_expr *expr,
94 			 source_range src_range)
95 {
96   expr->src_range = src_range;
97   if (expr->value)
98     set_source_range (expr->value, src_range);
99 }
100 
101 
102 /* Initialization routine for this file.  */
103 
104 void
c_parse_init(void)105 c_parse_init (void)
106 {
107   /* The only initialization required is of the reserved word
108      identifiers.  */
109   unsigned int i;
110   tree id;
111   int mask = 0;
112 
113   /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in
114      the c_token structure.  */
115   gcc_assert (RID_MAX <= 255);
116 
117   mask |= D_CXXONLY;
118   if (!flag_isoc99)
119     mask |= D_C99;
120   if (flag_no_asm)
121     {
122       mask |= D_ASM | D_EXT;
123       if (!flag_isoc99)
124 	mask |= D_EXT89;
125     }
126   if (!c_dialect_objc ())
127     mask |= D_OBJC | D_CXX_OBJC;
128 
129   ridpointers = ggc_cleared_vec_alloc<tree> ((int) RID_MAX);
130   for (i = 0; i < num_c_common_reswords; i++)
131     {
132       /* If a keyword is disabled, do not enter it into the table
133 	 and so create a canonical spelling that isn't a keyword.  */
134       if (c_common_reswords[i].disable & mask)
135 	{
136 	  if (warn_cxx_compat
137 	      && (c_common_reswords[i].disable & D_CXXWARN))
138 	    {
139 	      id = get_identifier (c_common_reswords[i].word);
140 	      C_SET_RID_CODE (id, RID_CXX_COMPAT_WARN);
141 	      C_IS_RESERVED_WORD (id) = 1;
142 	    }
143 	  continue;
144 	}
145 
146       id = get_identifier (c_common_reswords[i].word);
147       C_SET_RID_CODE (id, c_common_reswords[i].rid);
148       C_IS_RESERVED_WORD (id) = 1;
149       ridpointers [(int) c_common_reswords[i].rid] = id;
150     }
151 
152   for (i = 0; i < NUM_INT_N_ENTS; i++)
153     {
154       /* We always create the symbols but they aren't always supported.  */
155       char name[50];
156       sprintf (name, "__int%d", int_n_data[i].bitsize);
157       id = get_identifier (name);
158       C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
159       C_IS_RESERVED_WORD (id) = 1;
160 
161       sprintf (name, "__int%d__", int_n_data[i].bitsize);
162       id = get_identifier (name);
163       C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
164       C_IS_RESERVED_WORD (id) = 1;
165     }
166 }
167 
168 /* A parser structure recording information about the state and
169    context of parsing.  Includes lexer information with up to two
170    tokens of look-ahead; more are not needed for C.  */
171 struct GTY(()) c_parser {
172   /* The look-ahead tokens.  */
173   c_token * GTY((skip)) tokens;
174   /* Buffer for look-ahead tokens.  */
175   c_token tokens_buf[4];
176   /* How many look-ahead tokens are available (0 - 4, or
177      more if parsing from pre-lexed tokens).  */
178   unsigned int tokens_avail;
179   /* Raw look-ahead tokens, used only for checking in Objective-C
180      whether '[[' starts attributes.  */
181   vec<c_token, va_gc> *raw_tokens;
182   /* The number of raw look-ahead tokens that have since been fully
183      lexed.  */
184   unsigned int raw_tokens_used;
185   /* True if a syntax error is being recovered from; false otherwise.
186      c_parser_error sets this flag.  It should clear this flag when
187      enough tokens have been consumed to recover from the error.  */
188   BOOL_BITFIELD error : 1;
189   /* True if we're processing a pragma, and shouldn't automatically
190      consume CPP_PRAGMA_EOL.  */
191   BOOL_BITFIELD in_pragma : 1;
192   /* True if we're parsing the outermost block of an if statement.  */
193   BOOL_BITFIELD in_if_block : 1;
194   /* True if we want to lex a translated, joined string (for an
195      initial #pragma pch_preprocess).  Otherwise the parser is
196      responsible for concatenating strings and translating to the
197      execution character set as needed.  */
198   BOOL_BITFIELD lex_joined_string : 1;
199   /* True if, when the parser is concatenating string literals, it
200      should translate them to the execution character set (false
201      inside attributes).  */
202   BOOL_BITFIELD translate_strings_p : 1;
203 
204   /* Objective-C specific parser/lexer information.  */
205 
206   /* True if we are in a context where the Objective-C "PQ" keywords
207      are considered keywords.  */
208   BOOL_BITFIELD objc_pq_context : 1;
209   /* True if we are parsing a (potential) Objective-C foreach
210      statement.  This is set to true after we parsed 'for (' and while
211      we wait for 'in' or ';' to decide if it's a standard C for loop or an
212      Objective-C foreach loop.  */
213   BOOL_BITFIELD objc_could_be_foreach_context : 1;
214   /* The following flag is needed to contextualize Objective-C lexical
215      analysis.  In some cases (e.g., 'int NSObject;'), it is
216      undesirable to bind an identifier to an Objective-C class, even
217      if a class with that name exists.  */
218   BOOL_BITFIELD objc_need_raw_identifier : 1;
219   /* Nonzero if we're processing a __transaction statement.  The value
220      is 1 | TM_STMT_ATTR_*.  */
221   unsigned int in_transaction : 4;
222   /* True if we are in a context where the Objective-C "Property attribute"
223      keywords are valid.  */
224   BOOL_BITFIELD objc_property_attr_context : 1;
225 
226   /* Location of the last consumed token.  */
227   location_t last_token_location;
228 };
229 
230 /* Return a pointer to the Nth token in PARSERs tokens_buf.  */
231 
232 c_token *
c_parser_tokens_buf(c_parser * parser,unsigned n)233 c_parser_tokens_buf (c_parser *parser, unsigned n)
234 {
235   return &parser->tokens_buf[n];
236 }
237 
238 /* Return the error state of PARSER.  */
239 
240 bool
c_parser_error(c_parser * parser)241 c_parser_error (c_parser *parser)
242 {
243   return parser->error;
244 }
245 
246 /* Set the error state of PARSER to ERR.  */
247 
248 void
c_parser_set_error(c_parser * parser,bool err)249 c_parser_set_error (c_parser *parser, bool err)
250 {
251   parser->error = err;
252 }
253 
254 
255 /* The actual parser and external interface.  ??? Does this need to be
256    garbage-collected?  */
257 
258 static GTY (()) c_parser *the_parser;
259 
260 /* Read in and lex a single token, storing it in *TOKEN.  If RAW,
261    context-sensitive postprocessing of the token is not done.  */
262 
263 static void
264 c_lex_one_token (c_parser *parser, c_token *token, bool raw = false)
265 {
266   timevar_push (TV_LEX);
267 
268   if (raw || vec_safe_length (parser->raw_tokens) == 0)
269     {
270       token->type = c_lex_with_flags (&token->value, &token->location,
271 				      &token->flags,
272 				      (parser->lex_joined_string
273 				       ? 0 : C_LEX_STRING_NO_JOIN));
274       token->id_kind = C_ID_NONE;
275       token->keyword = RID_MAX;
276       token->pragma_kind = PRAGMA_NONE;
277     }
278   else
279     {
280       /* Use a token previously lexed as a raw look-ahead token, and
281 	 complete the processing on it.  */
282       *token = (*parser->raw_tokens)[parser->raw_tokens_used];
283       ++parser->raw_tokens_used;
284       if (parser->raw_tokens_used == vec_safe_length (parser->raw_tokens))
285 	{
286 	  vec_free (parser->raw_tokens);
287 	  parser->raw_tokens_used = 0;
288 	}
289     }
290 
291   if (raw)
292     goto out;
293 
294   switch (token->type)
295     {
296     case CPP_NAME:
297       {
298 	tree decl;
299 
300 	bool objc_force_identifier = parser->objc_need_raw_identifier;
301 	if (c_dialect_objc ())
302 	  parser->objc_need_raw_identifier = false;
303 
304 	if (C_IS_RESERVED_WORD (token->value))
305 	  {
306 	    enum rid rid_code = C_RID_CODE (token->value);
307 
308 	    if (rid_code == RID_CXX_COMPAT_WARN)
309 	      {
310 		warning_at (token->location,
311 			    OPT_Wc___compat,
312 			    "identifier %qE conflicts with C++ keyword",
313 			    token->value);
314 	      }
315 	    else if (rid_code >= RID_FIRST_ADDR_SPACE
316 		     && rid_code <= RID_LAST_ADDR_SPACE)
317 	      {
318 		addr_space_t as;
319 		as = (addr_space_t) (rid_code - RID_FIRST_ADDR_SPACE);
320 		targetm.addr_space.diagnose_usage (as, token->location);
321 		token->id_kind = C_ID_ADDRSPACE;
322 		token->keyword = rid_code;
323 		break;
324 	      }
325 	    else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code))
326 	      {
327 		/* We found an Objective-C "pq" keyword (in, out,
328 		   inout, bycopy, byref, oneway).  They need special
329 		   care because the interpretation depends on the
330 		   context.  */
331 		if (parser->objc_pq_context)
332 		  {
333 		    token->type = CPP_KEYWORD;
334 		    token->keyword = rid_code;
335 		    break;
336 		  }
337 		else if (parser->objc_could_be_foreach_context
338 			 && rid_code == RID_IN)
339 		  {
340 		    /* We are in Objective-C, inside a (potential)
341 		       foreach context (which means after having
342 		       parsed 'for (', but before having parsed ';'),
343 		       and we found 'in'.  We consider it the keyword
344 		       which terminates the declaration at the
345 		       beginning of a foreach-statement.  Note that
346 		       this means you can't use 'in' for anything else
347 		       in that context; in particular, in Objective-C
348 		       you can't use 'in' as the name of the running
349 		       variable in a C for loop.  We could potentially
350 		       try to add code here to disambiguate, but it
351 		       seems a reasonable limitation.  */
352 		    token->type = CPP_KEYWORD;
353 		    token->keyword = rid_code;
354 		    break;
355 		  }
356 		/* Else, "pq" keywords outside of the "pq" context are
357 		   not keywords, and we fall through to the code for
358 		   normal tokens.  */
359 	      }
360 	    else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code))
361 	      {
362 		/* We found an Objective-C "property attribute"
363 		   keyword (getter, setter, readonly, etc). These are
364 		   only valid in the property context.  */
365 		if (parser->objc_property_attr_context)
366 		  {
367 		    token->type = CPP_KEYWORD;
368 		    token->keyword = rid_code;
369 		    break;
370 		  }
371 		/* Else they are not special keywords.
372 		*/
373 	      }
374 	    else if (c_dialect_objc ()
375 		     && (OBJC_IS_AT_KEYWORD (rid_code)
376 			 || OBJC_IS_CXX_KEYWORD (rid_code)))
377 	      {
378 		/* We found one of the Objective-C "@" keywords (defs,
379 		   selector, synchronized, etc) or one of the
380 		   Objective-C "cxx" keywords (class, private,
381 		   protected, public, try, catch, throw) without a
382 		   preceding '@' sign.  Do nothing and fall through to
383 		   the code for normal tokens (in C++ we would still
384 		   consider the CXX ones keywords, but not in C).  */
385 		;
386 	      }
387 	    else
388 	      {
389 		token->type = CPP_KEYWORD;
390 		token->keyword = rid_code;
391 		break;
392 	      }
393 	  }
394 
395 	decl = lookup_name (token->value);
396 	if (decl)
397 	  {
398 	    if (TREE_CODE (decl) == TYPE_DECL)
399 	      {
400 		token->id_kind = C_ID_TYPENAME;
401 		break;
402 	      }
403 	  }
404 	else if (c_dialect_objc ())
405 	  {
406 	    tree objc_interface_decl = objc_is_class_name (token->value);
407 	    /* Objective-C class names are in the same namespace as
408 	       variables and typedefs, and hence are shadowed by local
409 	       declarations.  */
410 	    if (objc_interface_decl
411                 && (!objc_force_identifier || global_bindings_p ()))
412 	      {
413 		token->value = objc_interface_decl;
414 		token->id_kind = C_ID_CLASSNAME;
415 		break;
416 	      }
417 	  }
418         token->id_kind = C_ID_ID;
419       }
420       break;
421     case CPP_AT_NAME:
422       /* This only happens in Objective-C; it must be a keyword.  */
423       token->type = CPP_KEYWORD;
424       switch (C_RID_CODE (token->value))
425 	{
426 	  /* Replace 'class' with '@class', 'private' with '@private',
427 	     etc.  This prevents confusion with the C++ keyword
428 	     'class', and makes the tokens consistent with other
429 	     Objective-C 'AT' keywords.  For example '@class' is
430 	     reported as RID_AT_CLASS which is consistent with
431 	     '@synchronized', which is reported as
432 	     RID_AT_SYNCHRONIZED.
433 	  */
434 	case RID_CLASS:     token->keyword = RID_AT_CLASS; break;
435 	case RID_PRIVATE:   token->keyword = RID_AT_PRIVATE; break;
436 	case RID_PROTECTED: token->keyword = RID_AT_PROTECTED; break;
437 	case RID_PUBLIC:    token->keyword = RID_AT_PUBLIC; break;
438 	case RID_THROW:     token->keyword = RID_AT_THROW; break;
439 	case RID_TRY:       token->keyword = RID_AT_TRY; break;
440 	case RID_CATCH:     token->keyword = RID_AT_CATCH; break;
441 	case RID_SYNCHRONIZED: token->keyword = RID_AT_SYNCHRONIZED; break;
442 	default:            token->keyword = C_RID_CODE (token->value);
443 	}
444       break;
445     case CPP_COLON:
446     case CPP_COMMA:
447     case CPP_CLOSE_PAREN:
448     case CPP_SEMICOLON:
449       /* These tokens may affect the interpretation of any identifiers
450 	 following, if doing Objective-C.  */
451       if (c_dialect_objc ())
452 	parser->objc_need_raw_identifier = false;
453       break;
454     case CPP_PRAGMA:
455       /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST.  */
456       token->pragma_kind = (enum pragma_kind) TREE_INT_CST_LOW (token->value);
457       token->value = NULL;
458       break;
459     default:
460       break;
461     }
462  out:
463   timevar_pop (TV_LEX);
464 }
465 
466 /* Return a pointer to the next token from PARSER, reading it in if
467    necessary.  */
468 
469 c_token *
c_parser_peek_token(c_parser * parser)470 c_parser_peek_token (c_parser *parser)
471 {
472   if (parser->tokens_avail == 0)
473     {
474       c_lex_one_token (parser, &parser->tokens[0]);
475       parser->tokens_avail = 1;
476     }
477   return &parser->tokens[0];
478 }
479 
480 /* Return a pointer to the next-but-one token from PARSER, reading it
481    in if necessary.  The next token is already read in.  */
482 
483 c_token *
c_parser_peek_2nd_token(c_parser * parser)484 c_parser_peek_2nd_token (c_parser *parser)
485 {
486   if (parser->tokens_avail >= 2)
487     return &parser->tokens[1];
488   gcc_assert (parser->tokens_avail == 1);
489   gcc_assert (parser->tokens[0].type != CPP_EOF);
490   gcc_assert (parser->tokens[0].type != CPP_PRAGMA_EOL);
491   c_lex_one_token (parser, &parser->tokens[1]);
492   parser->tokens_avail = 2;
493   return &parser->tokens[1];
494 }
495 
496 /* Return a pointer to the Nth token from PARSER, reading it
497    in if necessary.  The N-1th token is already read in.  */
498 
499 c_token *
c_parser_peek_nth_token(c_parser * parser,unsigned int n)500 c_parser_peek_nth_token (c_parser *parser, unsigned int n)
501 {
502   /* N is 1-based, not zero-based.  */
503   gcc_assert (n > 0);
504 
505   if (parser->tokens_avail >= n)
506     return &parser->tokens[n - 1];
507   gcc_assert (parser->tokens_avail == n - 1);
508   c_lex_one_token (parser, &parser->tokens[n - 1]);
509   parser->tokens_avail = n;
510   return &parser->tokens[n - 1];
511 }
512 
513 /* Return a pointer to the Nth token from PARSER, reading it in as a
514    raw look-ahead token if necessary.  The N-1th token is already read
515    in.  Raw look-ahead tokens remain available for when the non-raw
516    functions above are called.  */
517 
518 c_token *
c_parser_peek_nth_token_raw(c_parser * parser,unsigned int n)519 c_parser_peek_nth_token_raw (c_parser *parser, unsigned int n)
520 {
521   /* N is 1-based, not zero-based.  */
522   gcc_assert (n > 0);
523 
524   if (parser->tokens_avail >= n)
525     return &parser->tokens[n - 1];
526   unsigned int raw_len = vec_safe_length (parser->raw_tokens);
527   unsigned int raw_avail
528     = parser->tokens_avail + raw_len - parser->raw_tokens_used;
529   gcc_assert (raw_avail >= n - 1);
530   if (raw_avail >= n)
531     return &(*parser->raw_tokens)[parser->raw_tokens_used
532 				  + n - 1 - parser->tokens_avail];
533   vec_safe_reserve (parser->raw_tokens, 1);
534   parser->raw_tokens->quick_grow (raw_len + 1);
535   c_lex_one_token (parser, &(*parser->raw_tokens)[raw_len], true);
536   return &(*parser->raw_tokens)[raw_len];
537 }
538 
539 bool
c_keyword_starts_typename(enum rid keyword)540 c_keyword_starts_typename (enum rid keyword)
541 {
542   switch (keyword)
543     {
544     case RID_UNSIGNED:
545     case RID_LONG:
546     case RID_SHORT:
547     case RID_SIGNED:
548     case RID_COMPLEX:
549     case RID_INT:
550     case RID_CHAR:
551     case RID_FLOAT:
552     case RID_DOUBLE:
553     case RID_VOID:
554     case RID_DFLOAT32:
555     case RID_DFLOAT64:
556     case RID_DFLOAT128:
557     CASE_RID_FLOATN_NX:
558     case RID_BOOL:
559     case RID_ENUM:
560     case RID_STRUCT:
561     case RID_UNION:
562     case RID_TYPEOF:
563     case RID_CONST:
564     case RID_ATOMIC:
565     case RID_VOLATILE:
566     case RID_RESTRICT:
567     case RID_ATTRIBUTE:
568     case RID_FRACT:
569     case RID_ACCUM:
570     case RID_SAT:
571     case RID_AUTO_TYPE:
572     case RID_ALIGNAS:
573       return true;
574     default:
575       if (keyword >= RID_FIRST_INT_N
576 	  && keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
577 	  && int_n_enabled_p[keyword - RID_FIRST_INT_N])
578 	return true;
579       return false;
580     }
581 }
582 
583 /* Return true if TOKEN can start a type name,
584    false otherwise.  */
585 bool
c_token_starts_typename(c_token * token)586 c_token_starts_typename (c_token *token)
587 {
588   switch (token->type)
589     {
590     case CPP_NAME:
591       switch (token->id_kind)
592 	{
593 	case C_ID_ID:
594 	  return false;
595 	case C_ID_ADDRSPACE:
596 	  return true;
597 	case C_ID_TYPENAME:
598 	  return true;
599 	case C_ID_CLASSNAME:
600 	  gcc_assert (c_dialect_objc ());
601 	  return true;
602 	default:
603 	  gcc_unreachable ();
604 	}
605     case CPP_KEYWORD:
606       return c_keyword_starts_typename (token->keyword);
607     case CPP_LESS:
608       if (c_dialect_objc ())
609 	return true;
610       return false;
611     default:
612       return false;
613     }
614 }
615 
616 /* Return true if the next token from PARSER can start a type name,
617    false otherwise.  LA specifies how to do lookahead in order to
618    detect unknown type names.  If unsure, pick CLA_PREFER_ID.  */
619 
620 static inline bool
c_parser_next_tokens_start_typename(c_parser * parser,enum c_lookahead_kind la)621 c_parser_next_tokens_start_typename (c_parser *parser, enum c_lookahead_kind la)
622 {
623   c_token *token = c_parser_peek_token (parser);
624   if (c_token_starts_typename (token))
625     return true;
626 
627   /* Try a bit harder to detect an unknown typename.  */
628   if (la != cla_prefer_id
629       && token->type == CPP_NAME
630       && token->id_kind == C_ID_ID
631 
632       /* Do not try too hard when we could have "object in array".  */
633       && !parser->objc_could_be_foreach_context
634 
635       && (la == cla_prefer_type
636 	  || c_parser_peek_2nd_token (parser)->type == CPP_NAME
637 	  || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
638 
639       /* Only unknown identifiers.  */
640       && !lookup_name (token->value))
641     return true;
642 
643   return false;
644 }
645 
646 /* Return true if TOKEN is a type qualifier, false otherwise.  */
647 static bool
c_token_is_qualifier(c_token * token)648 c_token_is_qualifier (c_token *token)
649 {
650   switch (token->type)
651     {
652     case CPP_NAME:
653       switch (token->id_kind)
654 	{
655 	case C_ID_ADDRSPACE:
656 	  return true;
657 	default:
658 	  return false;
659 	}
660     case CPP_KEYWORD:
661       switch (token->keyword)
662 	{
663 	case RID_CONST:
664 	case RID_VOLATILE:
665 	case RID_RESTRICT:
666 	case RID_ATTRIBUTE:
667 	case RID_ATOMIC:
668 	  return true;
669 	default:
670 	  return false;
671 	}
672     case CPP_LESS:
673       return false;
674     default:
675       gcc_unreachable ();
676     }
677 }
678 
679 /* Return true if the next token from PARSER is a type qualifier,
680    false otherwise.  */
681 static inline bool
c_parser_next_token_is_qualifier(c_parser * parser)682 c_parser_next_token_is_qualifier (c_parser *parser)
683 {
684   c_token *token = c_parser_peek_token (parser);
685   return c_token_is_qualifier (token);
686 }
687 
688 /* Return true if TOKEN can start declaration specifiers (not
689    including standard attributes), false otherwise.  */
690 static bool
c_token_starts_declspecs(c_token * token)691 c_token_starts_declspecs (c_token *token)
692 {
693   switch (token->type)
694     {
695     case CPP_NAME:
696       switch (token->id_kind)
697 	{
698 	case C_ID_ID:
699 	  return false;
700 	case C_ID_ADDRSPACE:
701 	  return true;
702 	case C_ID_TYPENAME:
703 	  return true;
704 	case C_ID_CLASSNAME:
705 	  gcc_assert (c_dialect_objc ());
706 	  return true;
707 	default:
708 	  gcc_unreachable ();
709 	}
710     case CPP_KEYWORD:
711       switch (token->keyword)
712 	{
713 	case RID_STATIC:
714 	case RID_EXTERN:
715 	case RID_REGISTER:
716 	case RID_TYPEDEF:
717 	case RID_INLINE:
718 	case RID_NORETURN:
719 	case RID_AUTO:
720 	case RID_THREAD:
721 	case RID_UNSIGNED:
722 	case RID_LONG:
723 	case RID_SHORT:
724 	case RID_SIGNED:
725 	case RID_COMPLEX:
726 	case RID_INT:
727 	case RID_CHAR:
728 	case RID_FLOAT:
729 	case RID_DOUBLE:
730 	case RID_VOID:
731 	case RID_DFLOAT32:
732 	case RID_DFLOAT64:
733 	case RID_DFLOAT128:
734 	CASE_RID_FLOATN_NX:
735 	case RID_BOOL:
736 	case RID_ENUM:
737 	case RID_STRUCT:
738 	case RID_UNION:
739 	case RID_TYPEOF:
740 	case RID_CONST:
741 	case RID_VOLATILE:
742 	case RID_RESTRICT:
743 	case RID_ATTRIBUTE:
744 	case RID_FRACT:
745 	case RID_ACCUM:
746 	case RID_SAT:
747 	case RID_ALIGNAS:
748 	case RID_ATOMIC:
749 	case RID_AUTO_TYPE:
750 	  return true;
751 	default:
752 	  if (token->keyword >= RID_FIRST_INT_N
753 	      && token->keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
754 	      && int_n_enabled_p[token->keyword - RID_FIRST_INT_N])
755 	    return true;
756 	  return false;
757 	}
758     case CPP_LESS:
759       if (c_dialect_objc ())
760 	return true;
761       return false;
762     default:
763       return false;
764     }
765 }
766 
767 
768 /* Return true if TOKEN can start declaration specifiers (not
769    including standard attributes) or a static assertion, false
770    otherwise.  */
771 static bool
c_token_starts_declaration(c_token * token)772 c_token_starts_declaration (c_token *token)
773 {
774   if (c_token_starts_declspecs (token)
775       || token->keyword == RID_STATIC_ASSERT)
776     return true;
777   else
778     return false;
779 }
780 
781 /* Return true if the next token from PARSER can start declaration
782    specifiers (not including standard attributes), false
783    otherwise.  */
784 bool
c_parser_next_token_starts_declspecs(c_parser * parser)785 c_parser_next_token_starts_declspecs (c_parser *parser)
786 {
787   c_token *token = c_parser_peek_token (parser);
788 
789   /* In Objective-C, a classname normally starts a declspecs unless it
790      is immediately followed by a dot.  In that case, it is the
791      Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
792      setter/getter on the class.  c_token_starts_declspecs() can't
793      differentiate between the two cases because it only checks the
794      current token, so we have a special check here.  */
795   if (c_dialect_objc ()
796       && token->type == CPP_NAME
797       && token->id_kind == C_ID_CLASSNAME
798       && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
799     return false;
800 
801   return c_token_starts_declspecs (token);
802 }
803 
804 /* Return true if the next tokens from PARSER can start declaration
805    specifiers (not including standard attributes) or a static
806    assertion, false otherwise.  */
807 bool
c_parser_next_tokens_start_declaration(c_parser * parser)808 c_parser_next_tokens_start_declaration (c_parser *parser)
809 {
810   c_token *token = c_parser_peek_token (parser);
811 
812   /* Same as above.  */
813   if (c_dialect_objc ()
814       && token->type == CPP_NAME
815       && token->id_kind == C_ID_CLASSNAME
816       && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
817     return false;
818 
819   /* Labels do not start declarations.  */
820   if (token->type == CPP_NAME
821       && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
822     return false;
823 
824   if (c_token_starts_declaration (token))
825     return true;
826 
827   if (c_parser_next_tokens_start_typename (parser, cla_nonabstract_decl))
828     return true;
829 
830   return false;
831 }
832 
833 /* Consume the next token from PARSER.  */
834 
835 void
c_parser_consume_token(c_parser * parser)836 c_parser_consume_token (c_parser *parser)
837 {
838   gcc_assert (parser->tokens_avail >= 1);
839   gcc_assert (parser->tokens[0].type != CPP_EOF);
840   gcc_assert (!parser->in_pragma || parser->tokens[0].type != CPP_PRAGMA_EOL);
841   gcc_assert (parser->error || parser->tokens[0].type != CPP_PRAGMA);
842   parser->last_token_location = parser->tokens[0].location;
843   if (parser->tokens != &parser->tokens_buf[0])
844     parser->tokens++;
845   else if (parser->tokens_avail >= 2)
846     {
847       parser->tokens[0] = parser->tokens[1];
848       if (parser->tokens_avail >= 3)
849         {
850           parser->tokens[1] = parser->tokens[2];
851           if (parser->tokens_avail >= 4)
852             parser->tokens[2] = parser->tokens[3];
853         }
854     }
855   parser->tokens_avail--;
856 }
857 
858 /* Expect the current token to be a #pragma.  Consume it and remember
859    that we've begun parsing a pragma.  */
860 
861 static void
c_parser_consume_pragma(c_parser * parser)862 c_parser_consume_pragma (c_parser *parser)
863 {
864   gcc_assert (!parser->in_pragma);
865   gcc_assert (parser->tokens_avail >= 1);
866   gcc_assert (parser->tokens[0].type == CPP_PRAGMA);
867   if (parser->tokens != &parser->tokens_buf[0])
868     parser->tokens++;
869   else if (parser->tokens_avail >= 2)
870     {
871       parser->tokens[0] = parser->tokens[1];
872       if (parser->tokens_avail >= 3)
873 	parser->tokens[1] = parser->tokens[2];
874     }
875   parser->tokens_avail--;
876   parser->in_pragma = true;
877 }
878 
879 /* Update the global input_location from TOKEN.  */
880 static inline void
c_parser_set_source_position_from_token(c_token * token)881 c_parser_set_source_position_from_token (c_token *token)
882 {
883   if (token->type != CPP_EOF)
884     {
885       input_location = token->location;
886     }
887 }
888 
889 /* Helper function for c_parser_error.
890    Having peeked a token of kind TOK1_KIND that might signify
891    a conflict marker, peek successor tokens to determine
892    if we actually do have a conflict marker.
893    Specifically, we consider a run of 7 '<', '=' or '>' characters
894    at the start of a line as a conflict marker.
895    These come through the lexer as three pairs and a single,
896    e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<').
897    If it returns true, *OUT_LOC is written to with the location/range
898    of the marker.  */
899 
900 static bool
c_parser_peek_conflict_marker(c_parser * parser,enum cpp_ttype tok1_kind,location_t * out_loc)901 c_parser_peek_conflict_marker (c_parser *parser, enum cpp_ttype tok1_kind,
902 			       location_t *out_loc)
903 {
904   c_token *token2 = c_parser_peek_2nd_token (parser);
905   if (token2->type != tok1_kind)
906     return false;
907   c_token *token3 = c_parser_peek_nth_token (parser, 3);
908   if (token3->type != tok1_kind)
909     return false;
910   c_token *token4 = c_parser_peek_nth_token (parser, 4);
911   if (token4->type != conflict_marker_get_final_tok_kind (tok1_kind))
912     return false;
913 
914   /* It must be at the start of the line.  */
915   location_t start_loc = c_parser_peek_token (parser)->location;
916   if (LOCATION_COLUMN (start_loc) != 1)
917     return false;
918 
919   /* We have a conflict marker.  Construct a location of the form:
920        <<<<<<<
921        ^~~~~~~
922      with start == caret, finishing at the end of the marker.  */
923   location_t finish_loc = get_finish (token4->location);
924   *out_loc = make_location (start_loc, start_loc, finish_loc);
925 
926   return true;
927 }
928 
929 /* Issue a diagnostic of the form
930       FILE:LINE: MESSAGE before TOKEN
931    where TOKEN is the next token in the input stream of PARSER.
932    MESSAGE (specified by the caller) is usually of the form "expected
933    OTHER-TOKEN".
934 
935    Use RICHLOC as the location of the diagnostic.
936 
937    Do not issue a diagnostic if still recovering from an error.
938 
939    Return true iff an error was actually emitted.
940 
941    ??? This is taken from the C++ parser, but building up messages in
942    this way is not i18n-friendly and some other approach should be
943    used.  */
944 
945 static bool
c_parser_error_richloc(c_parser * parser,const char * gmsgid,rich_location * richloc)946 c_parser_error_richloc (c_parser *parser, const char *gmsgid,
947 			rich_location *richloc)
948 {
949   c_token *token = c_parser_peek_token (parser);
950   if (parser->error)
951     return false;
952   parser->error = true;
953   if (!gmsgid)
954     return false;
955 
956   /* If this is actually a conflict marker, report it as such.  */
957   if (token->type == CPP_LSHIFT
958       || token->type == CPP_RSHIFT
959       || token->type == CPP_EQ_EQ)
960     {
961       location_t loc;
962       if (c_parser_peek_conflict_marker (parser, token->type, &loc))
963 	{
964 	  error_at (loc, "version control conflict marker in file");
965 	  return true;
966 	}
967     }
968 
969   c_parse_error (gmsgid,
970 		 /* Because c_parse_error does not understand
971 		    CPP_KEYWORD, keywords are treated like
972 		    identifiers.  */
973 		 (token->type == CPP_KEYWORD ? CPP_NAME : token->type),
974 		 /* ??? The C parser does not save the cpp flags of a
975 		    token, we need to pass 0 here and we will not get
976 		    the source spelling of some tokens but rather the
977 		    canonical spelling.  */
978 		 token->value, /*flags=*/0, richloc);
979   return true;
980 }
981 
982 /* As c_parser_error_richloc, but issue the message at the
983    location of PARSER's next token, or at input_location
984    if the next token is EOF.  */
985 
986 bool
c_parser_error(c_parser * parser,const char * gmsgid)987 c_parser_error (c_parser *parser, const char *gmsgid)
988 {
989   c_token *token = c_parser_peek_token (parser);
990   c_parser_set_source_position_from_token (token);
991   rich_location richloc (line_table, input_location);
992   return c_parser_error_richloc (parser, gmsgid, &richloc);
993 }
994 
995 /* Some tokens naturally come in pairs e.g.'(' and ')'.
996    This class is for tracking such a matching pair of symbols.
997    In particular, it tracks the location of the first token,
998    so that if the second token is missing, we can highlight the
999    location of the first token when notifying the user about the
1000    problem.  */
1001 
1002 template <typename traits_t>
1003 class token_pair
1004 {
1005  public:
1006   /* token_pair's ctor.  */
token_pair()1007   token_pair () : m_open_loc (UNKNOWN_LOCATION) {}
1008 
1009   /* If the next token is the opening symbol for this pair, consume it and
1010      return true.
1011      Otherwise, issue an error and return false.
1012      In either case, record the location of the opening token.  */
1013 
require_open(c_parser * parser)1014   bool require_open (c_parser *parser)
1015   {
1016     c_token *token = c_parser_peek_token (parser);
1017     if (token)
1018       m_open_loc = token->location;
1019 
1020     return c_parser_require (parser, traits_t::open_token_type,
1021 			     traits_t::open_gmsgid);
1022   }
1023 
1024   /* Consume the next token from PARSER, recording its location as
1025      that of the opening token within the pair.  */
1026 
consume_open(c_parser * parser)1027   void consume_open (c_parser *parser)
1028   {
1029     c_token *token = c_parser_peek_token (parser);
1030     gcc_assert (token->type == traits_t::open_token_type);
1031     m_open_loc = token->location;
1032     c_parser_consume_token (parser);
1033   }
1034 
1035   /* If the next token is the closing symbol for this pair, consume it
1036      and return true.
1037      Otherwise, issue an error, highlighting the location of the
1038      corresponding opening token, and return false.  */
1039 
require_close(c_parser * parser)1040   bool require_close (c_parser *parser) const
1041   {
1042     return c_parser_require (parser, traits_t::close_token_type,
1043 			     traits_t::close_gmsgid, m_open_loc);
1044   }
1045 
1046   /* Like token_pair::require_close, except that tokens will be skipped
1047      until the desired token is found.  An error message is still produced
1048      if the next token is not as expected.  */
1049 
skip_until_found_close(c_parser * parser)1050   void skip_until_found_close (c_parser *parser) const
1051   {
1052     c_parser_skip_until_found (parser, traits_t::close_token_type,
1053 			       traits_t::close_gmsgid, m_open_loc);
1054   }
1055 
1056  private:
1057   location_t m_open_loc;
1058 };
1059 
1060 /* Traits for token_pair<T> for tracking matching pairs of parentheses.  */
1061 
1062 struct matching_paren_traits
1063 {
1064   static const enum cpp_ttype open_token_type = CPP_OPEN_PAREN;
1065   static const char * const open_gmsgid;
1066   static const enum cpp_ttype close_token_type = CPP_CLOSE_PAREN;
1067   static const char * const close_gmsgid;
1068 };
1069 
1070 const char * const matching_paren_traits::open_gmsgid = "expected %<(%>";
1071 const char * const matching_paren_traits::close_gmsgid = "expected %<)%>";
1072 
1073 /* "matching_parens" is a token_pair<T> class for tracking matching
1074    pairs of parentheses.  */
1075 
1076 typedef token_pair<matching_paren_traits> matching_parens;
1077 
1078 /* Traits for token_pair<T> for tracking matching pairs of braces.  */
1079 
1080 struct matching_brace_traits
1081 {
1082   static const enum cpp_ttype open_token_type = CPP_OPEN_BRACE;
1083   static const char * const open_gmsgid;
1084   static const enum cpp_ttype close_token_type = CPP_CLOSE_BRACE;
1085   static const char * const close_gmsgid;
1086 };
1087 
1088 const char * const matching_brace_traits::open_gmsgid = "expected %<{%>";
1089 const char * const matching_brace_traits::close_gmsgid = "expected %<}%>";
1090 
1091 /* "matching_braces" is a token_pair<T> class for tracking matching
1092    pairs of braces.  */
1093 
1094 typedef token_pair<matching_brace_traits> matching_braces;
1095 
1096 /* Get a description of the matching symbol to TYPE e.g. "(" for
1097    CPP_CLOSE_PAREN.  */
1098 
1099 static const char *
get_matching_symbol(enum cpp_ttype type)1100 get_matching_symbol (enum cpp_ttype type)
1101 {
1102   switch (type)
1103     {
1104     default:
1105       gcc_unreachable ();
1106       return "";
1107     case CPP_CLOSE_PAREN:
1108       return "(";
1109     case CPP_CLOSE_BRACE:
1110       return "{";
1111     }
1112 }
1113 
1114 /* If the next token is of the indicated TYPE, consume it.  Otherwise,
1115    issue the error MSGID.  If MSGID is NULL then a message has already
1116    been produced and no message will be produced this time.  Returns
1117    true if found, false otherwise.
1118 
1119    If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1120    within any error as the location of an "opening" token matching
1121    the close token TYPE (e.g. the location of the '(' when TYPE is
1122    CPP_CLOSE_PAREN).
1123 
1124    If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly
1125    one type (e.g. "expected %<)%>") and thus it may be reasonable to
1126    attempt to generate a fix-it hint for the problem.
1127    Otherwise msgid describes multiple token types (e.g.
1128    "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to
1129    generate a fix-it hint.  */
1130 
1131 bool
c_parser_require(c_parser * parser,enum cpp_ttype type,const char * msgid,location_t matching_location,bool type_is_unique)1132 c_parser_require (c_parser *parser,
1133 		  enum cpp_ttype type,
1134 		  const char *msgid,
1135 		  location_t matching_location,
1136 		  bool type_is_unique)
1137 {
1138   if (c_parser_next_token_is (parser, type))
1139     {
1140       c_parser_consume_token (parser);
1141       return true;
1142     }
1143   else
1144     {
1145       location_t next_token_loc = c_parser_peek_token (parser)->location;
1146       gcc_rich_location richloc (next_token_loc);
1147 
1148       /* Potentially supply a fix-it hint, suggesting to add the
1149 	 missing token immediately after the *previous* token.
1150 	 This may move the primary location within richloc.  */
1151       if (!parser->error && type_is_unique)
1152 	maybe_suggest_missing_token_insertion (&richloc, type,
1153 					       parser->last_token_location);
1154 
1155       /* If matching_location != UNKNOWN_LOCATION, highlight it.
1156 	 Attempt to consolidate diagnostics by printing it as a
1157 	 secondary range within the main diagnostic.  */
1158       bool added_matching_location = false;
1159       if (matching_location != UNKNOWN_LOCATION)
1160 	added_matching_location
1161 	  = richloc.add_location_if_nearby (matching_location);
1162 
1163       if (c_parser_error_richloc (parser, msgid, &richloc))
1164 	/* If we weren't able to consolidate matching_location, then
1165 	   print it as a secondary diagnostic.  */
1166 	if (matching_location != UNKNOWN_LOCATION && !added_matching_location)
1167 	  inform (matching_location, "to match this %qs",
1168 		  get_matching_symbol (type));
1169 
1170       return false;
1171     }
1172 }
1173 
1174 /* If the next token is the indicated keyword, consume it.  Otherwise,
1175    issue the error MSGID.  Returns true if found, false otherwise.  */
1176 
1177 static bool
c_parser_require_keyword(c_parser * parser,enum rid keyword,const char * msgid)1178 c_parser_require_keyword (c_parser *parser,
1179 			  enum rid keyword,
1180 			  const char *msgid)
1181 {
1182   if (c_parser_next_token_is_keyword (parser, keyword))
1183     {
1184       c_parser_consume_token (parser);
1185       return true;
1186     }
1187   else
1188     {
1189       c_parser_error (parser, msgid);
1190       return false;
1191     }
1192 }
1193 
1194 /* Like c_parser_require, except that tokens will be skipped until the
1195    desired token is found.  An error message is still produced if the
1196    next token is not as expected.  If MSGID is NULL then a message has
1197    already been produced and no message will be produced this
1198    time.
1199 
1200    If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1201    within any error as the location of an "opening" token matching
1202    the close token TYPE (e.g. the location of the '(' when TYPE is
1203    CPP_CLOSE_PAREN).  */
1204 
1205 void
c_parser_skip_until_found(c_parser * parser,enum cpp_ttype type,const char * msgid,location_t matching_location)1206 c_parser_skip_until_found (c_parser *parser,
1207 			   enum cpp_ttype type,
1208 			   const char *msgid,
1209 			   location_t matching_location)
1210 {
1211   unsigned nesting_depth = 0;
1212 
1213   if (c_parser_require (parser, type, msgid, matching_location))
1214     return;
1215 
1216   /* Skip tokens until the desired token is found.  */
1217   while (true)
1218     {
1219       /* Peek at the next token.  */
1220       c_token *token = c_parser_peek_token (parser);
1221       /* If we've reached the token we want, consume it and stop.  */
1222       if (token->type == type && !nesting_depth)
1223 	{
1224 	  c_parser_consume_token (parser);
1225 	  break;
1226 	}
1227 
1228       /* If we've run out of tokens, stop.  */
1229       if (token->type == CPP_EOF)
1230 	return;
1231       if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1232 	return;
1233       if (token->type == CPP_OPEN_BRACE
1234 	  || token->type == CPP_OPEN_PAREN
1235 	  || token->type == CPP_OPEN_SQUARE)
1236 	++nesting_depth;
1237       else if (token->type == CPP_CLOSE_BRACE
1238 	       || token->type == CPP_CLOSE_PAREN
1239 	       || token->type == CPP_CLOSE_SQUARE)
1240 	{
1241 	  if (nesting_depth-- == 0)
1242 	    break;
1243 	}
1244       /* Consume this token.  */
1245       c_parser_consume_token (parser);
1246     }
1247   parser->error = false;
1248 }
1249 
1250 /* Skip tokens until the end of a parameter is found, but do not
1251    consume the comma, semicolon or closing delimiter.  */
1252 
1253 static void
c_parser_skip_to_end_of_parameter(c_parser * parser)1254 c_parser_skip_to_end_of_parameter (c_parser *parser)
1255 {
1256   unsigned nesting_depth = 0;
1257 
1258   while (true)
1259     {
1260       c_token *token = c_parser_peek_token (parser);
1261       if ((token->type == CPP_COMMA || token->type == CPP_SEMICOLON)
1262 	  && !nesting_depth)
1263 	break;
1264       /* If we've run out of tokens, stop.  */
1265       if (token->type == CPP_EOF)
1266 	return;
1267       if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1268 	return;
1269       if (token->type == CPP_OPEN_BRACE
1270 	  || token->type == CPP_OPEN_PAREN
1271 	  || token->type == CPP_OPEN_SQUARE)
1272 	++nesting_depth;
1273       else if (token->type == CPP_CLOSE_BRACE
1274 	       || token->type == CPP_CLOSE_PAREN
1275 	       || token->type == CPP_CLOSE_SQUARE)
1276 	{
1277 	  if (nesting_depth-- == 0)
1278 	    break;
1279 	}
1280       /* Consume this token.  */
1281       c_parser_consume_token (parser);
1282     }
1283   parser->error = false;
1284 }
1285 
1286 /* Expect to be at the end of the pragma directive and consume an
1287    end of line marker.  */
1288 
1289 static void
1290 c_parser_skip_to_pragma_eol (c_parser *parser, bool error_if_not_eol = true)
1291 {
1292   gcc_assert (parser->in_pragma);
1293   parser->in_pragma = false;
1294 
1295   if (error_if_not_eol && c_parser_peek_token (parser)->type != CPP_PRAGMA_EOL)
1296     c_parser_error (parser, "expected end of line");
1297 
1298   cpp_ttype token_type;
1299   do
1300     {
1301       c_token *token = c_parser_peek_token (parser);
1302       token_type = token->type;
1303       if (token_type == CPP_EOF)
1304 	break;
1305       c_parser_consume_token (parser);
1306     }
1307   while (token_type != CPP_PRAGMA_EOL);
1308 
1309   parser->error = false;
1310 }
1311 
1312 /* Skip tokens until we have consumed an entire block, or until we
1313    have consumed a non-nested ';'.  */
1314 
1315 static void
c_parser_skip_to_end_of_block_or_statement(c_parser * parser)1316 c_parser_skip_to_end_of_block_or_statement (c_parser *parser)
1317 {
1318   unsigned nesting_depth = 0;
1319   bool save_error = parser->error;
1320 
1321   while (true)
1322     {
1323       c_token *token;
1324 
1325       /* Peek at the next token.  */
1326       token = c_parser_peek_token (parser);
1327 
1328       switch (token->type)
1329 	{
1330 	case CPP_EOF:
1331 	  return;
1332 
1333 	case CPP_PRAGMA_EOL:
1334 	  if (parser->in_pragma)
1335 	    return;
1336 	  break;
1337 
1338 	case CPP_SEMICOLON:
1339 	  /* If the next token is a ';', we have reached the
1340 	     end of the statement.  */
1341 	  if (!nesting_depth)
1342 	    {
1343 	      /* Consume the ';'.  */
1344 	      c_parser_consume_token (parser);
1345 	      goto finished;
1346 	    }
1347 	  break;
1348 
1349 	case CPP_CLOSE_BRACE:
1350 	  /* If the next token is a non-nested '}', then we have
1351 	     reached the end of the current block.  */
1352 	  if (nesting_depth == 0 || --nesting_depth == 0)
1353 	    {
1354 	      c_parser_consume_token (parser);
1355 	      goto finished;
1356 	    }
1357 	  break;
1358 
1359 	case CPP_OPEN_BRACE:
1360 	  /* If it the next token is a '{', then we are entering a new
1361 	     block.  Consume the entire block.  */
1362 	  ++nesting_depth;
1363 	  break;
1364 
1365 	case CPP_PRAGMA:
1366 	  /* If we see a pragma, consume the whole thing at once.  We
1367 	     have some safeguards against consuming pragmas willy-nilly.
1368 	     Normally, we'd expect to be here with parser->error set,
1369 	     which disables these safeguards.  But it's possible to get
1370 	     here for secondary error recovery, after parser->error has
1371 	     been cleared.  */
1372 	  c_parser_consume_pragma (parser);
1373 	  c_parser_skip_to_pragma_eol (parser);
1374 	  parser->error = save_error;
1375 	  continue;
1376 
1377 	default:
1378 	  break;
1379 	}
1380 
1381       c_parser_consume_token (parser);
1382     }
1383 
1384  finished:
1385   parser->error = false;
1386 }
1387 
1388 /* CPP's options (initialized by c-opts.c).  */
1389 extern cpp_options *cpp_opts;
1390 
1391 /* Save the warning flags which are controlled by __extension__.  */
1392 
1393 static inline int
disable_extension_diagnostics(void)1394 disable_extension_diagnostics (void)
1395 {
1396   int ret = (pedantic
1397 	     | (warn_pointer_arith << 1)
1398 	     | (warn_traditional << 2)
1399 	     | (flag_iso << 3)
1400 	     | (warn_long_long << 4)
1401 	     | (warn_cxx_compat << 5)
1402 	     | (warn_overlength_strings << 6)
1403 	     /* warn_c90_c99_compat has three states: -1/0/1, so we must
1404 		play tricks to properly restore it.  */
1405 	     | ((warn_c90_c99_compat == 1) << 7)
1406 	     | ((warn_c90_c99_compat == -1) << 8)
1407 	     /* Similarly for warn_c99_c11_compat.  */
1408 	     | ((warn_c99_c11_compat == 1) << 9)
1409 	     | ((warn_c99_c11_compat == -1) << 10)
1410 	     /* Similarly for warn_c11_c2x_compat.  */
1411 	     | ((warn_c11_c2x_compat == 1) << 11)
1412 	     | ((warn_c11_c2x_compat == -1) << 12)
1413 	     );
1414   cpp_opts->cpp_pedantic = pedantic = 0;
1415   warn_pointer_arith = 0;
1416   cpp_opts->cpp_warn_traditional = warn_traditional = 0;
1417   flag_iso = 0;
1418   cpp_opts->cpp_warn_long_long = warn_long_long = 0;
1419   warn_cxx_compat = 0;
1420   warn_overlength_strings = 0;
1421   warn_c90_c99_compat = 0;
1422   warn_c99_c11_compat = 0;
1423   warn_c11_c2x_compat = 0;
1424   return ret;
1425 }
1426 
1427 /* Restore the warning flags which are controlled by __extension__.
1428    FLAGS is the return value from disable_extension_diagnostics.  */
1429 
1430 static inline void
restore_extension_diagnostics(int flags)1431 restore_extension_diagnostics (int flags)
1432 {
1433   cpp_opts->cpp_pedantic = pedantic = flags & 1;
1434   warn_pointer_arith = (flags >> 1) & 1;
1435   cpp_opts->cpp_warn_traditional = warn_traditional = (flags >> 2) & 1;
1436   flag_iso = (flags >> 3) & 1;
1437   cpp_opts->cpp_warn_long_long = warn_long_long = (flags >> 4) & 1;
1438   warn_cxx_compat = (flags >> 5) & 1;
1439   warn_overlength_strings = (flags >> 6) & 1;
1440   /* See above for why is this needed.  */
1441   warn_c90_c99_compat = (flags >> 7) & 1 ? 1 : ((flags >> 8) & 1 ? -1 : 0);
1442   warn_c99_c11_compat = (flags >> 9) & 1 ? 1 : ((flags >> 10) & 1 ? -1 : 0);
1443   warn_c11_c2x_compat = (flags >> 11) & 1 ? 1 : ((flags >> 12) & 1 ? -1 : 0);
1444 }
1445 
1446 /* Helper data structure for parsing #pragma acc routine.  */
1447 struct oacc_routine_data {
1448   bool error_seen; /* Set if error has been reported.  */
1449   bool fndecl_seen; /* Set if one fn decl/definition has been seen already.  */
1450   tree clauses;
1451   location_t loc;
1452 };
1453 
1454 static bool c_parser_nth_token_starts_std_attributes (c_parser *,
1455 						      unsigned int);
1456 static tree c_parser_std_attribute_specifier_sequence (c_parser *);
1457 static void c_parser_external_declaration (c_parser *);
1458 static void c_parser_asm_definition (c_parser *);
1459 static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
1460 					   bool, bool, tree *, vec<c_token>,
1461 					   bool have_attrs = false,
1462 					   tree attrs = NULL,
1463 					   struct oacc_routine_data * = NULL,
1464 					   bool * = NULL);
1465 static void c_parser_static_assert_declaration_no_semi (c_parser *);
1466 static void c_parser_static_assert_declaration (c_parser *);
1467 static struct c_typespec c_parser_enum_specifier (c_parser *);
1468 static struct c_typespec c_parser_struct_or_union_specifier (c_parser *);
1469 static tree c_parser_struct_declaration (c_parser *);
1470 static struct c_typespec c_parser_typeof_specifier (c_parser *);
1471 static tree c_parser_alignas_specifier (c_parser *);
1472 static struct c_declarator *c_parser_direct_declarator (c_parser *, bool,
1473 							c_dtr_syn, bool *);
1474 static struct c_declarator *c_parser_direct_declarator_inner (c_parser *,
1475 							      bool,
1476 							      struct c_declarator *);
1477 static struct c_arg_info *c_parser_parms_declarator (c_parser *, bool, tree,
1478 						     bool);
1479 static struct c_arg_info *c_parser_parms_list_declarator (c_parser *, tree,
1480 							  tree, bool);
1481 static struct c_parm *c_parser_parameter_declaration (c_parser *, tree, bool);
1482 static tree c_parser_simple_asm_expr (c_parser *);
1483 static tree c_parser_gnu_attributes (c_parser *);
1484 static struct c_expr c_parser_initializer (c_parser *);
1485 static struct c_expr c_parser_braced_init (c_parser *, tree, bool,
1486 					   struct obstack *);
1487 static void c_parser_initelt (c_parser *, struct obstack *);
1488 static void c_parser_initval (c_parser *, struct c_expr *,
1489 			      struct obstack *);
1490 static tree c_parser_compound_statement (c_parser *, location_t * = NULL);
1491 static location_t c_parser_compound_statement_nostart (c_parser *);
1492 static void c_parser_label (c_parser *);
1493 static void c_parser_statement (c_parser *, bool *, location_t * = NULL);
1494 static void c_parser_statement_after_labels (c_parser *, bool *,
1495 					     vec<tree> * = NULL);
1496 static tree c_parser_c99_block_statement (c_parser *, bool *,
1497 					  location_t * = NULL);
1498 static void c_parser_if_statement (c_parser *, bool *, vec<tree> *);
1499 static void c_parser_switch_statement (c_parser *, bool *);
1500 static void c_parser_while_statement (c_parser *, bool, unsigned short, bool *);
1501 static void c_parser_do_statement (c_parser *, bool, unsigned short);
1502 static void c_parser_for_statement (c_parser *, bool, unsigned short, bool *);
1503 static tree c_parser_asm_statement (c_parser *);
1504 static tree c_parser_asm_operands (c_parser *);
1505 static tree c_parser_asm_goto_operands (c_parser *);
1506 static tree c_parser_asm_clobbers (c_parser *);
1507 static struct c_expr c_parser_expr_no_commas (c_parser *, struct c_expr *,
1508 					      tree = NULL_TREE);
1509 static struct c_expr c_parser_conditional_expression (c_parser *,
1510 						      struct c_expr *, tree);
1511 static struct c_expr c_parser_binary_expression (c_parser *, struct c_expr *,
1512 						 tree);
1513 static struct c_expr c_parser_cast_expression (c_parser *, struct c_expr *);
1514 static struct c_expr c_parser_unary_expression (c_parser *);
1515 static struct c_expr c_parser_sizeof_expression (c_parser *);
1516 static struct c_expr c_parser_alignof_expression (c_parser *);
1517 static struct c_expr c_parser_postfix_expression (c_parser *);
1518 static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *,
1519 								   struct c_type_name *,
1520 								   location_t);
1521 static struct c_expr c_parser_postfix_expression_after_primary (c_parser *,
1522 								location_t loc,
1523 								struct c_expr);
1524 static tree c_parser_transaction (c_parser *, enum rid);
1525 static struct c_expr c_parser_transaction_expression (c_parser *, enum rid);
1526 static tree c_parser_transaction_cancel (c_parser *);
1527 static struct c_expr c_parser_expression (c_parser *);
1528 static struct c_expr c_parser_expression_conv (c_parser *);
1529 static vec<tree, va_gc> *c_parser_expr_list (c_parser *, bool, bool,
1530 					     vec<tree, va_gc> **, location_t *,
1531 					     tree *, vec<location_t> *,
1532 					     unsigned int * = NULL);
1533 static struct c_expr c_parser_has_attribute_expression (c_parser *);
1534 
1535 static void c_parser_oacc_declare (c_parser *);
1536 static void c_parser_oacc_enter_exit_data (c_parser *, bool);
1537 static void c_parser_oacc_update (c_parser *);
1538 static void c_parser_omp_construct (c_parser *, bool *);
1539 static void c_parser_omp_threadprivate (c_parser *);
1540 static void c_parser_omp_barrier (c_parser *);
1541 static void c_parser_omp_depobj (c_parser *);
1542 static void c_parser_omp_flush (c_parser *);
1543 static tree c_parser_omp_for_loop (location_t, c_parser *, enum tree_code,
1544 				   tree, tree *, bool *);
1545 static void c_parser_omp_taskwait (c_parser *);
1546 static void c_parser_omp_taskyield (c_parser *);
1547 static void c_parser_omp_cancel (c_parser *);
1548 
1549 enum pragma_context { pragma_external, pragma_struct, pragma_param,
1550 		      pragma_stmt, pragma_compound };
1551 static bool c_parser_pragma (c_parser *, enum pragma_context, bool *);
1552 static void c_parser_omp_cancellation_point (c_parser *, enum pragma_context);
1553 static bool c_parser_omp_target (c_parser *, enum pragma_context, bool *);
1554 static void c_parser_omp_end_declare_target (c_parser *);
1555 static void c_parser_omp_declare (c_parser *, enum pragma_context);
1556 static void c_parser_omp_requires (c_parser *);
1557 static bool c_parser_omp_ordered (c_parser *, enum pragma_context, bool *);
1558 static void c_parser_oacc_routine (c_parser *, enum pragma_context);
1559 
1560 /* These Objective-C parser functions are only ever called when
1561    compiling Objective-C.  */
1562 static void c_parser_objc_class_definition (c_parser *, tree);
1563 static void c_parser_objc_class_instance_variables (c_parser *);
1564 static void c_parser_objc_class_declaration (c_parser *);
1565 static void c_parser_objc_alias_declaration (c_parser *);
1566 static void c_parser_objc_protocol_definition (c_parser *, tree);
1567 static bool c_parser_objc_method_type (c_parser *);
1568 static void c_parser_objc_method_definition (c_parser *);
1569 static void c_parser_objc_methodprotolist (c_parser *);
1570 static void c_parser_objc_methodproto (c_parser *);
1571 static tree c_parser_objc_method_decl (c_parser *, bool, tree *, tree *);
1572 static tree c_parser_objc_type_name (c_parser *);
1573 static tree c_parser_objc_protocol_refs (c_parser *);
1574 static void c_parser_objc_try_catch_finally_statement (c_parser *);
1575 static void c_parser_objc_synchronized_statement (c_parser *);
1576 static tree c_parser_objc_selector (c_parser *);
1577 static tree c_parser_objc_selector_arg (c_parser *);
1578 static tree c_parser_objc_receiver (c_parser *);
1579 static tree c_parser_objc_message_args (c_parser *);
1580 static tree c_parser_objc_keywordexpr (c_parser *);
1581 static void c_parser_objc_at_property_declaration (c_parser *);
1582 static void c_parser_objc_at_synthesize_declaration (c_parser *);
1583 static void c_parser_objc_at_dynamic_declaration (c_parser *);
1584 static bool c_parser_objc_diagnose_bad_element_prefix
1585   (c_parser *, struct c_declspecs *);
1586 static location_t c_parser_parse_rtl_body (c_parser *, char *);
1587 
1588 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
1589 
1590    translation-unit:
1591      external-declarations
1592 
1593    external-declarations:
1594      external-declaration
1595      external-declarations external-declaration
1596 
1597    GNU extensions:
1598 
1599    translation-unit:
1600      empty
1601 */
1602 
1603 static void
c_parser_translation_unit(c_parser * parser)1604 c_parser_translation_unit (c_parser *parser)
1605 {
1606   if (c_parser_next_token_is (parser, CPP_EOF))
1607     {
1608       pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1609 	       "ISO C forbids an empty translation unit");
1610     }
1611   else
1612     {
1613       void *obstack_position = obstack_alloc (&parser_obstack, 0);
1614       mark_valid_location_for_stdc_pragma (false);
1615       do
1616 	{
1617 	  ggc_collect ();
1618 	  c_parser_external_declaration (parser);
1619 	  obstack_free (&parser_obstack, obstack_position);
1620 	}
1621       while (c_parser_next_token_is_not (parser, CPP_EOF));
1622     }
1623 
1624   unsigned int i;
1625   tree decl;
1626   FOR_EACH_VEC_ELT (incomplete_record_decls, i, decl)
1627     if (DECL_SIZE (decl) == NULL_TREE && TREE_TYPE (decl) != error_mark_node)
1628       error ("storage size of %q+D isn%'t known", decl);
1629 
1630   if (current_omp_declare_target_attribute)
1631     {
1632       if (!errorcount)
1633         error ("%<#pragma omp declare target%> without corresponding "
1634 	       "%<#pragma omp end declare target%>");
1635       current_omp_declare_target_attribute = 0;
1636     }
1637 }
1638 
1639 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
1640 
1641    external-declaration:
1642      function-definition
1643      declaration
1644 
1645    GNU extensions:
1646 
1647    external-declaration:
1648      asm-definition
1649      ;
1650      __extension__ external-declaration
1651 
1652    Objective-C:
1653 
1654    external-declaration:
1655      objc-class-definition
1656      objc-class-declaration
1657      objc-alias-declaration
1658      objc-protocol-definition
1659      objc-method-definition
1660      @end
1661 */
1662 
1663 static void
c_parser_external_declaration(c_parser * parser)1664 c_parser_external_declaration (c_parser *parser)
1665 {
1666   int ext;
1667   switch (c_parser_peek_token (parser)->type)
1668     {
1669     case CPP_KEYWORD:
1670       switch (c_parser_peek_token (parser)->keyword)
1671 	{
1672 	case RID_EXTENSION:
1673 	  ext = disable_extension_diagnostics ();
1674 	  c_parser_consume_token (parser);
1675 	  c_parser_external_declaration (parser);
1676 	  restore_extension_diagnostics (ext);
1677 	  break;
1678 	case RID_ASM:
1679 	  c_parser_asm_definition (parser);
1680 	  break;
1681 	case RID_AT_INTERFACE:
1682 	case RID_AT_IMPLEMENTATION:
1683 	  gcc_assert (c_dialect_objc ());
1684 	  c_parser_objc_class_definition (parser, NULL_TREE);
1685 	  break;
1686 	case RID_AT_CLASS:
1687 	  gcc_assert (c_dialect_objc ());
1688 	  c_parser_objc_class_declaration (parser);
1689 	  break;
1690 	case RID_AT_ALIAS:
1691 	  gcc_assert (c_dialect_objc ());
1692 	  c_parser_objc_alias_declaration (parser);
1693 	  break;
1694 	case RID_AT_PROTOCOL:
1695 	  gcc_assert (c_dialect_objc ());
1696 	  c_parser_objc_protocol_definition (parser, NULL_TREE);
1697 	  break;
1698 	case RID_AT_PROPERTY:
1699 	  gcc_assert (c_dialect_objc ());
1700 	  c_parser_objc_at_property_declaration (parser);
1701 	  break;
1702 	case RID_AT_SYNTHESIZE:
1703 	  gcc_assert (c_dialect_objc ());
1704 	  c_parser_objc_at_synthesize_declaration (parser);
1705 	  break;
1706 	case RID_AT_DYNAMIC:
1707 	  gcc_assert (c_dialect_objc ());
1708 	  c_parser_objc_at_dynamic_declaration (parser);
1709 	  break;
1710 	case RID_AT_END:
1711 	  gcc_assert (c_dialect_objc ());
1712 	  c_parser_consume_token (parser);
1713 	  objc_finish_implementation ();
1714 	  break;
1715 	default:
1716 	  goto decl_or_fndef;
1717 	}
1718       break;
1719     case CPP_SEMICOLON:
1720       pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1721 	       "ISO C does not allow extra %<;%> outside of a function");
1722       c_parser_consume_token (parser);
1723       break;
1724     case CPP_PRAGMA:
1725       mark_valid_location_for_stdc_pragma (true);
1726       c_parser_pragma (parser, pragma_external, NULL);
1727       mark_valid_location_for_stdc_pragma (false);
1728       break;
1729     case CPP_PLUS:
1730     case CPP_MINUS:
1731       if (c_dialect_objc ())
1732 	{
1733 	  c_parser_objc_method_definition (parser);
1734 	  break;
1735 	}
1736       /* Else fall through, and yield a syntax error trying to parse
1737 	 as a declaration or function definition.  */
1738       /* FALLTHRU */
1739     default:
1740     decl_or_fndef:
1741       /* A declaration or a function definition (or, in Objective-C,
1742 	 an @interface or @protocol with prefix attributes).  We can
1743 	 only tell which after parsing the declaration specifiers, if
1744 	 any, and the first declarator.  */
1745       c_parser_declaration_or_fndef (parser, true, true, true, false, true,
1746 				     NULL, vNULL);
1747       break;
1748     }
1749 }
1750 
1751 static void c_finish_omp_declare_simd (c_parser *, tree, tree, vec<c_token>);
1752 static void c_finish_oacc_routine (struct oacc_routine_data *, tree, bool);
1753 
1754 /* Build and add a DEBUG_BEGIN_STMT statement with location LOC.  */
1755 
1756 static void
add_debug_begin_stmt(location_t loc)1757 add_debug_begin_stmt (location_t loc)
1758 {
1759   /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721.  */
1760   if (!MAY_HAVE_DEBUG_MARKER_STMTS || !building_stmt_list_p ())
1761     return;
1762 
1763   tree stmt = build0 (DEBUG_BEGIN_STMT, void_type_node);
1764   SET_EXPR_LOCATION (stmt, loc);
1765   add_stmt (stmt);
1766 }
1767 
1768 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
1769    6.7, 6.9.1, C11 6.7, 6.9.1).  If FNDEF_OK is true, a function definition
1770    is accepted; otherwise (old-style parameter declarations) only other
1771    declarations are accepted.  If STATIC_ASSERT_OK is true, a static
1772    assertion is accepted; otherwise (old-style parameter declarations)
1773    it is not.  If NESTED is true, we are inside a function or parsing
1774    old-style parameter declarations; any functions encountered are
1775    nested functions and declaration specifiers are required; otherwise
1776    we are at top level and functions are normal functions and
1777    declaration specifiers may be optional.  If EMPTY_OK is true, empty
1778    declarations are OK (subject to all other constraints); otherwise
1779    (old-style parameter declarations) they are diagnosed.  If
1780    START_ATTR_OK is true, the declaration specifiers may start with
1781    attributes (GNU or standard); otherwise they may not.
1782    OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
1783    declaration when parsing an Objective-C foreach statement.
1784    FALLTHRU_ATTR_P is used to signal whether this function parsed
1785    "__attribute__((fallthrough));".  ATTRS are any standard attributes
1786    parsed in the caller (in contexts where such attributes had to be
1787    parsed to determine whether what follows is a declaration or a
1788    statement); HAVE_ATTRS says whether there were any such attributes
1789    (even empty).
1790 
1791    declaration:
1792      declaration-specifiers init-declarator-list[opt] ;
1793      static_assert-declaration
1794 
1795    function-definition:
1796      declaration-specifiers[opt] declarator declaration-list[opt]
1797        compound-statement
1798 
1799    declaration-list:
1800      declaration
1801      declaration-list declaration
1802 
1803    init-declarator-list:
1804      init-declarator
1805      init-declarator-list , init-declarator
1806 
1807    init-declarator:
1808      declarator simple-asm-expr[opt] gnu-attributes[opt]
1809      declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
1810 
1811    GNU extensions:
1812 
1813    nested-function-definition:
1814      declaration-specifiers declarator declaration-list[opt]
1815        compound-statement
1816 
1817    attribute ;
1818 
1819    Objective-C:
1820      gnu-attributes objc-class-definition
1821      gnu-attributes objc-category-definition
1822      gnu-attributes objc-protocol-definition
1823 
1824    The simple-asm-expr and gnu-attributes are GNU extensions.
1825 
1826    This function does not handle __extension__; that is handled in its
1827    callers.  ??? Following the old parser, __extension__ may start
1828    external declarations, declarations in functions and declarations
1829    at the start of "for" loops, but not old-style parameter
1830    declarations.
1831 
1832    C99 requires declaration specifiers in a function definition; the
1833    absence is diagnosed through the diagnosis of implicit int.  In GNU
1834    C we also allow but diagnose declarations without declaration
1835    specifiers, but only at top level (elsewhere they conflict with
1836    other syntax).
1837 
1838    In Objective-C, declarations of the looping variable in a foreach
1839    statement are exceptionally terminated by 'in' (for example, 'for
1840    (NSObject *object in array) { ... }').
1841 
1842    OpenMP:
1843 
1844    declaration:
1845      threadprivate-directive
1846 
1847    GIMPLE:
1848 
1849    gimple-function-definition:
1850      declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
1851        declaration-list[opt] compound-statement
1852 
1853    rtl-function-definition:
1854      declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
1855        declaration-list[opt] compound-statement  */
1856 
1857 static void
c_parser_declaration_or_fndef(c_parser * parser,bool fndef_ok,bool static_assert_ok,bool empty_ok,bool nested,bool start_attr_ok,tree * objc_foreach_object_declaration,vec<c_token> omp_declare_simd_clauses,bool have_attrs,tree attrs,struct oacc_routine_data * oacc_routine_data,bool * fallthru_attr_p)1858 c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
1859 			       bool static_assert_ok, bool empty_ok,
1860 			       bool nested, bool start_attr_ok,
1861 			       tree *objc_foreach_object_declaration,
1862 			       vec<c_token> omp_declare_simd_clauses,
1863 			       bool have_attrs, tree attrs,
1864 			       struct oacc_routine_data *oacc_routine_data,
1865 			       bool *fallthru_attr_p)
1866 {
1867   struct c_declspecs *specs;
1868   tree prefix_attrs;
1869   tree all_prefix_attrs;
1870   bool diagnosed_no_specs = false;
1871   location_t here = c_parser_peek_token (parser)->location;
1872 
1873   add_debug_begin_stmt (c_parser_peek_token (parser)->location);
1874 
1875   if (static_assert_ok
1876       && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
1877     {
1878       c_parser_static_assert_declaration (parser);
1879       return;
1880     }
1881   specs = build_null_declspecs ();
1882 
1883   /* Handle any standard attributes parsed in the caller.  */
1884   if (have_attrs)
1885     {
1886       declspecs_add_attrs (here, specs, attrs);
1887       specs->non_std_attrs_seen_p = false;
1888     }
1889 
1890   /* Try to detect an unknown type name when we have "A B" or "A *B".  */
1891   if (c_parser_peek_token (parser)->type == CPP_NAME
1892       && c_parser_peek_token (parser)->id_kind == C_ID_ID
1893       && (c_parser_peek_2nd_token (parser)->type == CPP_NAME
1894           || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
1895       && (!nested || !lookup_name (c_parser_peek_token (parser)->value)))
1896     {
1897       tree name = c_parser_peek_token (parser)->value;
1898 
1899       /* Issue a warning about NAME being an unknown type name, perhaps
1900 	 with some kind of hint.
1901 	 If the user forgot a "struct" etc, suggest inserting
1902 	 it.  Otherwise, attempt to look for misspellings.  */
1903       gcc_rich_location richloc (here);
1904       if (tag_exists_p (RECORD_TYPE, name))
1905 	{
1906 	  /* This is not C++ with its implicit typedef.  */
1907 	  richloc.add_fixit_insert_before ("struct ");
1908 	  error_at (&richloc,
1909 		    "unknown type name %qE;"
1910 		    " use %<struct%> keyword to refer to the type",
1911 		    name);
1912 	}
1913       else if (tag_exists_p (UNION_TYPE, name))
1914 	{
1915 	  richloc.add_fixit_insert_before ("union ");
1916 	  error_at (&richloc,
1917 		    "unknown type name %qE;"
1918 		    " use %<union%> keyword to refer to the type",
1919 		    name);
1920 	}
1921       else if (tag_exists_p (ENUMERAL_TYPE, name))
1922 	{
1923 	  richloc.add_fixit_insert_before ("enum ");
1924 	  error_at (&richloc,
1925 		    "unknown type name %qE;"
1926 		    " use %<enum%> keyword to refer to the type",
1927 		    name);
1928 	}
1929       else
1930 	{
1931 	  auto_diagnostic_group d;
1932 	  name_hint hint = lookup_name_fuzzy (name, FUZZY_LOOKUP_TYPENAME,
1933 					      here);
1934 	  if (const char *suggestion = hint.suggestion ())
1935 	    {
1936 	      richloc.add_fixit_replace (suggestion);
1937 	      error_at (&richloc,
1938 			"unknown type name %qE; did you mean %qs?",
1939 			name, suggestion);
1940 	    }
1941 	  else
1942 	    error_at (here, "unknown type name %qE", name);
1943 	}
1944 
1945       /* Parse declspecs normally to get a correct pointer type, but avoid
1946          a further "fails to be a type name" error.  Refuse nested functions
1947          since it is not how the user likely wants us to recover.  */
1948       c_parser_peek_token (parser)->type = CPP_KEYWORD;
1949       c_parser_peek_token (parser)->keyword = RID_VOID;
1950       c_parser_peek_token (parser)->value = error_mark_node;
1951       fndef_ok = !nested;
1952     }
1953 
1954   /* When there are standard attributes at the start of the
1955      declaration (to apply to the entity being declared), an
1956      init-declarator-list or function definition must be present.  */
1957   if (c_parser_nth_token_starts_std_attributes (parser, 1))
1958     have_attrs = true;
1959 
1960   c_parser_declspecs (parser, specs, true, true, start_attr_ok,
1961 		      true, true, start_attr_ok, true, cla_nonabstract_decl);
1962   if (parser->error)
1963     {
1964       c_parser_skip_to_end_of_block_or_statement (parser);
1965       return;
1966     }
1967   if (nested && !specs->declspecs_seen_p)
1968     {
1969       c_parser_error (parser, "expected declaration specifiers");
1970       c_parser_skip_to_end_of_block_or_statement (parser);
1971       return;
1972     }
1973 
1974   finish_declspecs (specs);
1975   bool auto_type_p = specs->typespec_word == cts_auto_type;
1976   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
1977     {
1978       if (auto_type_p)
1979 	error_at (here, "%<__auto_type%> in empty declaration");
1980       else if (specs->typespec_kind == ctsk_none
1981 	       && attribute_fallthrough_p (specs->attrs))
1982 	{
1983 	  if (fallthru_attr_p != NULL)
1984 	    *fallthru_attr_p = true;
1985 	  if (nested)
1986 	    {
1987 	      tree fn = build_call_expr_internal_loc (here, IFN_FALLTHROUGH,
1988 						      void_type_node, 0);
1989 	      add_stmt (fn);
1990 	    }
1991 	  else
1992 	    pedwarn (here, OPT_Wattributes,
1993 		     "%<fallthrough%> attribute at top level");
1994 	}
1995       else if (empty_ok && !(have_attrs
1996 			     && specs->non_std_attrs_seen_p))
1997 	shadow_tag (specs);
1998       else
1999 	{
2000 	  shadow_tag_warned (specs, 1);
2001 	  pedwarn (here, 0, "empty declaration");
2002 	}
2003       c_parser_consume_token (parser);
2004       if (oacc_routine_data)
2005 	c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2006       return;
2007     }
2008 
2009   /* Provide better error recovery.  Note that a type name here is usually
2010      better diagnosed as a redeclaration.  */
2011   if (empty_ok
2012       && specs->typespec_kind == ctsk_tagdef
2013       && c_parser_next_token_starts_declspecs (parser)
2014       && !c_parser_next_token_is (parser, CPP_NAME))
2015     {
2016       c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
2017       parser->error = false;
2018       shadow_tag_warned (specs, 1);
2019       return;
2020     }
2021   else if (c_dialect_objc () && !auto_type_p)
2022     {
2023       /* Prefix attributes are an error on method decls.  */
2024       switch (c_parser_peek_token (parser)->type)
2025 	{
2026 	  case CPP_PLUS:
2027 	  case CPP_MINUS:
2028 	    if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2029 	      return;
2030 	    if (specs->attrs)
2031 	      {
2032 		warning_at (c_parser_peek_token (parser)->location,
2033 			    OPT_Wattributes,
2034 	       		    "prefix attributes are ignored for methods");
2035 		specs->attrs = NULL_TREE;
2036 	      }
2037 	    if (fndef_ok)
2038 	      c_parser_objc_method_definition (parser);
2039 	    else
2040 	      c_parser_objc_methodproto (parser);
2041 	    return;
2042 	    break;
2043 	  default:
2044 	    break;
2045 	}
2046       /* This is where we parse 'attributes @interface ...',
2047 	 'attributes @implementation ...', 'attributes @protocol ...'
2048 	 (where attributes could be, for example, __attribute__
2049 	 ((deprecated)).
2050       */
2051       switch (c_parser_peek_token (parser)->keyword)
2052 	{
2053 	case RID_AT_INTERFACE:
2054 	  {
2055 	    if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2056 	      return;
2057 	    c_parser_objc_class_definition (parser, specs->attrs);
2058 	    return;
2059 	  }
2060 	  break;
2061 	case RID_AT_IMPLEMENTATION:
2062 	  {
2063 	    if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2064 	      return;
2065 	    if (specs->attrs)
2066 	      {
2067 		warning_at (c_parser_peek_token (parser)->location,
2068 			OPT_Wattributes,
2069 			"prefix attributes are ignored for implementations");
2070 		specs->attrs = NULL_TREE;
2071 	      }
2072 	    c_parser_objc_class_definition (parser, NULL_TREE);
2073 	    return;
2074 	  }
2075 	  break;
2076 	case RID_AT_PROTOCOL:
2077 	  {
2078 	    if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2079 	      return;
2080 	    c_parser_objc_protocol_definition (parser, specs->attrs);
2081 	    return;
2082 	  }
2083 	  break;
2084 	case RID_AT_ALIAS:
2085 	case RID_AT_CLASS:
2086 	case RID_AT_END:
2087 	case RID_AT_PROPERTY:
2088 	  if (specs->attrs)
2089 	    {
2090 	      c_parser_error (parser, "unexpected attribute");
2091 	      specs->attrs = NULL;
2092 	    }
2093 	  break;
2094 	default:
2095 	  break;
2096 	}
2097     }
2098   else if (attribute_fallthrough_p (specs->attrs))
2099     warning_at (here, OPT_Wattributes,
2100 		"%<fallthrough%> attribute not followed by %<;%>");
2101 
2102   pending_xref_error ();
2103   prefix_attrs = specs->attrs;
2104   all_prefix_attrs = prefix_attrs;
2105   specs->attrs = NULL_TREE;
2106   while (true)
2107     {
2108       struct c_declarator *declarator;
2109       bool dummy = false;
2110       timevar_id_t tv;
2111       tree fnbody = NULL_TREE;
2112       /* Declaring either one or more declarators (in which case we
2113 	 should diagnose if there were no declaration specifiers) or a
2114 	 function definition (in which case the diagnostic for
2115 	 implicit int suffices).  */
2116       declarator = c_parser_declarator (parser,
2117 					specs->typespec_kind != ctsk_none,
2118 					C_DTR_NORMAL, &dummy);
2119       if (declarator == NULL)
2120 	{
2121 	  if (omp_declare_simd_clauses.exists ())
2122 	    c_finish_omp_declare_simd (parser, NULL_TREE, NULL_TREE,
2123 				       omp_declare_simd_clauses);
2124 	  if (oacc_routine_data)
2125 	    c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2126 	  c_parser_skip_to_end_of_block_or_statement (parser);
2127 	  return;
2128 	}
2129       if (auto_type_p && declarator->kind != cdk_id)
2130 	{
2131 	  error_at (here,
2132 		    "%<__auto_type%> requires a plain identifier"
2133 		    " as declarator");
2134 	  c_parser_skip_to_end_of_block_or_statement (parser);
2135 	  return;
2136 	}
2137       if (c_parser_next_token_is (parser, CPP_EQ)
2138 	  || c_parser_next_token_is (parser, CPP_COMMA)
2139 	  || c_parser_next_token_is (parser, CPP_SEMICOLON)
2140 	  || c_parser_next_token_is_keyword (parser, RID_ASM)
2141 	  || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)
2142 	  || c_parser_next_token_is_keyword (parser, RID_IN))
2143 	{
2144 	  tree asm_name = NULL_TREE;
2145 	  tree postfix_attrs = NULL_TREE;
2146 	  if (!diagnosed_no_specs && !specs->declspecs_seen_p)
2147 	    {
2148 	      diagnosed_no_specs = true;
2149 	      pedwarn (here, 0, "data definition has no type or storage class");
2150 	    }
2151 	  /* Having seen a data definition, there cannot now be a
2152 	     function definition.  */
2153 	  fndef_ok = false;
2154 	  if (c_parser_next_token_is_keyword (parser, RID_ASM))
2155 	    asm_name = c_parser_simple_asm_expr (parser);
2156 	  if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2157 	    {
2158 	      postfix_attrs = c_parser_gnu_attributes (parser);
2159 	      if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
2160 		{
2161 		  /* This means there is an attribute specifier after
2162 		     the declarator in a function definition.  Provide
2163 		     some more information for the user.  */
2164 		  error_at (here, "attributes should be specified before the "
2165 			    "declarator in a function definition");
2166 		  c_parser_skip_to_end_of_block_or_statement (parser);
2167 		  return;
2168 		}
2169 	    }
2170 	  if (c_parser_next_token_is (parser, CPP_EQ))
2171 	    {
2172 	      tree d;
2173 	      struct c_expr init;
2174 	      location_t init_loc;
2175 	      c_parser_consume_token (parser);
2176 	      if (auto_type_p)
2177 		{
2178 		  init_loc = c_parser_peek_token (parser)->location;
2179 		  rich_location richloc (line_table, init_loc);
2180 		  start_init (NULL_TREE, asm_name, global_bindings_p (), &richloc);
2181 		  /* A parameter is initialized, which is invalid.  Don't
2182 		     attempt to instrument the initializer.  */
2183 		  int flag_sanitize_save = flag_sanitize;
2184 		  if (nested && !empty_ok)
2185 		    flag_sanitize = 0;
2186 		  init = c_parser_expr_no_commas (parser, NULL);
2187 		  flag_sanitize = flag_sanitize_save;
2188 		  if (TREE_CODE (init.value) == COMPONENT_REF
2189 		      && DECL_C_BIT_FIELD (TREE_OPERAND (init.value, 1)))
2190 		    error_at (here,
2191 			      "%<__auto_type%> used with a bit-field"
2192 			      " initializer");
2193 		  init = convert_lvalue_to_rvalue (init_loc, init, true, true);
2194 		  tree init_type = TREE_TYPE (init.value);
2195 		  /* As with typeof, remove all qualifiers from atomic types.  */
2196 		  if (init_type != error_mark_node && TYPE_ATOMIC (init_type))
2197 		    init_type
2198 		      = c_build_qualified_type (init_type, TYPE_UNQUALIFIED);
2199 		  bool vm_type = variably_modified_type_p (init_type,
2200 							   NULL_TREE);
2201 		  if (vm_type)
2202 		    init.value = save_expr (init.value);
2203 		  finish_init ();
2204 		  specs->typespec_kind = ctsk_typeof;
2205 		  specs->locations[cdw_typedef] = init_loc;
2206 		  specs->typedef_p = true;
2207 		  specs->type = init_type;
2208 		  if (vm_type)
2209 		    {
2210 		      bool maybe_const = true;
2211 		      tree type_expr = c_fully_fold (init.value, false,
2212 						     &maybe_const);
2213 		      specs->expr_const_operands &= maybe_const;
2214 		      if (specs->expr)
2215 			specs->expr = build2 (COMPOUND_EXPR,
2216 					      TREE_TYPE (type_expr),
2217 					      specs->expr, type_expr);
2218 		      else
2219 			specs->expr = type_expr;
2220 		    }
2221 		  d = start_decl (declarator, specs, true,
2222 				  chainon (postfix_attrs, all_prefix_attrs));
2223 		  if (!d)
2224 		    d = error_mark_node;
2225 		  if (omp_declare_simd_clauses.exists ())
2226 		    c_finish_omp_declare_simd (parser, d, NULL_TREE,
2227 					       omp_declare_simd_clauses);
2228 		}
2229 	      else
2230 		{
2231 		  /* The declaration of the variable is in effect while
2232 		     its initializer is parsed.  */
2233 		  d = start_decl (declarator, specs, true,
2234 				  chainon (postfix_attrs, all_prefix_attrs));
2235 		  if (!d)
2236 		    d = error_mark_node;
2237 		  if (omp_declare_simd_clauses.exists ())
2238 		    c_finish_omp_declare_simd (parser, d, NULL_TREE,
2239 					       omp_declare_simd_clauses);
2240 		  init_loc = c_parser_peek_token (parser)->location;
2241 		  rich_location richloc (line_table, init_loc);
2242 		  start_init (d, asm_name, global_bindings_p (), &richloc);
2243 		  /* A parameter is initialized, which is invalid.  Don't
2244 		     attempt to instrument the initializer.  */
2245 		  int flag_sanitize_save = flag_sanitize;
2246 		  if (TREE_CODE (d) == PARM_DECL)
2247 		    flag_sanitize = 0;
2248 		  init = c_parser_initializer (parser);
2249 		  flag_sanitize = flag_sanitize_save;
2250 		  finish_init ();
2251 		}
2252 	      if (oacc_routine_data)
2253 		c_finish_oacc_routine (oacc_routine_data, d, false);
2254 	      if (d != error_mark_node)
2255 		{
2256 		  maybe_warn_string_init (init_loc, TREE_TYPE (d), init);
2257 		  finish_decl (d, init_loc, init.value,
2258 			       init.original_type, asm_name);
2259 		}
2260 	    }
2261 	  else
2262 	    {
2263 	      if (auto_type_p)
2264 		{
2265 		  error_at (here,
2266 			    "%<__auto_type%> requires an initialized "
2267 			    "data declaration");
2268 		  c_parser_skip_to_end_of_block_or_statement (parser);
2269 		  return;
2270 		}
2271 	      tree d = start_decl (declarator, specs, false,
2272 				   chainon (postfix_attrs,
2273 					    all_prefix_attrs));
2274 	      if (d
2275 		  && TREE_CODE (d) == FUNCTION_DECL
2276 		  && DECL_ARGUMENTS (d) == NULL_TREE
2277 		  && DECL_INITIAL (d) == NULL_TREE)
2278 		{
2279 		  /* Find the innermost declarator that is neither cdk_id
2280 		     nor cdk_attrs.  */
2281 		  const struct c_declarator *decl = declarator;
2282 		  const struct c_declarator *last_non_id_attrs = NULL;
2283 
2284 		  while (decl)
2285 		    switch (decl->kind)
2286 		      {
2287 		      case cdk_array:
2288 		      case cdk_function:
2289 		      case cdk_pointer:
2290 			last_non_id_attrs = decl;
2291 			decl = decl->declarator;
2292 			break;
2293 
2294 		      case cdk_attrs:
2295 			decl = decl->declarator;
2296 			break;
2297 
2298 		      case cdk_id:
2299 			decl = 0;
2300 			break;
2301 
2302 		      default:
2303 			gcc_unreachable ();
2304 		      }
2305 
2306 		  /* If it exists and is cdk_function, use its parameters.  */
2307 		  if (last_non_id_attrs
2308 		      && last_non_id_attrs->kind == cdk_function)
2309 		    DECL_ARGUMENTS (d) = last_non_id_attrs->u.arg_info->parms;
2310 		}
2311 	      if (omp_declare_simd_clauses.exists ())
2312 		{
2313 		  tree parms = NULL_TREE;
2314 		  if (d && TREE_CODE (d) == FUNCTION_DECL)
2315 		    {
2316 		      struct c_declarator *ce = declarator;
2317 		      while (ce != NULL)
2318 			if (ce->kind == cdk_function)
2319 			  {
2320 			    parms = ce->u.arg_info->parms;
2321 			    break;
2322 			  }
2323 			else
2324 			  ce = ce->declarator;
2325 		    }
2326 		  if (parms)
2327 		    temp_store_parm_decls (d, parms);
2328 		  c_finish_omp_declare_simd (parser, d, parms,
2329 					     omp_declare_simd_clauses);
2330 		  if (parms)
2331 		    temp_pop_parm_decls ();
2332 		}
2333 	      if (oacc_routine_data)
2334 		c_finish_oacc_routine (oacc_routine_data, d, false);
2335 	      if (d)
2336 		finish_decl (d, UNKNOWN_LOCATION, NULL_TREE,
2337 			     NULL_TREE, asm_name);
2338 
2339 	      if (c_parser_next_token_is_keyword (parser, RID_IN))
2340 		{
2341 		  if (d)
2342 		    *objc_foreach_object_declaration = d;
2343 		  else
2344 		    *objc_foreach_object_declaration = error_mark_node;
2345 		}
2346 	    }
2347 	  if (c_parser_next_token_is (parser, CPP_COMMA))
2348 	    {
2349 	      if (auto_type_p)
2350 		{
2351 		  error_at (here,
2352 			    "%<__auto_type%> may only be used with"
2353 			    " a single declarator");
2354 		  c_parser_skip_to_end_of_block_or_statement (parser);
2355 		  return;
2356 		}
2357 	      c_parser_consume_token (parser);
2358 	      if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2359 		all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
2360 					    prefix_attrs);
2361 	      else
2362 		all_prefix_attrs = prefix_attrs;
2363 	      continue;
2364 	    }
2365 	  else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2366 	    {
2367 	      c_parser_consume_token (parser);
2368 	      return;
2369 	    }
2370 	  else if (c_parser_next_token_is_keyword (parser, RID_IN))
2371 	    {
2372 	      /* This can only happen in Objective-C: we found the
2373 		 'in' that terminates the declaration inside an
2374 		 Objective-C foreach statement.  Do not consume the
2375 		 token, so that the caller can use it to determine
2376 		 that this indeed is a foreach context.  */
2377 	      return;
2378 	    }
2379 	  else
2380 	    {
2381 	      c_parser_error (parser, "expected %<,%> or %<;%>");
2382 	      c_parser_skip_to_end_of_block_or_statement (parser);
2383 	      return;
2384 	    }
2385 	}
2386       else if (auto_type_p)
2387 	{
2388 	  error_at (here,
2389 		    "%<__auto_type%> requires an initialized data declaration");
2390 	  c_parser_skip_to_end_of_block_or_statement (parser);
2391 	  return;
2392 	}
2393       else if (!fndef_ok)
2394 	{
2395 	  c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, "
2396 			  "%<asm%> or %<__attribute__%>");
2397 	  c_parser_skip_to_end_of_block_or_statement (parser);
2398 	  return;
2399 	}
2400       /* Function definition (nested or otherwise).  */
2401       if (nested)
2402 	{
2403 	  pedwarn (here, OPT_Wpedantic, "ISO C forbids nested functions");
2404 	  c_push_function_context ();
2405 	}
2406       if (!start_function (specs, declarator, all_prefix_attrs))
2407 	{
2408 	  /* At this point we've consumed:
2409 	       declaration-specifiers declarator
2410 	     and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2411 	     RID_ASM, RID_ATTRIBUTE, or RID_IN,
2412 	     but the
2413 	       declaration-specifiers declarator
2414 	     aren't grokkable as a function definition, so we have
2415 	     an error.  */
2416 	  gcc_assert (!c_parser_next_token_is (parser, CPP_SEMICOLON));
2417 	  if (c_parser_next_token_starts_declspecs (parser))
2418 	    {
2419 	      /* If we have
2420 		   declaration-specifiers declarator decl-specs
2421 		 then assume we have a missing semicolon, which would
2422 		 give us:
2423 		   declaration-specifiers declarator  decl-specs
2424 						    ^
2425 						    ;
2426 		   <~~~~~~~~~ declaration ~~~~~~~~~~>
2427 		 Use c_parser_require to get an error with a fix-it hint.  */
2428 	      c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>");
2429 	      parser->error = false;
2430 	    }
2431 	  else
2432 	    {
2433 	      /* This can appear in many cases looking nothing like a
2434 		 function definition, so we don't give a more specific
2435 		 error suggesting there was one.  */
2436 	      c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2437 			      "or %<__attribute__%>");
2438 	    }
2439 	  if (nested)
2440 	    c_pop_function_context ();
2441 	  break;
2442 	}
2443 
2444       if (DECL_DECLARED_INLINE_P (current_function_decl))
2445         tv = TV_PARSE_INLINE;
2446       else
2447         tv = TV_PARSE_FUNC;
2448       auto_timevar at (g_timer, tv);
2449 
2450       /* Parse old-style parameter declarations.  ??? Attributes are
2451 	 not allowed to start declaration specifiers here because of a
2452 	 syntax conflict between a function declaration with attribute
2453 	 suffix and a function definition with an attribute prefix on
2454 	 first old-style parameter declaration.  Following the old
2455 	 parser, they are not accepted on subsequent old-style
2456 	 parameter declarations either.  However, there is no
2457 	 ambiguity after the first declaration, nor indeed on the
2458 	 first as long as we don't allow postfix attributes after a
2459 	 declarator with a nonempty identifier list in a definition;
2460 	 and postfix attributes have never been accepted here in
2461 	 function definitions either.  */
2462       while (c_parser_next_token_is_not (parser, CPP_EOF)
2463 	     && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE))
2464 	c_parser_declaration_or_fndef (parser, false, false, false,
2465 				       true, false, NULL, vNULL);
2466       store_parm_decls ();
2467       if (omp_declare_simd_clauses.exists ())
2468 	c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE,
2469 				   omp_declare_simd_clauses);
2470       if (oacc_routine_data)
2471 	c_finish_oacc_routine (oacc_routine_data, current_function_decl, true);
2472       location_t startloc = c_parser_peek_token (parser)->location;
2473       DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
2474 	= startloc;
2475       location_t endloc = startloc;
2476 
2477       /* If the definition was marked with __RTL, use the RTL parser now,
2478 	 consuming the function body.  */
2479       if (specs->declspec_il == cdil_rtl)
2480 	{
2481 	  endloc = c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass);
2482 
2483 	  /* Normally, store_parm_decls sets next_is_function_body,
2484 	     anticipating a function body.  We need a push_scope/pop_scope
2485 	     pair to flush out this state, or subsequent function parsing
2486 	     will go wrong.  */
2487 	  push_scope ();
2488 	  pop_scope ();
2489 
2490 	  finish_function (endloc);
2491 	  return;
2492 	}
2493       /* If the definition was marked with __GIMPLE then parse the
2494          function body as GIMPLE.  */
2495       else if (specs->declspec_il != cdil_none)
2496 	{
2497 	  bool saved = in_late_binary_op;
2498 	  in_late_binary_op = true;
2499 	  c_parser_parse_gimple_body (parser, specs->gimple_or_rtl_pass,
2500 				      specs->declspec_il,
2501 				      specs->entry_bb_count);
2502 	  in_late_binary_op = saved;
2503 	}
2504       else
2505 	fnbody = c_parser_compound_statement (parser, &endloc);
2506       tree fndecl = current_function_decl;
2507       if (nested)
2508 	{
2509 	  tree decl = current_function_decl;
2510 	  /* Mark nested functions as needing static-chain initially.
2511 	     lower_nested_functions will recompute it but the
2512 	     DECL_STATIC_CHAIN flag is also used before that happens,
2513 	     by initializer_constant_valid_p.  See gcc.dg/nested-fn-2.c.  */
2514 	  DECL_STATIC_CHAIN (decl) = 1;
2515 	  add_stmt (fnbody);
2516 	  finish_function (endloc);
2517 	  c_pop_function_context ();
2518 	  add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));
2519 	}
2520       else
2521 	{
2522 	  if (fnbody)
2523 	    add_stmt (fnbody);
2524 	  finish_function (endloc);
2525 	}
2526       /* Get rid of the empty stmt list for GIMPLE/RTL.  */
2527       if (specs->declspec_il != cdil_none)
2528 	DECL_SAVED_TREE (fndecl) = NULL_TREE;
2529 
2530       break;
2531     }
2532 }
2533 
2534 /* Parse an asm-definition (asm() outside a function body).  This is a
2535    GNU extension.
2536 
2537    asm-definition:
2538      simple-asm-expr ;
2539 */
2540 
2541 static void
c_parser_asm_definition(c_parser * parser)2542 c_parser_asm_definition (c_parser *parser)
2543 {
2544   tree asm_str = c_parser_simple_asm_expr (parser);
2545   if (asm_str)
2546     symtab->finalize_toplevel_asm (asm_str);
2547   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
2548 }
2549 
2550 /* Parse a static assertion (C11 6.7.10).
2551 
2552    static_assert-declaration:
2553      static_assert-declaration-no-semi ;
2554 */
2555 
2556 static void
c_parser_static_assert_declaration(c_parser * parser)2557 c_parser_static_assert_declaration (c_parser *parser)
2558 {
2559   c_parser_static_assert_declaration_no_semi (parser);
2560   if (parser->error
2561       || !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
2562     c_parser_skip_to_end_of_block_or_statement (parser);
2563 }
2564 
2565 /* Parse a static assertion (C11 6.7.10), without the trailing
2566    semicolon.
2567 
2568    static_assert-declaration-no-semi:
2569      _Static_assert ( constant-expression , string-literal )
2570 
2571    C2X:
2572    static_assert-declaration-no-semi:
2573      _Static_assert ( constant-expression )
2574 */
2575 
2576 static void
c_parser_static_assert_declaration_no_semi(c_parser * parser)2577 c_parser_static_assert_declaration_no_semi (c_parser *parser)
2578 {
2579   location_t assert_loc, value_loc;
2580   tree value;
2581   tree string = NULL_TREE;
2582 
2583   gcc_assert (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT));
2584   assert_loc = c_parser_peek_token (parser)->location;
2585   if (flag_isoc99)
2586     pedwarn_c99 (assert_loc, OPT_Wpedantic,
2587 		 "ISO C99 does not support %<_Static_assert%>");
2588   else
2589     pedwarn_c99 (assert_loc, OPT_Wpedantic,
2590 		 "ISO C90 does not support %<_Static_assert%>");
2591   c_parser_consume_token (parser);
2592   matching_parens parens;
2593   if (!parens.require_open (parser))
2594     return;
2595   location_t value_tok_loc = c_parser_peek_token (parser)->location;
2596   value = c_parser_expr_no_commas (parser, NULL).value;
2597   value_loc = EXPR_LOC_OR_LOC (value, value_tok_loc);
2598   if (c_parser_next_token_is (parser, CPP_COMMA))
2599     {
2600       c_parser_consume_token (parser);
2601       switch (c_parser_peek_token (parser)->type)
2602 	{
2603 	case CPP_STRING:
2604 	case CPP_STRING16:
2605 	case CPP_STRING32:
2606 	case CPP_WSTRING:
2607 	case CPP_UTF8STRING:
2608 	  string = c_parser_string_literal (parser, false, true).value;
2609 	  break;
2610 	default:
2611 	  c_parser_error (parser, "expected string literal");
2612 	  return;
2613 	}
2614     }
2615   else if (flag_isoc11)
2616     /* If pedantic for pre-C11, the use of _Static_assert itself will
2617        have been diagnosed, so do not also diagnose the use of this
2618        new C2X feature of _Static_assert.  */
2619     pedwarn_c11 (assert_loc, OPT_Wpedantic,
2620 		 "ISO C11 does not support omitting the string in "
2621 		 "%<_Static_assert%>");
2622   parens.require_close (parser);
2623 
2624   if (!INTEGRAL_TYPE_P (TREE_TYPE (value)))
2625     {
2626       error_at (value_loc, "expression in static assertion is not an integer");
2627       return;
2628     }
2629   if (TREE_CODE (value) != INTEGER_CST)
2630     {
2631       value = c_fully_fold (value, false, NULL);
2632       /* Strip no-op conversions.  */
2633       STRIP_TYPE_NOPS (value);
2634       if (TREE_CODE (value) == INTEGER_CST)
2635 	pedwarn (value_loc, OPT_Wpedantic, "expression in static assertion "
2636 		 "is not an integer constant expression");
2637     }
2638   if (TREE_CODE (value) != INTEGER_CST)
2639     {
2640       error_at (value_loc, "expression in static assertion is not constant");
2641       return;
2642     }
2643   constant_expression_warning (value);
2644   if (integer_zerop (value))
2645     {
2646       if (string)
2647 	error_at (assert_loc, "static assertion failed: %E", string);
2648       else
2649 	error_at (assert_loc, "static assertion failed");
2650     }
2651 }
2652 
2653 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
2654    6.7, C11 6.7), adding them to SPECS (which may already include some).
2655    Storage class specifiers are accepted iff SCSPEC_OK; type
2656    specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
2657    accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start
2658    iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK.  In
2659    addition to the syntax shown, standard attributes are accepted at
2660    the start iff START_STD_ATTR_OK and at the end iff END_STD_ATTR_OK;
2661    unlike gnu-attributes, they are not accepted in the middle of the
2662    list.  (This combines various different syntax productions in the C
2663    standard, and in some cases gnu-attributes and standard attributes
2664    at the start may already have been parsed before this function is
2665    called.)
2666 
2667    declaration-specifiers:
2668      storage-class-specifier declaration-specifiers[opt]
2669      type-specifier declaration-specifiers[opt]
2670      type-qualifier declaration-specifiers[opt]
2671      function-specifier declaration-specifiers[opt]
2672      alignment-specifier declaration-specifiers[opt]
2673 
2674    Function specifiers (inline) are from C99, and are currently
2675    handled as storage class specifiers, as is __thread.  Alignment
2676    specifiers are from C11.
2677 
2678    C90 6.5.1, C99 6.7.1, C11 6.7.1:
2679    storage-class-specifier:
2680      typedef
2681      extern
2682      static
2683      auto
2684      register
2685      _Thread_local
2686 
2687    (_Thread_local is new in C11.)
2688 
2689    C99 6.7.4, C11 6.7.4:
2690    function-specifier:
2691      inline
2692      _Noreturn
2693 
2694    (_Noreturn is new in C11.)
2695 
2696    C90 6.5.2, C99 6.7.2, C11 6.7.2:
2697    type-specifier:
2698      void
2699      char
2700      short
2701      int
2702      long
2703      float
2704      double
2705      signed
2706      unsigned
2707      _Bool
2708      _Complex
2709      [_Imaginary removed in C99 TC2]
2710      struct-or-union-specifier
2711      enum-specifier
2712      typedef-name
2713      atomic-type-specifier
2714 
2715    (_Bool and _Complex are new in C99.)
2716    (atomic-type-specifier is new in C11.)
2717 
2718    C90 6.5.3, C99 6.7.3, C11 6.7.3:
2719 
2720    type-qualifier:
2721      const
2722      restrict
2723      volatile
2724      address-space-qualifier
2725      _Atomic
2726 
2727    (restrict is new in C99.)
2728    (_Atomic is new in C11.)
2729 
2730    GNU extensions:
2731 
2732    declaration-specifiers:
2733      gnu-attributes declaration-specifiers[opt]
2734 
2735    type-qualifier:
2736      address-space
2737 
2738    address-space:
2739      identifier recognized by the target
2740 
2741    storage-class-specifier:
2742      __thread
2743 
2744    type-specifier:
2745      typeof-specifier
2746      __auto_type
2747      __intN
2748      _Decimal32
2749      _Decimal64
2750      _Decimal128
2751      _Fract
2752      _Accum
2753      _Sat
2754 
2755   (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
2756    http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
2757 
2758    atomic-type-specifier
2759     _Atomic ( type-name )
2760 
2761    Objective-C:
2762 
2763    type-specifier:
2764      class-name objc-protocol-refs[opt]
2765      typedef-name objc-protocol-refs
2766      objc-protocol-refs
2767 */
2768 
2769 void
c_parser_declspecs(c_parser * parser,struct c_declspecs * specs,bool scspec_ok,bool typespec_ok,bool start_attr_ok,bool alignspec_ok,bool auto_type_ok,bool start_std_attr_ok,bool end_std_attr_ok,enum c_lookahead_kind la)2770 c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
2771 		    bool scspec_ok, bool typespec_ok, bool start_attr_ok,
2772 		    bool alignspec_ok, bool auto_type_ok,
2773 		    bool start_std_attr_ok, bool end_std_attr_ok,
2774 		    enum c_lookahead_kind la)
2775 {
2776   bool attrs_ok = start_attr_ok;
2777   bool seen_type = specs->typespec_kind != ctsk_none;
2778 
2779   if (!typespec_ok)
2780     gcc_assert (la == cla_prefer_id);
2781 
2782   if (start_std_attr_ok
2783       && c_parser_nth_token_starts_std_attributes (parser, 1))
2784     {
2785       gcc_assert (!specs->non_std_attrs_seen_p);
2786       location_t loc = c_parser_peek_token (parser)->location;
2787       tree attrs = c_parser_std_attribute_specifier_sequence (parser);
2788       declspecs_add_attrs (loc, specs, attrs);
2789       specs->non_std_attrs_seen_p = false;
2790     }
2791 
2792   while (c_parser_next_token_is (parser, CPP_NAME)
2793 	 || c_parser_next_token_is (parser, CPP_KEYWORD)
2794 	 || (c_dialect_objc () && c_parser_next_token_is (parser, CPP_LESS)))
2795     {
2796       struct c_typespec t;
2797       tree attrs;
2798       tree align;
2799       location_t loc = c_parser_peek_token (parser)->location;
2800 
2801       /* If we cannot accept a type, exit if the next token must start
2802 	 one.  Also, if we already have seen a tagged definition,
2803 	 a typename would be an error anyway and likely the user
2804 	 has simply forgotten a semicolon, so we exit.  */
2805       if ((!typespec_ok || specs->typespec_kind == ctsk_tagdef)
2806 	  && c_parser_next_tokens_start_typename (parser, la)
2807 	  && !c_parser_next_token_is_qualifier (parser)
2808 	  && !c_parser_next_token_is_keyword (parser, RID_ALIGNAS))
2809 	break;
2810 
2811       if (c_parser_next_token_is (parser, CPP_NAME))
2812 	{
2813 	  c_token *name_token = c_parser_peek_token (parser);
2814 	  tree value = name_token->value;
2815 	  c_id_kind kind = name_token->id_kind;
2816 
2817 	  if (kind == C_ID_ADDRSPACE)
2818 	    {
2819 	      addr_space_t as
2820 		= name_token->keyword - RID_FIRST_ADDR_SPACE;
2821 	      declspecs_add_addrspace (name_token->location, specs, as);
2822 	      c_parser_consume_token (parser);
2823 	      attrs_ok = true;
2824 	      continue;
2825 	    }
2826 
2827 	  gcc_assert (!c_parser_next_token_is_qualifier (parser));
2828 
2829 	  /* If we cannot accept a type, and the next token must start one,
2830 	     exit.  Do the same if we already have seen a tagged definition,
2831 	     since it would be an error anyway and likely the user has simply
2832 	     forgotten a semicolon.  */
2833 	  if (seen_type || !c_parser_next_tokens_start_typename (parser, la))
2834 	    break;
2835 
2836 	  /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
2837 	     a C_ID_CLASSNAME.  */
2838 	  c_parser_consume_token (parser);
2839 	  seen_type = true;
2840 	  attrs_ok = true;
2841 	  if (kind == C_ID_ID)
2842 	    {
2843 	      error_at (loc, "unknown type name %qE", value);
2844 	      t.kind = ctsk_typedef;
2845 	      t.spec = error_mark_node;
2846 	    }
2847 	  else if (kind == C_ID_TYPENAME
2848 	           && (!c_dialect_objc ()
2849 	               || c_parser_next_token_is_not (parser, CPP_LESS)))
2850 	    {
2851 	      t.kind = ctsk_typedef;
2852 	      /* For a typedef name, record the meaning, not the name.
2853 		 In case of 'foo foo, bar;'.  */
2854 	      t.spec = lookup_name (value);
2855 	    }
2856 	  else
2857 	    {
2858 	      tree proto = NULL_TREE;
2859 	      gcc_assert (c_dialect_objc ());
2860 	      t.kind = ctsk_objc;
2861 	      if (c_parser_next_token_is (parser, CPP_LESS))
2862 		proto = c_parser_objc_protocol_refs (parser);
2863 	      t.spec = objc_get_protocol_qualified_type (value, proto);
2864 	    }
2865 	  t.expr = NULL_TREE;
2866 	  t.expr_const_operands = true;
2867 	  declspecs_add_type (name_token->location, specs, t);
2868 	  continue;
2869 	}
2870       if (c_parser_next_token_is (parser, CPP_LESS))
2871 	{
2872 	  /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
2873 	     nisse@lysator.liu.se.  */
2874 	  tree proto;
2875 	  gcc_assert (c_dialect_objc ());
2876 	  if (!typespec_ok || seen_type)
2877 	    break;
2878 	  proto = c_parser_objc_protocol_refs (parser);
2879 	  t.kind = ctsk_objc;
2880 	  t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto);
2881 	  t.expr = NULL_TREE;
2882 	  t.expr_const_operands = true;
2883 	  declspecs_add_type (loc, specs, t);
2884 	  continue;
2885 	}
2886       gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD));
2887       switch (c_parser_peek_token (parser)->keyword)
2888 	{
2889 	case RID_STATIC:
2890 	case RID_EXTERN:
2891 	case RID_REGISTER:
2892 	case RID_TYPEDEF:
2893 	case RID_INLINE:
2894 	case RID_NORETURN:
2895 	case RID_AUTO:
2896 	case RID_THREAD:
2897 	  if (!scspec_ok)
2898 	    goto out;
2899 	  attrs_ok = true;
2900 	  /* TODO: Distinguish between function specifiers (inline, noreturn)
2901 	     and storage class specifiers, either here or in
2902 	     declspecs_add_scspec.  */
2903 	  declspecs_add_scspec (loc, specs,
2904 				c_parser_peek_token (parser)->value);
2905 	  c_parser_consume_token (parser);
2906 	  break;
2907 	case RID_AUTO_TYPE:
2908 	  if (!auto_type_ok)
2909 	    goto out;
2910 	  /* Fall through.  */
2911 	case RID_UNSIGNED:
2912 	case RID_LONG:
2913 	case RID_SHORT:
2914 	case RID_SIGNED:
2915 	case RID_COMPLEX:
2916 	case RID_INT:
2917 	case RID_CHAR:
2918 	case RID_FLOAT:
2919 	case RID_DOUBLE:
2920 	case RID_VOID:
2921 	case RID_DFLOAT32:
2922 	case RID_DFLOAT64:
2923 	case RID_DFLOAT128:
2924 	CASE_RID_FLOATN_NX:
2925 	case RID_BOOL:
2926 	case RID_FRACT:
2927 	case RID_ACCUM:
2928 	case RID_SAT:
2929 	case RID_INT_N_0:
2930 	case RID_INT_N_1:
2931 	case RID_INT_N_2:
2932 	case RID_INT_N_3:
2933 	  if (!typespec_ok)
2934 	    goto out;
2935 	  attrs_ok = true;
2936 	  seen_type = true;
2937 	  if (c_dialect_objc ())
2938 	    parser->objc_need_raw_identifier = true;
2939 	  t.kind = ctsk_resword;
2940 	  t.spec = c_parser_peek_token (parser)->value;
2941 	  t.expr = NULL_TREE;
2942 	  t.expr_const_operands = true;
2943 	  declspecs_add_type (loc, specs, t);
2944 	  c_parser_consume_token (parser);
2945 	  break;
2946 	case RID_ENUM:
2947 	  if (!typespec_ok)
2948 	    goto out;
2949 	  attrs_ok = true;
2950 	  seen_type = true;
2951 	  t = c_parser_enum_specifier (parser);
2952           invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
2953 	  declspecs_add_type (loc, specs, t);
2954 	  break;
2955 	case RID_STRUCT:
2956 	case RID_UNION:
2957 	  if (!typespec_ok)
2958 	    goto out;
2959 	  attrs_ok = true;
2960 	  seen_type = true;
2961 	  t = c_parser_struct_or_union_specifier (parser);
2962           invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
2963 	  declspecs_add_type (loc, specs, t);
2964 	  break;
2965 	case RID_TYPEOF:
2966 	  /* ??? The old parser rejected typeof after other type
2967 	     specifiers, but is a syntax error the best way of
2968 	     handling this?  */
2969 	  if (!typespec_ok || seen_type)
2970 	    goto out;
2971 	  attrs_ok = true;
2972 	  seen_type = true;
2973 	  t = c_parser_typeof_specifier (parser);
2974 	  declspecs_add_type (loc, specs, t);
2975 	  break;
2976 	case RID_ATOMIC:
2977 	  /* C parser handling of Objective-C constructs needs
2978 	     checking for correct lvalue-to-rvalue conversions, and
2979 	     the code in build_modify_expr handling various
2980 	     Objective-C cases, and that in build_unary_op handling
2981 	     Objective-C cases for increment / decrement, also needs
2982 	     updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
2983 	     and objc_types_are_equivalent may also need updates.  */
2984 	  if (c_dialect_objc ())
2985 	    sorry ("%<_Atomic%> in Objective-C");
2986 	  if (flag_isoc99)
2987 	    pedwarn_c99 (loc, OPT_Wpedantic,
2988 			 "ISO C99 does not support the %<_Atomic%> qualifier");
2989 	  else
2990 	    pedwarn_c99 (loc, OPT_Wpedantic,
2991 			 "ISO C90 does not support the %<_Atomic%> qualifier");
2992 	  attrs_ok = true;
2993 	  tree value;
2994 	  value = c_parser_peek_token (parser)->value;
2995 	  c_parser_consume_token (parser);
2996 	  if (typespec_ok && c_parser_next_token_is (parser, CPP_OPEN_PAREN))
2997 	    {
2998 	      /* _Atomic ( type-name ).  */
2999 	      seen_type = true;
3000 	      c_parser_consume_token (parser);
3001 	      struct c_type_name *type = c_parser_type_name (parser);
3002 	      t.kind = ctsk_typeof;
3003 	      t.spec = error_mark_node;
3004 	      t.expr = NULL_TREE;
3005 	      t.expr_const_operands = true;
3006 	      if (type != NULL)
3007 		t.spec = groktypename (type, &t.expr,
3008 				       &t.expr_const_operands);
3009 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3010 					 "expected %<)%>");
3011 	      if (t.spec != error_mark_node)
3012 		{
3013 		  if (TREE_CODE (t.spec) == ARRAY_TYPE)
3014 		    error_at (loc, "%<_Atomic%>-qualified array type");
3015 		  else if (TREE_CODE (t.spec) == FUNCTION_TYPE)
3016 		    error_at (loc, "%<_Atomic%>-qualified function type");
3017 		  else if (TYPE_QUALS (t.spec) != TYPE_UNQUALIFIED)
3018 		    error_at (loc, "%<_Atomic%> applied to a qualified type");
3019 		  else
3020 		    t.spec = c_build_qualified_type (t.spec, TYPE_QUAL_ATOMIC);
3021 		}
3022 	      declspecs_add_type (loc, specs, t);
3023 	    }
3024 	  else
3025 	    declspecs_add_qual (loc, specs, value);
3026 	  break;
3027 	case RID_CONST:
3028 	case RID_VOLATILE:
3029 	case RID_RESTRICT:
3030 	  attrs_ok = true;
3031 	  declspecs_add_qual (loc, specs, c_parser_peek_token (parser)->value);
3032 	  c_parser_consume_token (parser);
3033 	  break;
3034 	case RID_ATTRIBUTE:
3035 	  if (!attrs_ok)
3036 	    goto out;
3037 	  attrs = c_parser_gnu_attributes (parser);
3038 	  declspecs_add_attrs (loc, specs, attrs);
3039 	  break;
3040 	case RID_ALIGNAS:
3041 	  if (!alignspec_ok)
3042 	    goto out;
3043 	  align = c_parser_alignas_specifier (parser);
3044 	  declspecs_add_alignas (loc, specs, align);
3045 	  break;
3046 	case RID_GIMPLE:
3047 	  if (! flag_gimple)
3048 	    error_at (loc, "%<__GIMPLE%> only valid with %<-fgimple%>");
3049 	  c_parser_consume_token (parser);
3050 	  specs->declspec_il = cdil_gimple;
3051 	  specs->locations[cdw_gimple] = loc;
3052 	  c_parser_gimple_or_rtl_pass_list (parser, specs);
3053 	  break;
3054 	case RID_RTL:
3055 	  c_parser_consume_token (parser);
3056 	  specs->declspec_il = cdil_rtl;
3057 	  specs->locations[cdw_rtl] = loc;
3058 	  c_parser_gimple_or_rtl_pass_list (parser, specs);
3059 	  break;
3060 	default:
3061 	  goto out;
3062 	}
3063     }
3064  out:
3065   if (end_std_attr_ok
3066       && c_parser_nth_token_starts_std_attributes (parser, 1))
3067     specs->postfix_attrs = c_parser_std_attribute_specifier_sequence (parser);
3068 }
3069 
3070 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
3071 
3072    enum-specifier:
3073      enum gnu-attributes[opt] identifier[opt] { enumerator-list }
3074        gnu-attributes[opt]
3075      enum gnu-attributes[opt] identifier[opt] { enumerator-list , }
3076        gnu-attributes[opt]
3077      enum gnu-attributes[opt] identifier
3078 
3079    The form with trailing comma is new in C99.  The forms with
3080    gnu-attributes are GNU extensions.  In GNU C, we accept any expression
3081    without commas in the syntax (assignment expressions, not just
3082    conditional expressions); assignment expressions will be diagnosed
3083    as non-constant.
3084 
3085    enumerator-list:
3086      enumerator
3087      enumerator-list , enumerator
3088 
3089    enumerator:
3090      enumeration-constant attribute-specifier-sequence[opt]
3091      enumeration-constant attribute-specifier-sequence[opt]
3092        = constant-expression
3093 
3094    GNU Extensions:
3095 
3096    enumerator:
3097      enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3098      enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3099        = constant-expression
3100 
3101 */
3102 
3103 static struct c_typespec
c_parser_enum_specifier(c_parser * parser)3104 c_parser_enum_specifier (c_parser *parser)
3105 {
3106   struct c_typespec ret;
3107   bool have_std_attrs;
3108   tree std_attrs = NULL_TREE;
3109   tree attrs;
3110   tree ident = NULL_TREE;
3111   location_t enum_loc;
3112   location_t ident_loc = UNKNOWN_LOCATION;  /* Quiet warning.  */
3113   gcc_assert (c_parser_next_token_is_keyword (parser, RID_ENUM));
3114   c_parser_consume_token (parser);
3115   have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3116   if (have_std_attrs)
3117     std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3118   attrs = c_parser_gnu_attributes (parser);
3119   enum_loc = c_parser_peek_token (parser)->location;
3120   /* Set the location in case we create a decl now.  */
3121   c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3122   if (c_parser_next_token_is (parser, CPP_NAME))
3123     {
3124       ident = c_parser_peek_token (parser)->value;
3125       ident_loc = c_parser_peek_token (parser)->location;
3126       enum_loc = ident_loc;
3127       c_parser_consume_token (parser);
3128     }
3129   if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3130     {
3131       /* Parse an enum definition.  */
3132       struct c_enum_contents the_enum;
3133       tree type;
3134       tree postfix_attrs;
3135       /* We chain the enumerators in reverse order, then put them in
3136 	 forward order at the end.  */
3137       tree values;
3138       timevar_push (TV_PARSE_ENUM);
3139       type = start_enum (enum_loc, &the_enum, ident);
3140       values = NULL_TREE;
3141       c_parser_consume_token (parser);
3142       while (true)
3143 	{
3144 	  tree enum_id;
3145 	  tree enum_value;
3146 	  tree enum_decl;
3147 	  bool seen_comma;
3148 	  c_token *token;
3149 	  location_t comma_loc = UNKNOWN_LOCATION;  /* Quiet warning.  */
3150 	  location_t decl_loc, value_loc;
3151 	  if (c_parser_next_token_is_not (parser, CPP_NAME))
3152 	    {
3153 	      /* Give a nicer error for "enum {}".  */
3154 	      if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3155 		  && !parser->error)
3156 		{
3157 		  error_at (c_parser_peek_token (parser)->location,
3158 			    "empty enum is invalid");
3159 		  parser->error = true;
3160 		}
3161 	      else
3162 		c_parser_error (parser, "expected identifier");
3163 	      c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3164 	      values = error_mark_node;
3165 	      break;
3166 	    }
3167 	  token = c_parser_peek_token (parser);
3168 	  enum_id = token->value;
3169 	  /* Set the location in case we create a decl now.  */
3170 	  c_parser_set_source_position_from_token (token);
3171 	  decl_loc = value_loc = token->location;
3172 	  c_parser_consume_token (parser);
3173 	  /* Parse any specified attributes.  */
3174 	  tree std_attrs = NULL_TREE;
3175 	  if (c_parser_nth_token_starts_std_attributes (parser, 1))
3176 	    std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3177 	  tree enum_attrs = chainon (std_attrs,
3178 				     c_parser_gnu_attributes (parser));
3179 	  if (c_parser_next_token_is (parser, CPP_EQ))
3180 	    {
3181 	      c_parser_consume_token (parser);
3182 	      value_loc = c_parser_peek_token (parser)->location;
3183 	      enum_value = c_parser_expr_no_commas (parser, NULL).value;
3184 	    }
3185 	  else
3186 	    enum_value = NULL_TREE;
3187 	  enum_decl = build_enumerator (decl_loc, value_loc,
3188 					&the_enum, enum_id, enum_value);
3189 	  if (enum_attrs)
3190 	    decl_attributes (&TREE_PURPOSE (enum_decl), enum_attrs, 0);
3191 	  TREE_CHAIN (enum_decl) = values;
3192 	  values = enum_decl;
3193 	  seen_comma = false;
3194 	  if (c_parser_next_token_is (parser, CPP_COMMA))
3195 	    {
3196 	      comma_loc = c_parser_peek_token (parser)->location;
3197 	      seen_comma = true;
3198 	      c_parser_consume_token (parser);
3199 	    }
3200 	  if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3201 	    {
3202 	      if (seen_comma)
3203 		pedwarn_c90 (comma_loc, OPT_Wpedantic,
3204 			     "comma at end of enumerator list");
3205 	      c_parser_consume_token (parser);
3206 	      break;
3207 	    }
3208 	  if (!seen_comma)
3209 	    {
3210 	      c_parser_error (parser, "expected %<,%> or %<}%>");
3211 	      c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3212 	      values = error_mark_node;
3213 	      break;
3214 	    }
3215 	}
3216       postfix_attrs = c_parser_gnu_attributes (parser);
3217       ret.spec = finish_enum (type, nreverse (values),
3218 			      chainon (std_attrs,
3219 				       chainon (attrs, postfix_attrs)));
3220       ret.kind = ctsk_tagdef;
3221       ret.expr = NULL_TREE;
3222       ret.expr_const_operands = true;
3223       timevar_pop (TV_PARSE_ENUM);
3224       return ret;
3225     }
3226   else if (!ident)
3227     {
3228       c_parser_error (parser, "expected %<{%>");
3229       ret.spec = error_mark_node;
3230       ret.kind = ctsk_tagref;
3231       ret.expr = NULL_TREE;
3232       ret.expr_const_operands = true;
3233       return ret;
3234     }
3235   /* Attributes may only appear when the members are defined or in
3236      certain forward declarations (treat enum forward declarations in
3237      GNU C analogously to struct and union forward declarations in
3238      standard C).  */
3239   if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3240     c_parser_error (parser, "expected %<;%>");
3241   ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident, have_std_attrs,
3242 			 std_attrs);
3243   /* In ISO C, enumerated types can be referred to only if already
3244      defined.  */
3245   if (pedantic && !COMPLETE_TYPE_P (ret.spec))
3246     {
3247       gcc_assert (ident);
3248       pedwarn (enum_loc, OPT_Wpedantic,
3249 	       "ISO C forbids forward references to %<enum%> types");
3250     }
3251   return ret;
3252 }
3253 
3254 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3255 
3256    struct-or-union-specifier:
3257      struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3258        identifier[opt] { struct-contents } gnu-attributes[opt]
3259      struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3260        identifier
3261 
3262    struct-contents:
3263      struct-declaration-list
3264 
3265    struct-declaration-list:
3266      struct-declaration ;
3267      struct-declaration-list struct-declaration ;
3268 
3269    GNU extensions:
3270 
3271    struct-contents:
3272      empty
3273      struct-declaration
3274      struct-declaration-list struct-declaration
3275 
3276    struct-declaration-list:
3277      struct-declaration-list ;
3278      ;
3279 
3280    (Note that in the syntax here, unlike that in ISO C, the semicolons
3281    are included here rather than in struct-declaration, in order to
3282    describe the syntax with extra semicolons and missing semicolon at
3283    end.)
3284 
3285    Objective-C:
3286 
3287    struct-declaration-list:
3288      @defs ( class-name )
3289 
3290    (Note this does not include a trailing semicolon, but can be
3291    followed by further declarations, and gets a pedwarn-if-pedantic
3292    when followed by a semicolon.)  */
3293 
3294 static struct c_typespec
c_parser_struct_or_union_specifier(c_parser * parser)3295 c_parser_struct_or_union_specifier (c_parser *parser)
3296 {
3297   struct c_typespec ret;
3298   bool have_std_attrs;
3299   tree std_attrs = NULL_TREE;
3300   tree attrs;
3301   tree ident = NULL_TREE;
3302   location_t struct_loc;
3303   location_t ident_loc = UNKNOWN_LOCATION;
3304   enum tree_code code;
3305   switch (c_parser_peek_token (parser)->keyword)
3306     {
3307     case RID_STRUCT:
3308       code = RECORD_TYPE;
3309       break;
3310     case RID_UNION:
3311       code = UNION_TYPE;
3312       break;
3313     default:
3314       gcc_unreachable ();
3315     }
3316   struct_loc = c_parser_peek_token (parser)->location;
3317   c_parser_consume_token (parser);
3318   have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3319   if (have_std_attrs)
3320     std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3321   attrs = c_parser_gnu_attributes (parser);
3322 
3323   /* Set the location in case we create a decl now.  */
3324   c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3325 
3326   if (c_parser_next_token_is (parser, CPP_NAME))
3327     {
3328       ident = c_parser_peek_token (parser)->value;
3329       ident_loc = c_parser_peek_token (parser)->location;
3330       struct_loc = ident_loc;
3331       c_parser_consume_token (parser);
3332     }
3333   if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3334     {
3335       /* Parse a struct or union definition.  Start the scope of the
3336 	 tag before parsing components.  */
3337       class c_struct_parse_info *struct_info;
3338       tree type = start_struct (struct_loc, code, ident, &struct_info);
3339       tree postfix_attrs;
3340       /* We chain the components in reverse order, then put them in
3341 	 forward order at the end.  Each struct-declaration may
3342 	 declare multiple components (comma-separated), so we must use
3343 	 chainon to join them, although when parsing each
3344 	 struct-declaration we can use TREE_CHAIN directly.
3345 
3346 	 The theory behind all this is that there will be more
3347 	 semicolon separated fields than comma separated fields, and
3348 	 so we'll be minimizing the number of node traversals required
3349 	 by chainon.  */
3350       tree contents;
3351       timevar_push (TV_PARSE_STRUCT);
3352       contents = NULL_TREE;
3353       c_parser_consume_token (parser);
3354       /* Handle the Objective-C @defs construct,
3355 	 e.g. foo(sizeof(struct{ @defs(ClassName) }));.  */
3356       if (c_parser_next_token_is_keyword (parser, RID_AT_DEFS))
3357 	{
3358 	  tree name;
3359 	  gcc_assert (c_dialect_objc ());
3360 	  c_parser_consume_token (parser);
3361 	  matching_parens parens;
3362 	  if (!parens.require_open (parser))
3363 	    goto end_at_defs;
3364 	  if (c_parser_next_token_is (parser, CPP_NAME)
3365 	      && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)
3366 	    {
3367 	      name = c_parser_peek_token (parser)->value;
3368 	      c_parser_consume_token (parser);
3369 	    }
3370 	  else
3371 	    {
3372 	      c_parser_error (parser, "expected class name");
3373 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
3374 	      goto end_at_defs;
3375 	    }
3376 	  parens.skip_until_found_close (parser);
3377 	  contents = nreverse (objc_get_class_ivars (name));
3378 	}
3379     end_at_defs:
3380       /* Parse the struct-declarations and semicolons.  Problems with
3381 	 semicolons are diagnosed here; empty structures are diagnosed
3382 	 elsewhere.  */
3383       while (true)
3384 	{
3385 	  tree decls;
3386 	  /* Parse any stray semicolon.  */
3387 	  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3388 	    {
3389 	      location_t semicolon_loc
3390 		= c_parser_peek_token (parser)->location;
3391 	      gcc_rich_location richloc (semicolon_loc);
3392 	      richloc.add_fixit_remove ();
3393 	      pedwarn (&richloc, OPT_Wpedantic,
3394 		       "extra semicolon in struct or union specified");
3395 	      c_parser_consume_token (parser);
3396 	      continue;
3397 	    }
3398 	  /* Stop if at the end of the struct or union contents.  */
3399 	  if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3400 	    {
3401 	      c_parser_consume_token (parser);
3402 	      break;
3403 	    }
3404 	  /* Accept #pragmas at struct scope.  */
3405 	  if (c_parser_next_token_is (parser, CPP_PRAGMA))
3406 	    {
3407 	      c_parser_pragma (parser, pragma_struct, NULL);
3408 	      continue;
3409 	    }
3410 	  /* Parse some comma-separated declarations, but not the
3411 	     trailing semicolon if any.  */
3412 	  decls = c_parser_struct_declaration (parser);
3413 	  contents = chainon (decls, contents);
3414 	  /* If no semicolon follows, either we have a parse error or
3415 	     are at the end of the struct or union and should
3416 	     pedwarn.  */
3417 	  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3418 	    c_parser_consume_token (parser);
3419 	  else
3420 	    {
3421 	      if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3422 		pedwarn (c_parser_peek_token (parser)->location, 0,
3423 			 "no semicolon at end of struct or union");
3424 	      else if (parser->error
3425 		       || !c_parser_next_token_starts_declspecs (parser))
3426 		{
3427 		  c_parser_error (parser, "expected %<;%>");
3428 		  c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3429 		  break;
3430 		}
3431 
3432 	      /* If we come here, we have already emitted an error
3433 		 for an expected `;', identifier or `(', and we also
3434 	         recovered already.  Go on with the next field. */
3435 	    }
3436 	}
3437       postfix_attrs = c_parser_gnu_attributes (parser);
3438       ret.spec = finish_struct (struct_loc, type, nreverse (contents),
3439 				chainon (std_attrs,
3440 					 chainon (attrs, postfix_attrs)),
3441 				struct_info);
3442       ret.kind = ctsk_tagdef;
3443       ret.expr = NULL_TREE;
3444       ret.expr_const_operands = true;
3445       timevar_pop (TV_PARSE_STRUCT);
3446       return ret;
3447     }
3448   else if (!ident)
3449     {
3450       c_parser_error (parser, "expected %<{%>");
3451       ret.spec = error_mark_node;
3452       ret.kind = ctsk_tagref;
3453       ret.expr = NULL_TREE;
3454       ret.expr_const_operands = true;
3455       return ret;
3456     }
3457   /* Attributes may only appear when the members are defined or in
3458      certain forward declarations.  */
3459   if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3460     c_parser_error (parser, "expected %<;%>");
3461   /* ??? Existing practice is that GNU attributes are ignored after
3462      the struct or union keyword when not defining the members.  */
3463   ret = parser_xref_tag (ident_loc, code, ident, have_std_attrs, std_attrs);
3464   return ret;
3465 }
3466 
3467 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
3468    *without* the trailing semicolon.
3469 
3470    struct-declaration:
3471      attribute-specifier-sequence[opt] specifier-qualifier-list
3472        attribute-specifier-sequence[opt] struct-declarator-list
3473      static_assert-declaration-no-semi
3474 
3475    specifier-qualifier-list:
3476      type-specifier specifier-qualifier-list[opt]
3477      type-qualifier specifier-qualifier-list[opt]
3478      alignment-specifier specifier-qualifier-list[opt]
3479      gnu-attributes specifier-qualifier-list[opt]
3480 
3481    struct-declarator-list:
3482      struct-declarator
3483      struct-declarator-list , gnu-attributes[opt] struct-declarator
3484 
3485    struct-declarator:
3486      declarator gnu-attributes[opt]
3487      declarator[opt] : constant-expression gnu-attributes[opt]
3488 
3489    GNU extensions:
3490 
3491    struct-declaration:
3492      __extension__ struct-declaration
3493      specifier-qualifier-list
3494 
3495    Unlike the ISO C syntax, semicolons are handled elsewhere.  The use
3496    of gnu-attributes where shown is a GNU extension.  In GNU C, we accept
3497    any expression without commas in the syntax (assignment
3498    expressions, not just conditional expressions); assignment
3499    expressions will be diagnosed as non-constant.  */
3500 
3501 static tree
c_parser_struct_declaration(c_parser * parser)3502 c_parser_struct_declaration (c_parser *parser)
3503 {
3504   struct c_declspecs *specs;
3505   tree prefix_attrs;
3506   tree all_prefix_attrs;
3507   tree decls;
3508   location_t decl_loc;
3509   if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
3510     {
3511       int ext;
3512       tree decl;
3513       ext = disable_extension_diagnostics ();
3514       c_parser_consume_token (parser);
3515       decl = c_parser_struct_declaration (parser);
3516       restore_extension_diagnostics (ext);
3517       return decl;
3518     }
3519   if (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
3520     {
3521       c_parser_static_assert_declaration_no_semi (parser);
3522       return NULL_TREE;
3523     }
3524   specs = build_null_declspecs ();
3525   decl_loc = c_parser_peek_token (parser)->location;
3526   /* Strictly by the standard, we shouldn't allow _Alignas here,
3527      but it appears to have been intended to allow it there, so
3528      we're keeping it as it is until WG14 reaches a conclusion
3529      of N1731.
3530      <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf>  */
3531   c_parser_declspecs (parser, specs, false, true, true,
3532 		      true, false, true, true, cla_nonabstract_decl);
3533   if (parser->error)
3534     return NULL_TREE;
3535   if (!specs->declspecs_seen_p)
3536     {
3537       c_parser_error (parser, "expected specifier-qualifier-list");
3538       return NULL_TREE;
3539     }
3540   finish_declspecs (specs);
3541   if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3542       || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3543     {
3544       tree ret;
3545       if (specs->typespec_kind == ctsk_none)
3546 	{
3547 	  pedwarn (decl_loc, OPT_Wpedantic,
3548 		   "ISO C forbids member declarations with no members");
3549 	  shadow_tag_warned (specs, pedantic);
3550 	  ret = NULL_TREE;
3551 	}
3552       else
3553 	{
3554 	  /* Support for unnamed structs or unions as members of
3555 	     structs or unions (which is [a] useful and [b] supports
3556 	     MS P-SDK).  */
3557 	  tree attrs = NULL;
3558 
3559 	  ret = grokfield (c_parser_peek_token (parser)->location,
3560 			   build_id_declarator (NULL_TREE), specs,
3561 			   NULL_TREE, &attrs);
3562 	  if (ret)
3563 	    decl_attributes (&ret, attrs, 0);
3564 	}
3565       return ret;
3566     }
3567 
3568   /* Provide better error recovery.  Note that a type name here is valid,
3569      and will be treated as a field name.  */
3570   if (specs->typespec_kind == ctsk_tagdef
3571       && TREE_CODE (specs->type) != ENUMERAL_TYPE
3572       && c_parser_next_token_starts_declspecs (parser)
3573       && !c_parser_next_token_is (parser, CPP_NAME))
3574     {
3575       c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
3576       parser->error = false;
3577       return NULL_TREE;
3578     }
3579 
3580   pending_xref_error ();
3581   prefix_attrs = specs->attrs;
3582   all_prefix_attrs = prefix_attrs;
3583   specs->attrs = NULL_TREE;
3584   decls = NULL_TREE;
3585   while (true)
3586     {
3587       /* Declaring one or more declarators or un-named bit-fields.  */
3588       struct c_declarator *declarator;
3589       bool dummy = false;
3590       if (c_parser_next_token_is (parser, CPP_COLON))
3591 	declarator = build_id_declarator (NULL_TREE);
3592       else
3593 	declarator = c_parser_declarator (parser,
3594 					  specs->typespec_kind != ctsk_none,
3595 					  C_DTR_NORMAL, &dummy);
3596       if (declarator == NULL)
3597 	{
3598 	  c_parser_skip_to_end_of_block_or_statement (parser);
3599 	  break;
3600 	}
3601       if (c_parser_next_token_is (parser, CPP_COLON)
3602 	  || c_parser_next_token_is (parser, CPP_COMMA)
3603 	  || c_parser_next_token_is (parser, CPP_SEMICOLON)
3604 	  || c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3605 	  || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3606 	{
3607 	  tree postfix_attrs = NULL_TREE;
3608 	  tree width = NULL_TREE;
3609 	  tree d;
3610 	  if (c_parser_next_token_is (parser, CPP_COLON))
3611 	    {
3612 	      c_parser_consume_token (parser);
3613 	      width = c_parser_expr_no_commas (parser, NULL).value;
3614 	    }
3615 	  if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3616 	    postfix_attrs = c_parser_gnu_attributes (parser);
3617 	  d = grokfield (c_parser_peek_token (parser)->location,
3618 			 declarator, specs, width, &all_prefix_attrs);
3619 	  decl_attributes (&d, chainon (postfix_attrs,
3620 					all_prefix_attrs), 0);
3621 	  DECL_CHAIN (d) = decls;
3622 	  decls = d;
3623 	  if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3624 	    all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
3625 					prefix_attrs);
3626 	  else
3627 	    all_prefix_attrs = prefix_attrs;
3628 	  if (c_parser_next_token_is (parser, CPP_COMMA))
3629 	    c_parser_consume_token (parser);
3630 	  else if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3631 		   || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3632 	    {
3633 	      /* Semicolon consumed in caller.  */
3634 	      break;
3635 	    }
3636 	  else
3637 	    {
3638 	      c_parser_error (parser, "expected %<,%>, %<;%> or %<}%>");
3639 	      break;
3640 	    }
3641 	}
3642       else
3643 	{
3644 	  c_parser_error (parser,
3645 			  "expected %<:%>, %<,%>, %<;%>, %<}%> or "
3646 			  "%<__attribute__%>");
3647 	  break;
3648 	}
3649     }
3650   return decls;
3651 }
3652 
3653 /* Parse a typeof specifier (a GNU extension).
3654 
3655    typeof-specifier:
3656      typeof ( expression )
3657      typeof ( type-name )
3658 */
3659 
3660 static struct c_typespec
c_parser_typeof_specifier(c_parser * parser)3661 c_parser_typeof_specifier (c_parser *parser)
3662 {
3663   struct c_typespec ret;
3664   ret.kind = ctsk_typeof;
3665   ret.spec = error_mark_node;
3666   ret.expr = NULL_TREE;
3667   ret.expr_const_operands = true;
3668   gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF));
3669   c_parser_consume_token (parser);
3670   c_inhibit_evaluation_warnings++;
3671   in_typeof++;
3672   matching_parens parens;
3673   if (!parens.require_open (parser))
3674     {
3675       c_inhibit_evaluation_warnings--;
3676       in_typeof--;
3677       return ret;
3678     }
3679   if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
3680     {
3681       struct c_type_name *type = c_parser_type_name (parser);
3682       c_inhibit_evaluation_warnings--;
3683       in_typeof--;
3684       if (type != NULL)
3685 	{
3686 	  ret.spec = groktypename (type, &ret.expr, &ret.expr_const_operands);
3687 	  pop_maybe_used (variably_modified_type_p (ret.spec, NULL_TREE));
3688 	}
3689     }
3690   else
3691     {
3692       bool was_vm;
3693       location_t here = c_parser_peek_token (parser)->location;
3694       struct c_expr expr = c_parser_expression (parser);
3695       c_inhibit_evaluation_warnings--;
3696       in_typeof--;
3697       if (TREE_CODE (expr.value) == COMPONENT_REF
3698 	  && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
3699 	error_at (here, "%<typeof%> applied to a bit-field");
3700       mark_exp_read (expr.value);
3701       ret.spec = TREE_TYPE (expr.value);
3702       was_vm = variably_modified_type_p (ret.spec, NULL_TREE);
3703       /* This is returned with the type so that when the type is
3704 	 evaluated, this can be evaluated.  */
3705       if (was_vm)
3706 	ret.expr = c_fully_fold (expr.value, false, &ret.expr_const_operands);
3707       pop_maybe_used (was_vm);
3708       /* For use in macros such as those in <stdatomic.h>, remove all
3709 	 qualifiers from atomic types.  (const can be an issue for more macros
3710 	 using typeof than just the <stdatomic.h> ones.)  */
3711       if (ret.spec != error_mark_node && TYPE_ATOMIC (ret.spec))
3712 	ret.spec = c_build_qualified_type (ret.spec, TYPE_UNQUALIFIED);
3713     }
3714   parens.skip_until_found_close (parser);
3715   return ret;
3716 }
3717 
3718 /* Parse an alignment-specifier.
3719 
3720    C11 6.7.5:
3721 
3722    alignment-specifier:
3723      _Alignas ( type-name )
3724      _Alignas ( constant-expression )
3725 */
3726 
3727 static tree
c_parser_alignas_specifier(c_parser * parser)3728 c_parser_alignas_specifier (c_parser * parser)
3729 {
3730   tree ret = error_mark_node;
3731   location_t loc = c_parser_peek_token (parser)->location;
3732   gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNAS));
3733   c_parser_consume_token (parser);
3734   if (flag_isoc99)
3735     pedwarn_c99 (loc, OPT_Wpedantic,
3736 		 "ISO C99 does not support %<_Alignas%>");
3737   else
3738     pedwarn_c99 (loc, OPT_Wpedantic,
3739 		 "ISO C90 does not support %<_Alignas%>");
3740   matching_parens parens;
3741   if (!parens.require_open (parser))
3742     return ret;
3743   if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
3744     {
3745       struct c_type_name *type = c_parser_type_name (parser);
3746       if (type != NULL)
3747 	ret = c_sizeof_or_alignof_type (loc, groktypename (type, NULL, NULL),
3748 					false, true, 1);
3749     }
3750   else
3751     ret = c_parser_expr_no_commas (parser, NULL).value;
3752   parens.skip_until_found_close (parser);
3753   return ret;
3754 }
3755 
3756 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
3757    6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7).  If TYPE_SEEN_P then
3758    a typedef name may be redeclared; otherwise it may not.  KIND
3759    indicates which kind of declarator is wanted.  Returns a valid
3760    declarator except in the case of a syntax error in which case NULL is
3761    returned.  *SEEN_ID is set to true if an identifier being declared is
3762    seen; this is used to diagnose bad forms of abstract array declarators
3763    and to determine whether an identifier list is syntactically permitted.
3764 
3765    declarator:
3766      pointer[opt] direct-declarator
3767 
3768    direct-declarator:
3769      identifier
3770      ( gnu-attributes[opt] declarator )
3771      direct-declarator array-declarator
3772      direct-declarator ( parameter-type-list )
3773      direct-declarator ( identifier-list[opt] )
3774 
3775    pointer:
3776      * type-qualifier-list[opt]
3777      * type-qualifier-list[opt] pointer
3778 
3779    type-qualifier-list:
3780      type-qualifier
3781      gnu-attributes
3782      type-qualifier-list type-qualifier
3783      type-qualifier-list gnu-attributes
3784 
3785    array-declarator:
3786      [ type-qualifier-list[opt] assignment-expression[opt] ]
3787      [ static type-qualifier-list[opt] assignment-expression ]
3788      [ type-qualifier-list static assignment-expression ]
3789      [ type-qualifier-list[opt] * ]
3790 
3791    parameter-type-list:
3792      parameter-list
3793      parameter-list , ...
3794 
3795    parameter-list:
3796      parameter-declaration
3797      parameter-list , parameter-declaration
3798 
3799    parameter-declaration:
3800      declaration-specifiers declarator gnu-attributes[opt]
3801      declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
3802 
3803    identifier-list:
3804      identifier
3805      identifier-list , identifier
3806 
3807    abstract-declarator:
3808      pointer
3809      pointer[opt] direct-abstract-declarator
3810 
3811    direct-abstract-declarator:
3812      ( gnu-attributes[opt] abstract-declarator )
3813      direct-abstract-declarator[opt] array-declarator
3814      direct-abstract-declarator[opt] ( parameter-type-list[opt] )
3815 
3816    GNU extensions:
3817 
3818    direct-declarator:
3819      direct-declarator ( parameter-forward-declarations
3820 			 parameter-type-list[opt] )
3821 
3822    direct-abstract-declarator:
3823      direct-abstract-declarator[opt] ( parameter-forward-declarations
3824 				       parameter-type-list[opt] )
3825 
3826    parameter-forward-declarations:
3827      parameter-list ;
3828      parameter-forward-declarations parameter-list ;
3829 
3830    The uses of gnu-attributes shown above are GNU extensions.
3831 
3832    Some forms of array declarator are not included in C99 in the
3833    syntax for abstract declarators; these are disallowed elsewhere.
3834    This may be a defect (DR#289).
3835 
3836    This function also accepts an omitted abstract declarator as being
3837    an abstract declarator, although not part of the formal syntax.  */
3838 
3839 struct c_declarator *
c_parser_declarator(c_parser * parser,bool type_seen_p,c_dtr_syn kind,bool * seen_id)3840 c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
3841 		     bool *seen_id)
3842 {
3843   /* Parse any initial pointer part.  */
3844   if (c_parser_next_token_is (parser, CPP_MULT))
3845     {
3846       struct c_declspecs *quals_attrs = build_null_declspecs ();
3847       struct c_declarator *inner;
3848       c_parser_consume_token (parser);
3849       c_parser_declspecs (parser, quals_attrs, false, false, true,
3850 			  false, false, true, false, cla_prefer_id);
3851       inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
3852       if (inner == NULL)
3853 	return NULL;
3854       else
3855 	return make_pointer_declarator (quals_attrs, inner);
3856     }
3857   /* Now we have a direct declarator, direct abstract declarator or
3858      nothing (which counts as a direct abstract declarator here).  */
3859   return c_parser_direct_declarator (parser, type_seen_p, kind, seen_id);
3860 }
3861 
3862 /* Parse a direct declarator or direct abstract declarator; arguments
3863    as c_parser_declarator.  */
3864 
3865 static struct c_declarator *
c_parser_direct_declarator(c_parser * parser,bool type_seen_p,c_dtr_syn kind,bool * seen_id)3866 c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
3867 			    bool *seen_id)
3868 {
3869   /* The direct declarator must start with an identifier (possibly
3870      omitted) or a parenthesized declarator (possibly abstract).  In
3871      an ordinary declarator, initial parentheses must start a
3872      parenthesized declarator.  In an abstract declarator or parameter
3873      declarator, they could start a parenthesized declarator or a
3874      parameter list.  To tell which, the open parenthesis and any
3875      following gnu-attributes must be read.  If a declaration
3876      specifier or standard attributes follow, then it is a parameter
3877      list; if the specifier is a typedef name, there might be an
3878      ambiguity about redeclaring it, which is resolved in the
3879      direction of treating it as a typedef name.  If a close
3880      parenthesis follows, it is also an empty parameter list, as the
3881      syntax does not permit empty abstract declarators.  Otherwise, it
3882      is a parenthesized declarator (in which case the analysis may be
3883      repeated inside it, recursively).
3884 
3885      ??? There is an ambiguity in a parameter declaration "int
3886      (__attribute__((foo)) x)", where x is not a typedef name: it
3887      could be an abstract declarator for a function, or declare x with
3888      parentheses.  The proper resolution of this ambiguity needs
3889      documenting.  At present we follow an accident of the old
3890      parser's implementation, whereby the first parameter must have
3891      some declaration specifiers other than just gnu-attributes.  Thus as
3892      a parameter declaration it is treated as a parenthesized
3893      parameter named x, and as an abstract declarator it is
3894      rejected.
3895 
3896      ??? Also following the old parser, gnu-attributes inside an empty
3897      parameter list are ignored, making it a list not yielding a
3898      prototype, rather than giving an error or making it have one
3899      parameter with implicit type int.
3900 
3901      ??? Also following the old parser, typedef names may be
3902      redeclared in declarators, but not Objective-C class names.  */
3903 
3904   if (kind != C_DTR_ABSTRACT
3905       && c_parser_next_token_is (parser, CPP_NAME)
3906       && ((type_seen_p
3907 	   && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
3908 	       || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
3909 	  || c_parser_peek_token (parser)->id_kind == C_ID_ID))
3910     {
3911       struct c_declarator *inner
3912 	= build_id_declarator (c_parser_peek_token (parser)->value);
3913       *seen_id = true;
3914       inner->id_loc = c_parser_peek_token (parser)->location;
3915       c_parser_consume_token (parser);
3916       if (c_parser_nth_token_starts_std_attributes (parser, 1))
3917 	inner->u.id.attrs = c_parser_std_attribute_specifier_sequence (parser);
3918       return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3919     }
3920 
3921   if (kind != C_DTR_NORMAL
3922       && c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
3923       && !c_parser_nth_token_starts_std_attributes (parser, 1))
3924     {
3925       struct c_declarator *inner = build_id_declarator (NULL_TREE);
3926       inner->id_loc = c_parser_peek_token (parser)->location;
3927       return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3928     }
3929 
3930   /* Either we are at the end of an abstract declarator, or we have
3931      parentheses.  */
3932 
3933   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3934     {
3935       tree attrs;
3936       struct c_declarator *inner;
3937       c_parser_consume_token (parser);
3938       bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
3939 							    RID_ATTRIBUTE);
3940       attrs = c_parser_gnu_attributes (parser);
3941       if (kind != C_DTR_NORMAL
3942 	  && (c_parser_next_token_starts_declspecs (parser)
3943 	      || (!have_gnu_attrs
3944 		  && c_parser_nth_token_starts_std_attributes (parser, 1))
3945 	      || c_parser_next_token_is (parser, CPP_CLOSE_PAREN)))
3946 	{
3947 	  struct c_arg_info *args
3948 	    = c_parser_parms_declarator (parser, kind == C_DTR_NORMAL,
3949 					 attrs, have_gnu_attrs);
3950 	  if (args == NULL)
3951 	    return NULL;
3952 	  else
3953 	    {
3954 	      inner = build_id_declarator (NULL_TREE);
3955 	      if (!(args->types
3956 		    && args->types != error_mark_node
3957 		    && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
3958 		  && c_parser_nth_token_starts_std_attributes (parser, 1))
3959 		{
3960 		  tree std_attrs
3961 		    = c_parser_std_attribute_specifier_sequence (parser);
3962 		  if (std_attrs)
3963 		    inner = build_attrs_declarator (std_attrs, inner);
3964 		}
3965 	      inner = build_function_declarator (args, inner);
3966 	      return c_parser_direct_declarator_inner (parser, *seen_id,
3967 						       inner);
3968 	    }
3969 	}
3970       /* A parenthesized declarator.  */
3971       inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
3972       if (inner != NULL && attrs != NULL)
3973 	inner = build_attrs_declarator (attrs, inner);
3974       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3975 	{
3976 	  c_parser_consume_token (parser);
3977 	  if (inner == NULL)
3978 	    return NULL;
3979 	  else
3980 	    return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3981 	}
3982       else
3983 	{
3984 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3985 				     "expected %<)%>");
3986 	  return NULL;
3987 	}
3988     }
3989   else
3990     {
3991       if (kind == C_DTR_NORMAL)
3992 	{
3993 	  c_parser_error (parser, "expected identifier or %<(%>");
3994 	  return NULL;
3995 	}
3996       else
3997 	return build_id_declarator (NULL_TREE);
3998     }
3999 }
4000 
4001 /* Parse part of a direct declarator or direct abstract declarator,
4002    given that some (in INNER) has already been parsed; ID_PRESENT is
4003    true if an identifier is present, false for an abstract
4004    declarator.  */
4005 
4006 static struct c_declarator *
c_parser_direct_declarator_inner(c_parser * parser,bool id_present,struct c_declarator * inner)4007 c_parser_direct_declarator_inner (c_parser *parser, bool id_present,
4008 				  struct c_declarator *inner)
4009 {
4010   /* Parse a sequence of array declarators and parameter lists.  */
4011   if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
4012       && !c_parser_nth_token_starts_std_attributes (parser, 1))
4013     {
4014       location_t brace_loc = c_parser_peek_token (parser)->location;
4015       struct c_declarator *declarator;
4016       struct c_declspecs *quals_attrs = build_null_declspecs ();
4017       bool static_seen;
4018       bool star_seen;
4019       struct c_expr dimen;
4020       dimen.value = NULL_TREE;
4021       dimen.original_code = ERROR_MARK;
4022       dimen.original_type = NULL_TREE;
4023       c_parser_consume_token (parser);
4024       c_parser_declspecs (parser, quals_attrs, false, false, true,
4025 			  false, false, false, false, cla_prefer_id);
4026       static_seen = c_parser_next_token_is_keyword (parser, RID_STATIC);
4027       if (static_seen)
4028 	c_parser_consume_token (parser);
4029       if (static_seen && !quals_attrs->declspecs_seen_p)
4030 	c_parser_declspecs (parser, quals_attrs, false, false, true,
4031 			    false, false, false, false, cla_prefer_id);
4032       if (!quals_attrs->declspecs_seen_p)
4033 	quals_attrs = NULL;
4034       /* If "static" is present, there must be an array dimension.
4035 	 Otherwise, there may be a dimension, "*", or no
4036 	 dimension.  */
4037       if (static_seen)
4038 	{
4039 	  star_seen = false;
4040 	  dimen = c_parser_expr_no_commas (parser, NULL);
4041 	}
4042       else
4043 	{
4044 	  if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4045 	    {
4046 	      dimen.value = NULL_TREE;
4047 	      star_seen = false;
4048 	    }
4049 	  else if (c_parser_next_token_is (parser, CPP_MULT))
4050 	    {
4051 	      if (c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_SQUARE)
4052 		{
4053 		  dimen.value = NULL_TREE;
4054 		  star_seen = true;
4055 		  c_parser_consume_token (parser);
4056 		}
4057 	      else
4058 		{
4059 		  star_seen = false;
4060 		  dimen = c_parser_expr_no_commas (parser, NULL);
4061 		}
4062 	    }
4063 	  else
4064 	    {
4065 	      star_seen = false;
4066 	      dimen = c_parser_expr_no_commas (parser, NULL);
4067 	    }
4068 	}
4069       if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4070 	c_parser_consume_token (parser);
4071       else
4072 	{
4073 	  c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
4074 				     "expected %<]%>");
4075 	  return NULL;
4076 	}
4077       if (dimen.value)
4078 	dimen = convert_lvalue_to_rvalue (brace_loc, dimen, true, true);
4079       declarator = build_array_declarator (brace_loc, dimen.value, quals_attrs,
4080 					   static_seen, star_seen);
4081       if (declarator == NULL)
4082 	return NULL;
4083       if (c_parser_nth_token_starts_std_attributes (parser, 1))
4084 	{
4085 	  tree std_attrs
4086 	    = c_parser_std_attribute_specifier_sequence (parser);
4087 	  if (std_attrs)
4088 	    inner = build_attrs_declarator (std_attrs, inner);
4089 	}
4090       inner = set_array_declarator_inner (declarator, inner);
4091       return c_parser_direct_declarator_inner (parser, id_present, inner);
4092     }
4093   else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
4094     {
4095       tree attrs;
4096       struct c_arg_info *args;
4097       c_parser_consume_token (parser);
4098       bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
4099 							    RID_ATTRIBUTE);
4100       attrs = c_parser_gnu_attributes (parser);
4101       args = c_parser_parms_declarator (parser, id_present, attrs,
4102 					have_gnu_attrs);
4103       if (args == NULL)
4104 	return NULL;
4105       else
4106 	{
4107 	  if (!(args->types
4108 		&& args->types != error_mark_node
4109 		&& TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
4110 	      && c_parser_nth_token_starts_std_attributes (parser, 1))
4111 	    {
4112 	      tree std_attrs
4113 		= c_parser_std_attribute_specifier_sequence (parser);
4114 	      if (std_attrs)
4115 		inner = build_attrs_declarator (std_attrs, inner);
4116 	    }
4117 	  inner = build_function_declarator (args, inner);
4118 	  return c_parser_direct_declarator_inner (parser, id_present, inner);
4119 	}
4120     }
4121   return inner;
4122 }
4123 
4124 /* Parse a parameter list or identifier list, including the closing
4125    parenthesis but not the opening one.  ATTRS are the gnu-attributes
4126    at the start of the list.  ID_LIST_OK is true if an identifier list
4127    is acceptable; such a list must not have attributes at the start.
4128    HAVE_GNU_ATTRS says whether any gnu-attributes (including empty
4129    attributes) were present (in which case standard attributes cannot
4130    occur).  */
4131 
4132 static struct c_arg_info *
c_parser_parms_declarator(c_parser * parser,bool id_list_ok,tree attrs,bool have_gnu_attrs)4133 c_parser_parms_declarator (c_parser *parser, bool id_list_ok, tree attrs,
4134 			   bool have_gnu_attrs)
4135 {
4136   push_scope ();
4137   declare_parm_level ();
4138   /* If the list starts with an identifier, it is an identifier list.
4139      Otherwise, it is either a prototype list or an empty list.  */
4140   if (id_list_ok
4141       && !attrs
4142       && c_parser_next_token_is (parser, CPP_NAME)
4143       && c_parser_peek_token (parser)->id_kind == C_ID_ID
4144 
4145       /* Look ahead to detect typos in type names.  */
4146       && c_parser_peek_2nd_token (parser)->type != CPP_NAME
4147       && c_parser_peek_2nd_token (parser)->type != CPP_MULT
4148       && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
4149       && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_SQUARE
4150       && c_parser_peek_2nd_token (parser)->type != CPP_KEYWORD)
4151     {
4152       tree list = NULL_TREE, *nextp = &list;
4153       while (c_parser_next_token_is (parser, CPP_NAME)
4154 	     && c_parser_peek_token (parser)->id_kind == C_ID_ID)
4155 	{
4156 	  *nextp = build_tree_list (NULL_TREE,
4157 				    c_parser_peek_token (parser)->value);
4158 	  nextp = & TREE_CHAIN (*nextp);
4159 	  c_parser_consume_token (parser);
4160 	  if (c_parser_next_token_is_not (parser, CPP_COMMA))
4161 	    break;
4162 	  c_parser_consume_token (parser);
4163 	  if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4164 	    {
4165 	      c_parser_error (parser, "expected identifier");
4166 	      break;
4167 	    }
4168 	}
4169       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4170 	{
4171 	  struct c_arg_info *ret = build_arg_info ();
4172 	  ret->types = list;
4173 	  c_parser_consume_token (parser);
4174 	  pop_scope ();
4175 	  return ret;
4176 	}
4177       else
4178 	{
4179 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4180 				     "expected %<)%>");
4181 	  pop_scope ();
4182 	  return NULL;
4183 	}
4184     }
4185   else
4186     {
4187       struct c_arg_info *ret
4188 	= c_parser_parms_list_declarator (parser, attrs, NULL, have_gnu_attrs);
4189       pop_scope ();
4190       return ret;
4191     }
4192 }
4193 
4194 /* Parse a parameter list (possibly empty), including the closing
4195    parenthesis but not the opening one.  ATTRS are the gnu-attributes
4196    at the start of the list; if HAVE_GNU_ATTRS, there were some such
4197    attributes (possibly empty, in which case ATTRS is NULL_TREE),
4198    which means standard attributes cannot start the list.  EXPR is
4199    NULL or an expression that needs to be evaluated for the side
4200    effects of array size expressions in the parameters.  */
4201 
4202 static struct c_arg_info *
c_parser_parms_list_declarator(c_parser * parser,tree attrs,tree expr,bool have_gnu_attrs)4203 c_parser_parms_list_declarator (c_parser *parser, tree attrs, tree expr,
4204 				bool have_gnu_attrs)
4205 {
4206   bool bad_parm = false;
4207 
4208   /* ??? Following the old parser, forward parameter declarations may
4209      use abstract declarators, and if no real parameter declarations
4210      follow the forward declarations then this is not diagnosed.  Also
4211      note as above that gnu-attributes are ignored as the only contents of
4212      the parentheses, or as the only contents after forward
4213      declarations.  */
4214   if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4215     {
4216       struct c_arg_info *ret = build_arg_info ();
4217       c_parser_consume_token (parser);
4218       return ret;
4219     }
4220   if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4221     {
4222       struct c_arg_info *ret = build_arg_info ();
4223 
4224       if (flag_allow_parameterless_variadic_functions)
4225         {
4226           /* F (...) is allowed.  */
4227           ret->types = NULL_TREE;
4228         }
4229       else
4230         {
4231           /* Suppress -Wold-style-definition for this case.  */
4232           ret->types = error_mark_node;
4233           error_at (c_parser_peek_token (parser)->location,
4234                     "ISO C requires a named argument before %<...%>");
4235         }
4236       c_parser_consume_token (parser);
4237       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4238 	{
4239 	  c_parser_consume_token (parser);
4240 	  return ret;
4241 	}
4242       else
4243 	{
4244 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4245 				     "expected %<)%>");
4246 	  return NULL;
4247 	}
4248     }
4249   /* Nonempty list of parameters, either terminated with semicolon
4250      (forward declarations; recurse) or with close parenthesis (normal
4251      function) or with ", ... )" (variadic function).  */
4252   while (true)
4253     {
4254       /* Parse a parameter.  */
4255       struct c_parm *parm = c_parser_parameter_declaration (parser, attrs,
4256 							    have_gnu_attrs);
4257       attrs = NULL_TREE;
4258       have_gnu_attrs = false;
4259       if (parm == NULL)
4260 	bad_parm = true;
4261       else
4262 	push_parm_decl (parm, &expr);
4263       if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4264 	{
4265 	  tree new_attrs;
4266 	  c_parser_consume_token (parser);
4267 	  mark_forward_parm_decls ();
4268 	  bool new_have_gnu_attrs
4269 	    = c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE);
4270 	  new_attrs = c_parser_gnu_attributes (parser);
4271 	  return c_parser_parms_list_declarator (parser, new_attrs, expr,
4272 						 new_have_gnu_attrs);
4273 	}
4274       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4275 	{
4276 	  c_parser_consume_token (parser);
4277 	  if (bad_parm)
4278 	    return NULL;
4279 	  else
4280 	    return get_parm_info (false, expr);
4281 	}
4282       if (!c_parser_require (parser, CPP_COMMA,
4283 			     "expected %<;%>, %<,%> or %<)%>",
4284 			     UNKNOWN_LOCATION, false))
4285 	{
4286 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4287 	  return NULL;
4288 	}
4289       if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4290 	{
4291 	  c_parser_consume_token (parser);
4292 	  if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4293 	    {
4294 	      c_parser_consume_token (parser);
4295 	      if (bad_parm)
4296 		return NULL;
4297 	      else
4298 		return get_parm_info (true, expr);
4299 	    }
4300 	  else
4301 	    {
4302 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4303 					 "expected %<)%>");
4304 	      return NULL;
4305 	    }
4306 	}
4307     }
4308 }
4309 
4310 /* Parse a parameter declaration.  ATTRS are the gnu-attributes at the
4311    start of the declaration if it is the first parameter;
4312    HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even
4313    empty) there.  */
4314 
4315 static struct c_parm *
c_parser_parameter_declaration(c_parser * parser,tree attrs,bool have_gnu_attrs)4316 c_parser_parameter_declaration (c_parser *parser, tree attrs,
4317 				bool have_gnu_attrs)
4318 {
4319   struct c_declspecs *specs;
4320   struct c_declarator *declarator;
4321   tree prefix_attrs;
4322   tree postfix_attrs = NULL_TREE;
4323   bool dummy = false;
4324 
4325   /* Accept #pragmas between parameter declarations.  */
4326   while (c_parser_next_token_is (parser, CPP_PRAGMA))
4327     c_parser_pragma (parser, pragma_param, NULL);
4328 
4329   if (!c_parser_next_token_starts_declspecs (parser)
4330       && !c_parser_nth_token_starts_std_attributes (parser, 1))
4331     {
4332       c_token *token = c_parser_peek_token (parser);
4333       if (parser->error)
4334 	return NULL;
4335       c_parser_set_source_position_from_token (token);
4336       if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
4337 	{
4338 	  auto_diagnostic_group d;
4339 	  name_hint hint = lookup_name_fuzzy (token->value,
4340 					      FUZZY_LOOKUP_TYPENAME,
4341 					      token->location);
4342 	  if (const char *suggestion = hint.suggestion ())
4343 	    {
4344 	      gcc_rich_location richloc (token->location);
4345 	      richloc.add_fixit_replace (suggestion);
4346 	      error_at (&richloc,
4347 			"unknown type name %qE; did you mean %qs?",
4348 			token->value, suggestion);
4349 	    }
4350 	  else
4351 	    error_at (token->location, "unknown type name %qE", token->value);
4352 	  parser->error = true;
4353 	}
4354       /* ??? In some Objective-C cases '...' isn't applicable so there
4355 	 should be a different message.  */
4356       else
4357 	c_parser_error (parser,
4358 			"expected declaration specifiers or %<...%>");
4359       c_parser_skip_to_end_of_parameter (parser);
4360       return NULL;
4361     }
4362 
4363   location_t start_loc = c_parser_peek_token (parser)->location;
4364 
4365   specs = build_null_declspecs ();
4366   if (attrs)
4367     {
4368       declspecs_add_attrs (input_location, specs, attrs);
4369       attrs = NULL_TREE;
4370     }
4371   c_parser_declspecs (parser, specs, true, true, true, true, false,
4372 		      !have_gnu_attrs, true, cla_nonabstract_decl);
4373   finish_declspecs (specs);
4374   pending_xref_error ();
4375   prefix_attrs = specs->attrs;
4376   specs->attrs = NULL_TREE;
4377   declarator = c_parser_declarator (parser,
4378 				    specs->typespec_kind != ctsk_none,
4379 				    C_DTR_PARM, &dummy);
4380   if (declarator == NULL)
4381     {
4382       c_parser_skip_until_found (parser, CPP_COMMA, NULL);
4383       return NULL;
4384     }
4385   if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4386     postfix_attrs = c_parser_gnu_attributes (parser);
4387 
4388   /* Generate a location for the parameter, ranging from the start of the
4389      initial token to the end of the final token.
4390 
4391      If we have a identifier, then use it for the caret location, e.g.
4392 
4393        extern int callee (int one, int (*two)(int, int), float three);
4394                                    ~~~~~~^~~~~~~~~~~~~~
4395 
4396      otherwise, reuse the start location for the caret location e.g.:
4397 
4398        extern int callee (int one, int (*)(int, int), float three);
4399                                    ^~~~~~~~~~~~~~~~~
4400   */
4401   location_t end_loc = parser->last_token_location;
4402 
4403   /* Find any cdk_id declarator; determine if we have an identifier.  */
4404   c_declarator *id_declarator = declarator;
4405   while (id_declarator && id_declarator->kind != cdk_id)
4406     id_declarator = id_declarator->declarator;
4407   location_t caret_loc = (id_declarator->u.id.id
4408 			  ? id_declarator->id_loc
4409 			  : start_loc);
4410   location_t param_loc = make_location (caret_loc, start_loc, end_loc);
4411 
4412   return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
4413 		       declarator, param_loc);
4414 }
4415 
4416 /* Parse a string literal in an asm expression.  It should not be
4417    translated, and wide string literals are an error although
4418    permitted by the syntax.  This is a GNU extension.
4419 
4420    asm-string-literal:
4421      string-literal
4422 */
4423 
4424 static tree
c_parser_asm_string_literal(c_parser * parser)4425 c_parser_asm_string_literal (c_parser *parser)
4426 {
4427   tree str;
4428   int save_flag = warn_overlength_strings;
4429   warn_overlength_strings = 0;
4430   str = c_parser_string_literal (parser, false, false).value;
4431   warn_overlength_strings = save_flag;
4432   return str;
4433 }
4434 
4435 /* Parse a simple asm expression.  This is used in restricted
4436    contexts, where a full expression with inputs and outputs does not
4437    make sense.  This is a GNU extension.
4438 
4439    simple-asm-expr:
4440      asm ( asm-string-literal )
4441 */
4442 
4443 static tree
c_parser_simple_asm_expr(c_parser * parser)4444 c_parser_simple_asm_expr (c_parser *parser)
4445 {
4446   tree str;
4447   gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
4448   c_parser_consume_token (parser);
4449   matching_parens parens;
4450   if (!parens.require_open (parser))
4451     return NULL_TREE;
4452   str = c_parser_asm_string_literal (parser);
4453   if (!parens.require_close (parser))
4454     {
4455       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4456       return NULL_TREE;
4457     }
4458   return str;
4459 }
4460 
4461 static tree
c_parser_gnu_attribute_any_word(c_parser * parser)4462 c_parser_gnu_attribute_any_word (c_parser *parser)
4463 {
4464   tree attr_name = NULL_TREE;
4465 
4466   if (c_parser_next_token_is (parser, CPP_KEYWORD))
4467     {
4468       /* ??? See comment above about what keywords are accepted here.  */
4469       bool ok;
4470       switch (c_parser_peek_token (parser)->keyword)
4471 	{
4472 	case RID_STATIC:
4473 	case RID_UNSIGNED:
4474 	case RID_LONG:
4475 	case RID_CONST:
4476 	case RID_EXTERN:
4477 	case RID_REGISTER:
4478 	case RID_TYPEDEF:
4479 	case RID_SHORT:
4480 	case RID_INLINE:
4481 	case RID_NORETURN:
4482 	case RID_VOLATILE:
4483 	case RID_SIGNED:
4484 	case RID_AUTO:
4485 	case RID_RESTRICT:
4486 	case RID_COMPLEX:
4487 	case RID_THREAD:
4488 	case RID_INT:
4489 	case RID_CHAR:
4490 	case RID_FLOAT:
4491 	case RID_DOUBLE:
4492 	case RID_VOID:
4493 	case RID_DFLOAT32:
4494 	case RID_DFLOAT64:
4495 	case RID_DFLOAT128:
4496 	CASE_RID_FLOATN_NX:
4497 	case RID_BOOL:
4498 	case RID_FRACT:
4499 	case RID_ACCUM:
4500 	case RID_SAT:
4501 	case RID_TRANSACTION_ATOMIC:
4502 	case RID_TRANSACTION_CANCEL:
4503 	case RID_ATOMIC:
4504 	case RID_AUTO_TYPE:
4505 	case RID_INT_N_0:
4506 	case RID_INT_N_1:
4507 	case RID_INT_N_2:
4508 	case RID_INT_N_3:
4509 	  ok = true;
4510 	  break;
4511 	default:
4512 	  ok = false;
4513 	  break;
4514 	}
4515       if (!ok)
4516 	return NULL_TREE;
4517 
4518       /* Accept __attribute__((__const)) as __attribute__((const)) etc.  */
4519       attr_name = ridpointers[(int) c_parser_peek_token (parser)->keyword];
4520     }
4521   else if (c_parser_next_token_is (parser, CPP_NAME))
4522     attr_name = c_parser_peek_token (parser)->value;
4523 
4524   return attr_name;
4525 }
4526 
4527 /* Parse attribute arguments.  This is a common form of syntax
4528    covering all currently valid GNU and standard attributes.
4529 
4530    gnu-attribute-arguments:
4531      identifier
4532      identifier , nonempty-expr-list
4533      expr-list
4534 
4535    where the "identifier" must not be declared as a type.  ??? Why not
4536    allow identifiers declared as types to start the arguments?  */
4537 
4538 static tree
c_parser_attribute_arguments(c_parser * parser,bool takes_identifier,bool require_string,bool allow_empty_args)4539 c_parser_attribute_arguments (c_parser *parser, bool takes_identifier,
4540 			      bool require_string, bool allow_empty_args)
4541 {
4542   vec<tree, va_gc> *expr_list;
4543   tree attr_args;
4544   /* Parse the attribute contents.  If they start with an
4545      identifier which is followed by a comma or close
4546      parenthesis, then the arguments start with that
4547      identifier; otherwise they are an expression list.
4548      In objective-c the identifier may be a classname.  */
4549   if (c_parser_next_token_is (parser, CPP_NAME)
4550       && (c_parser_peek_token (parser)->id_kind == C_ID_ID
4551 	  || (c_dialect_objc ()
4552 	      && c_parser_peek_token (parser)->id_kind
4553 	      == C_ID_CLASSNAME))
4554       && ((c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
4555 	  || (c_parser_peek_2nd_token (parser)->type
4556 	      == CPP_CLOSE_PAREN))
4557       && (takes_identifier
4558 	  || (c_dialect_objc ()
4559 	      && c_parser_peek_token (parser)->id_kind
4560 	      == C_ID_CLASSNAME)))
4561     {
4562       tree arg1 = c_parser_peek_token (parser)->value;
4563       c_parser_consume_token (parser);
4564       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4565 	attr_args = build_tree_list (NULL_TREE, arg1);
4566       else
4567 	{
4568 	  tree tree_list;
4569 	  c_parser_consume_token (parser);
4570 	  expr_list = c_parser_expr_list (parser, false, true,
4571 					  NULL, NULL, NULL, NULL);
4572 	  tree_list = build_tree_list_vec (expr_list);
4573 	  attr_args = tree_cons (NULL_TREE, arg1, tree_list);
4574 	  release_tree_vector (expr_list);
4575 	}
4576     }
4577   else
4578     {
4579       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4580 	{
4581 	  if (!allow_empty_args)
4582 	    error_at (c_parser_peek_token (parser)->location,
4583 		      "parentheses must be omitted if "
4584 		      "attribute argument list is empty");
4585 	  attr_args = NULL_TREE;
4586 	}
4587       else if (require_string)
4588 	{
4589 	  /* The only valid argument for this attribute is a string
4590 	     literal.  Handle this specially here to avoid accepting
4591 	     string literals with excess parentheses.  */
4592 	  tree string = c_parser_string_literal (parser, false, true).value;
4593 	  attr_args = build_tree_list (NULL_TREE, string);
4594 	}
4595       else
4596 	{
4597 	  expr_list = c_parser_expr_list (parser, false, true,
4598 					  NULL, NULL, NULL, NULL);
4599 	  attr_args = build_tree_list_vec (expr_list);
4600 	  release_tree_vector (expr_list);
4601 	}
4602     }
4603   return attr_args;
4604 }
4605 
4606 /* Parse (possibly empty) gnu-attributes.  This is a GNU extension.
4607 
4608    gnu-attributes:
4609      empty
4610      gnu-attributes gnu-attribute
4611 
4612    gnu-attribute:
4613      __attribute__ ( ( gnu-attribute-list ) )
4614 
4615    gnu-attribute-list:
4616      gnu-attrib
4617      gnu-attribute_list , gnu-attrib
4618 
4619    gnu-attrib:
4620      empty
4621      any-word
4622      any-word ( gnu-attribute-arguments )
4623 
4624    where "any-word" may be any identifier (including one declared as a
4625    type), a reserved word storage class specifier, type specifier or
4626    type qualifier.  ??? This still leaves out most reserved keywords
4627    (following the old parser), shouldn't we include them?
4628    When EXPECT_COMMA is true, expect the attribute to be preceded
4629    by a comma and fail if it isn't.
4630    When EMPTY_OK is true, allow and consume any number of consecutive
4631    commas with no attributes in between.  */
4632 
4633 static tree
4634 c_parser_gnu_attribute (c_parser *parser, tree attrs,
4635 			bool expect_comma = false, bool empty_ok = true)
4636 {
4637   bool comma_first = c_parser_next_token_is (parser, CPP_COMMA);
4638   if (!comma_first
4639       && !c_parser_next_token_is (parser, CPP_NAME)
4640       && !c_parser_next_token_is (parser, CPP_KEYWORD))
4641     return NULL_TREE;
4642 
4643   while (c_parser_next_token_is (parser, CPP_COMMA))
4644     {
4645       c_parser_consume_token (parser);
4646       if (!empty_ok)
4647 	return attrs;
4648     }
4649 
4650   tree attr_name = c_parser_gnu_attribute_any_word (parser);
4651   if (attr_name == NULL_TREE)
4652     return NULL_TREE;
4653 
4654   attr_name = canonicalize_attr_name (attr_name);
4655   c_parser_consume_token (parser);
4656 
4657   tree attr;
4658   if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
4659     {
4660       if (expect_comma && !comma_first)
4661 	{
4662 	  /* A comma is missing between the last attribute on the chain
4663 	     and this one.  */
4664 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4665 				     "expected %<)%>");
4666 	  return error_mark_node;
4667 	}
4668       attr = build_tree_list (attr_name, NULL_TREE);
4669       /* Add this attribute to the list.  */
4670       attrs = chainon (attrs, attr);
4671       return attrs;
4672     }
4673   c_parser_consume_token (parser);
4674 
4675   tree attr_args
4676     = c_parser_attribute_arguments (parser,
4677 				    attribute_takes_identifier_p (attr_name),
4678 				    false, true);
4679 
4680   attr = build_tree_list (attr_name, attr_args);
4681   if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4682     c_parser_consume_token (parser);
4683   else
4684     {
4685       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4686 				 "expected %<)%>");
4687       return error_mark_node;
4688     }
4689 
4690   if (expect_comma && !comma_first)
4691     {
4692       /* A comma is missing between the last attribute on the chain
4693 	 and this one.  */
4694       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4695 				 "expected %<)%>");
4696       return error_mark_node;
4697     }
4698 
4699   /* Add this attribute to the list.  */
4700   attrs = chainon (attrs, attr);
4701   return attrs;
4702 }
4703 
4704 static tree
c_parser_gnu_attributes(c_parser * parser)4705 c_parser_gnu_attributes (c_parser *parser)
4706 {
4707   tree attrs = NULL_TREE;
4708   while (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4709     {
4710       bool save_translate_strings_p = parser->translate_strings_p;
4711       parser->translate_strings_p = false;
4712       /* Consume the `__attribute__' keyword.  */
4713       c_parser_consume_token (parser);
4714       /* Look for the two `(' tokens.  */
4715       if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4716 	{
4717 	  parser->translate_strings_p = save_translate_strings_p;
4718 	  return attrs;
4719 	}
4720       if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4721 	{
4722 	  parser->translate_strings_p = save_translate_strings_p;
4723 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4724 	  return attrs;
4725 	}
4726       /* Parse the attribute list.  Require a comma between successive
4727 	 (possibly empty) attributes.  */
4728       for (bool expect_comma = false; ; expect_comma = true)
4729 	{
4730 	  /* Parse a single attribute.  */
4731 	  tree attr = c_parser_gnu_attribute (parser, attrs, expect_comma);
4732 	  if (attr == error_mark_node)
4733 	    return attrs;
4734 	  if (!attr)
4735 	    break;
4736 	  attrs = attr;
4737       }
4738 
4739       /* Look for the two `)' tokens.  */
4740       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4741 	c_parser_consume_token (parser);
4742       else
4743 	{
4744 	  parser->translate_strings_p = save_translate_strings_p;
4745 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4746 				     "expected %<)%>");
4747 	  return attrs;
4748 	}
4749       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4750 	c_parser_consume_token (parser);
4751       else
4752 	{
4753 	  parser->translate_strings_p = save_translate_strings_p;
4754 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4755 				     "expected %<)%>");
4756 	  return attrs;
4757 	}
4758       parser->translate_strings_p = save_translate_strings_p;
4759     }
4760 
4761   return attrs;
4762 }
4763 
4764 /* Parse an optional balanced token sequence.
4765 
4766    balanced-token-sequence:
4767      balanced-token
4768      balanced-token-sequence balanced-token
4769 
4770    balanced-token:
4771      ( balanced-token-sequence[opt] )
4772      [ balanced-token-sequence[opt] ]
4773      { balanced-token-sequence[opt] }
4774      any token other than ()[]{}
4775 */
4776 
4777 static void
c_parser_balanced_token_sequence(c_parser * parser)4778 c_parser_balanced_token_sequence (c_parser *parser)
4779 {
4780   while (true)
4781     {
4782       c_token *token = c_parser_peek_token (parser);
4783       switch (token->type)
4784 	{
4785 	case CPP_OPEN_BRACE:
4786 	  {
4787 	    matching_braces braces;
4788 	    braces.consume_open (parser);
4789 	    c_parser_balanced_token_sequence (parser);
4790 	    braces.require_close (parser);
4791 	    break;
4792 	  }
4793 
4794 	case CPP_OPEN_PAREN:
4795 	  {
4796 	    matching_parens parens;
4797 	    parens.consume_open (parser);
4798 	    c_parser_balanced_token_sequence (parser);
4799 	    parens.require_close (parser);
4800 	    break;
4801 	  }
4802 
4803 	case CPP_OPEN_SQUARE:
4804 	  c_parser_consume_token (parser);
4805 	  c_parser_balanced_token_sequence (parser);
4806 	  c_parser_require (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
4807 	  break;
4808 
4809 	case CPP_CLOSE_BRACE:
4810 	case CPP_CLOSE_PAREN:
4811 	case CPP_CLOSE_SQUARE:
4812 	case CPP_EOF:
4813 	  return;
4814 
4815 	default:
4816 	  c_parser_consume_token (parser);
4817 	  break;
4818 	}
4819     }
4820 }
4821 
4822 /* Parse standard (C2X) attributes (including GNU attributes in the
4823    gnu:: namespace).
4824 
4825    attribute-specifier-sequence:
4826      attribute-specifier-sequence[opt] attribute-specifier
4827 
4828    attribute-specifier:
4829      [ [ attribute-list ] ]
4830 
4831    attribute-list:
4832      attribute[opt]
4833      attribute-list, attribute[opt]
4834 
4835    attribute:
4836      attribute-token attribute-argument-clause[opt]
4837 
4838    attribute-token:
4839      standard-attribute
4840      attribute-prefixed-token
4841 
4842    standard-attribute:
4843      identifier
4844 
4845    attribute-prefixed-token:
4846      attribute-prefix :: identifier
4847 
4848    attribute-prefix:
4849      identifier
4850 
4851    attribute-argument-clause:
4852      ( balanced-token-sequence[opt] )
4853 
4854    Keywords are accepted as identifiers for this purpose.
4855 */
4856 
4857 static tree
c_parser_std_attribute(c_parser * parser,bool for_tm)4858 c_parser_std_attribute (c_parser *parser, bool for_tm)
4859 {
4860   c_token *token = c_parser_peek_token (parser);
4861   tree ns, name, attribute;
4862 
4863   /* Parse the attribute-token.  */
4864   if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
4865     {
4866       c_parser_error (parser, "expected identifier");
4867       return error_mark_node;
4868     }
4869   name = canonicalize_attr_name (token->value);
4870   c_parser_consume_token (parser);
4871   if (c_parser_next_token_is (parser, CPP_SCOPE))
4872     {
4873       ns = name;
4874       c_parser_consume_token (parser);
4875       token = c_parser_peek_token (parser);
4876       if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
4877 	{
4878 	  c_parser_error (parser, "expected identifier");
4879 	  return error_mark_node;
4880 	}
4881       name = canonicalize_attr_name (token->value);
4882       c_parser_consume_token (parser);
4883     }
4884   else
4885     ns = NULL_TREE;
4886   attribute = build_tree_list (build_tree_list (ns, name), NULL_TREE);
4887 
4888   /* Parse the arguments, if any.  */
4889   const attribute_spec *as = lookup_attribute_spec (TREE_PURPOSE (attribute));
4890   if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
4891     goto out;
4892   {
4893     location_t open_loc = c_parser_peek_token (parser)->location;
4894     matching_parens parens;
4895     parens.consume_open (parser);
4896     if ((as && as->max_length == 0)
4897 	/* Special-case the transactional-memory attribute "outer",
4898 	   which is specially handled but not registered as an
4899 	   attribute, to avoid allowing arbitrary balanced token
4900 	   sequences as arguments.  */
4901 	|| is_attribute_p ("outer", name))
4902       {
4903 	error_at (open_loc, "%qE attribute does not take any arguments", name);
4904 	parens.skip_until_found_close (parser);
4905 	return error_mark_node;
4906       }
4907     if (as)
4908       {
4909 	bool takes_identifier
4910 	  = (ns != NULL_TREE
4911 	     && strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0
4912 	     && attribute_takes_identifier_p (name));
4913 	bool require_string
4914 	  = (ns == NULL_TREE
4915 	     && strcmp (IDENTIFIER_POINTER (name), "deprecated") == 0);
4916 	TREE_VALUE (attribute)
4917 	  = c_parser_attribute_arguments (parser, takes_identifier,
4918 					  require_string, false);
4919       }
4920     else
4921       c_parser_balanced_token_sequence (parser);
4922     parens.require_close (parser);
4923   }
4924  out:
4925   if (ns == NULL_TREE && !for_tm && !as && !is_attribute_p ("nodiscard", name))
4926     {
4927       /* An attribute with standard syntax and no namespace specified
4928 	 is a constraint violation if it is not one of the known
4929 	 standard attributes (of which nodiscard is the only one
4930 	 without a handler in GCC).  Diagnose it here with a pedwarn
4931 	 and then discard it to prevent a duplicate warning later.  */
4932       pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored",
4933 	       name);
4934       return error_mark_node;
4935     }
4936   return attribute;
4937 }
4938 
4939 static tree
c_parser_std_attribute_specifier(c_parser * parser,bool for_tm)4940 c_parser_std_attribute_specifier (c_parser *parser, bool for_tm)
4941 {
4942   bool seen_deprecated = false;
4943   bool seen_fallthrough = false;
4944   bool seen_maybe_unused = false;
4945   location_t loc = c_parser_peek_token (parser)->location;
4946   if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
4947     return NULL_TREE;
4948   if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
4949     {
4950       c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
4951       return NULL_TREE;
4952     }
4953   if (!for_tm)
4954     pedwarn_c11 (loc, OPT_Wpedantic,
4955 		 "ISO C does not support %<[[]]%> attributes before C2X");
4956   tree attributes = NULL_TREE;
4957   while (true)
4958     {
4959       c_token *token = c_parser_peek_token (parser);
4960       if (token->type == CPP_CLOSE_SQUARE)
4961 	break;
4962       if (token->type == CPP_COMMA)
4963 	{
4964 	  c_parser_consume_token (parser);
4965 	  continue;
4966 	}
4967       tree attribute = c_parser_std_attribute (parser, for_tm);
4968       if (attribute != error_mark_node)
4969 	{
4970 	  bool duplicate = false;
4971 	  tree name = get_attribute_name (attribute);
4972 	  tree ns = get_attribute_namespace (attribute);
4973 	  if (ns == NULL_TREE)
4974 	    {
4975 	      /* Some standard attributes may appear at most once in
4976 		 each attribute list.  Diagnose duplicates and remove
4977 		 them from the list to avoid subsequent diagnostics
4978 		 such as the more general one for multiple
4979 		 "fallthrough" attributes in the same place (including
4980 		 in separate attribute lists in the same attribute
4981 		 specifier sequence, which is not a constraint
4982 		 violation).  */
4983 	      if (is_attribute_p ("deprecated", name))
4984 		{
4985 		  if (seen_deprecated)
4986 		    {
4987 		      error ("attribute %<deprecated%> can appear at most "
4988 			     "once in an attribute-list");
4989 		      duplicate = true;
4990 		    }
4991 		  seen_deprecated = true;
4992 		}
4993 	      else if (is_attribute_p ("fallthrough", name))
4994 		{
4995 		  if (seen_fallthrough)
4996 		    {
4997 		      error ("attribute %<fallthrough%> can appear at most "
4998 			     "once in an attribute-list");
4999 		      duplicate = true;
5000 		    }
5001 		  seen_fallthrough = true;
5002 		}
5003 	      else if (is_attribute_p ("maybe_unused", name))
5004 		{
5005 		  if (seen_maybe_unused)
5006 		    {
5007 		      error ("attribute %<maybe_unused%> can appear at most "
5008 			     "once in an attribute-list");
5009 		      duplicate = true;
5010 		    }
5011 		  seen_maybe_unused = true;
5012 		}
5013 	    }
5014 	  if (!duplicate)
5015 	    {
5016 	      TREE_CHAIN (attribute) = attributes;
5017 	      attributes = attribute;
5018 	    }
5019 	}
5020       if (c_parser_next_token_is_not (parser, CPP_COMMA))
5021 	break;
5022     }
5023   c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5024   c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5025   return nreverse (attributes);
5026 }
5027 
5028 /* Look past an optional balanced token sequence of raw look-ahead
5029    tokens starting with the *Nth token.  *N is updated to point to the
5030    following token.  Return true if such a sequence was found, false
5031    if the tokens parsed were not balanced.  */
5032 
5033 static bool
c_parser_check_balanced_raw_token_sequence(c_parser * parser,unsigned int * n)5034 c_parser_check_balanced_raw_token_sequence (c_parser *parser, unsigned int *n)
5035 {
5036   while (true)
5037     {
5038       c_token *token = c_parser_peek_nth_token_raw (parser, *n);
5039       switch (token->type)
5040 	{
5041 	case CPP_OPEN_BRACE:
5042 	  {
5043 	    ++*n;
5044 	    if (c_parser_check_balanced_raw_token_sequence (parser, n))
5045 	      {
5046 		token = c_parser_peek_nth_token_raw (parser, *n);
5047 		if (token->type == CPP_CLOSE_BRACE)
5048 		  ++*n;
5049 		else
5050 		  return false;
5051 	      }
5052 	    else
5053 	      return false;
5054 	    break;
5055 	  }
5056 
5057 	case CPP_OPEN_PAREN:
5058 	  {
5059 	    ++*n;
5060 	    if (c_parser_check_balanced_raw_token_sequence (parser, n))
5061 	      {
5062 		token = c_parser_peek_nth_token_raw (parser, *n);
5063 		if (token->type == CPP_CLOSE_PAREN)
5064 		  ++*n;
5065 		else
5066 		  return false;
5067 	      }
5068 	    else
5069 	      return false;
5070 	    break;
5071 	  }
5072 
5073 	case CPP_OPEN_SQUARE:
5074 	  {
5075 	    ++*n;
5076 	    if (c_parser_check_balanced_raw_token_sequence (parser, n))
5077 	      {
5078 		token = c_parser_peek_nth_token_raw (parser, *n);
5079 		if (token->type == CPP_CLOSE_SQUARE)
5080 		  ++*n;
5081 		else
5082 		  return false;
5083 	      }
5084 	    else
5085 	      return false;
5086 	    break;
5087 	  }
5088 
5089 	case CPP_CLOSE_BRACE:
5090 	case CPP_CLOSE_PAREN:
5091 	case CPP_CLOSE_SQUARE:
5092 	case CPP_EOF:
5093 	  return true;
5094 
5095 	default:
5096 	  ++*n;
5097 	  break;
5098 	}
5099     }
5100 }
5101 
5102 /* Return whether standard attributes start with the Nth token.  */
5103 
5104 static bool
c_parser_nth_token_starts_std_attributes(c_parser * parser,unsigned int n)5105 c_parser_nth_token_starts_std_attributes (c_parser *parser, unsigned int n)
5106 {
5107   if (!(c_parser_peek_nth_token (parser, n)->type == CPP_OPEN_SQUARE
5108 	&& c_parser_peek_nth_token (parser, n + 1)->type == CPP_OPEN_SQUARE))
5109     return false;
5110   /* In C, '[[' must start attributes.  In Objective-C, we need to
5111      check whether '[[' is matched by ']]'.  */
5112   if (!c_dialect_objc ())
5113     return true;
5114   n += 2;
5115   if (!c_parser_check_balanced_raw_token_sequence (parser, &n))
5116     return false;
5117   c_token *token = c_parser_peek_nth_token_raw (parser, n);
5118   if (token->type != CPP_CLOSE_SQUARE)
5119     return false;
5120   token = c_parser_peek_nth_token_raw (parser, n + 1);
5121   return token->type == CPP_CLOSE_SQUARE;
5122 }
5123 
5124 static tree
c_parser_std_attribute_specifier_sequence(c_parser * parser)5125 c_parser_std_attribute_specifier_sequence (c_parser *parser)
5126 {
5127   tree attributes = NULL_TREE;
5128   do
5129     {
5130       tree attrs = c_parser_std_attribute_specifier (parser, false);
5131       attributes = chainon (attributes, attrs);
5132     }
5133   while (c_parser_nth_token_starts_std_attributes (parser, 1));
5134   return attributes;
5135 }
5136 
5137 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7).  ALIGNAS_OK
5138    says whether alignment specifiers are OK (only in cases that might
5139    be the type name of a compound literal).
5140 
5141    type-name:
5142      specifier-qualifier-list abstract-declarator[opt]
5143 */
5144 
5145 struct c_type_name *
c_parser_type_name(c_parser * parser,bool alignas_ok)5146 c_parser_type_name (c_parser *parser, bool alignas_ok)
5147 {
5148   struct c_declspecs *specs = build_null_declspecs ();
5149   struct c_declarator *declarator;
5150   struct c_type_name *ret;
5151   bool dummy = false;
5152   c_parser_declspecs (parser, specs, false, true, true, alignas_ok, false,
5153 		      false, true, cla_prefer_type);
5154   if (!specs->declspecs_seen_p)
5155     {
5156       c_parser_error (parser, "expected specifier-qualifier-list");
5157       return NULL;
5158     }
5159   if (specs->type != error_mark_node)
5160     {
5161       pending_xref_error ();
5162       finish_declspecs (specs);
5163     }
5164   declarator = c_parser_declarator (parser,
5165 				    specs->typespec_kind != ctsk_none,
5166 				    C_DTR_ABSTRACT, &dummy);
5167   if (declarator == NULL)
5168     return NULL;
5169   ret = XOBNEW (&parser_obstack, struct c_type_name);
5170   ret->specs = specs;
5171   ret->declarator = declarator;
5172   return ret;
5173 }
5174 
5175 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
5176 
5177    initializer:
5178      assignment-expression
5179      { initializer-list }
5180      { initializer-list , }
5181 
5182    initializer-list:
5183      designation[opt] initializer
5184      initializer-list , designation[opt] initializer
5185 
5186    designation:
5187      designator-list =
5188 
5189    designator-list:
5190      designator
5191      designator-list designator
5192 
5193    designator:
5194      array-designator
5195      . identifier
5196 
5197    array-designator:
5198      [ constant-expression ]
5199 
5200    GNU extensions:
5201 
5202    initializer:
5203      { }
5204 
5205    designation:
5206      array-designator
5207      identifier :
5208 
5209    array-designator:
5210      [ constant-expression ... constant-expression ]
5211 
5212    Any expression without commas is accepted in the syntax for the
5213    constant-expressions, with non-constant expressions rejected later.
5214 
5215    This function is only used for top-level initializers; for nested
5216    ones, see c_parser_initval.  */
5217 
5218 static struct c_expr
c_parser_initializer(c_parser * parser)5219 c_parser_initializer (c_parser *parser)
5220 {
5221   if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
5222     return c_parser_braced_init (parser, NULL_TREE, false, NULL);
5223   else
5224     {
5225       struct c_expr ret;
5226       location_t loc = c_parser_peek_token (parser)->location;
5227       ret = c_parser_expr_no_commas (parser, NULL);
5228       if (TREE_CODE (ret.value) != STRING_CST
5229 	  && TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR)
5230 	ret = convert_lvalue_to_rvalue (loc, ret, true, true);
5231       return ret;
5232     }
5233 }
5234 
5235 /* The location of the last comma within the current initializer list,
5236    or UNKNOWN_LOCATION if not within one.  */
5237 
5238 location_t last_init_list_comma;
5239 
5240 /* Parse a braced initializer list.  TYPE is the type specified for a
5241    compound literal, and NULL_TREE for other initializers and for
5242    nested braced lists.  NESTED_P is true for nested braced lists,
5243    false for the list of a compound literal or the list that is the
5244    top-level initializer in a declaration.  */
5245 
5246 static struct c_expr
c_parser_braced_init(c_parser * parser,tree type,bool nested_p,struct obstack * outer_obstack)5247 c_parser_braced_init (c_parser *parser, tree type, bool nested_p,
5248 		      struct obstack *outer_obstack)
5249 {
5250   struct c_expr ret;
5251   struct obstack braced_init_obstack;
5252   location_t brace_loc = c_parser_peek_token (parser)->location;
5253   gcc_obstack_init (&braced_init_obstack);
5254   gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
5255   matching_braces braces;
5256   braces.consume_open (parser);
5257   if (nested_p)
5258     {
5259       finish_implicit_inits (brace_loc, outer_obstack);
5260       push_init_level (brace_loc, 0, &braced_init_obstack);
5261     }
5262   else
5263     really_start_incremental_init (type);
5264   if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5265     {
5266       pedwarn (brace_loc, OPT_Wpedantic, "ISO C forbids empty initializer braces");
5267     }
5268   else
5269     {
5270       /* Parse a non-empty initializer list, possibly with a trailing
5271 	 comma.  */
5272       while (true)
5273 	{
5274 	  c_parser_initelt (parser, &braced_init_obstack);
5275 	  if (parser->error)
5276 	    break;
5277 	  if (c_parser_next_token_is (parser, CPP_COMMA))
5278 	    {
5279 	      last_init_list_comma = c_parser_peek_token (parser)->location;
5280 	      c_parser_consume_token (parser);
5281 	    }
5282 	  else
5283 	    break;
5284 	  if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5285 	    break;
5286 	}
5287     }
5288   c_token *next_tok = c_parser_peek_token (parser);
5289   if (next_tok->type != CPP_CLOSE_BRACE)
5290     {
5291       ret.set_error ();
5292       ret.original_code = ERROR_MARK;
5293       ret.original_type = NULL;
5294       braces.skip_until_found_close (parser);
5295       pop_init_level (brace_loc, 0, &braced_init_obstack, last_init_list_comma);
5296       obstack_free (&braced_init_obstack, NULL);
5297       return ret;
5298     }
5299   location_t close_loc = next_tok->location;
5300   c_parser_consume_token (parser);
5301   ret = pop_init_level (brace_loc, 0, &braced_init_obstack, close_loc);
5302   obstack_free (&braced_init_obstack, NULL);
5303   set_c_expr_source_range (&ret, brace_loc, close_loc);
5304   return ret;
5305 }
5306 
5307 /* Parse a nested initializer, including designators.  */
5308 
5309 static void
c_parser_initelt(c_parser * parser,struct obstack * braced_init_obstack)5310 c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
5311 {
5312   /* Parse any designator or designator list.  A single array
5313      designator may have the subsequent "=" omitted in GNU C, but a
5314      longer list or a structure member designator may not.  */
5315   if (c_parser_next_token_is (parser, CPP_NAME)
5316       && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
5317     {
5318       /* Old-style structure member designator.  */
5319       set_init_label (c_parser_peek_token (parser)->location,
5320 		      c_parser_peek_token (parser)->value,
5321 		      c_parser_peek_token (parser)->location,
5322 		      braced_init_obstack);
5323       /* Use the colon as the error location.  */
5324       pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_Wpedantic,
5325 	       "obsolete use of designated initializer with %<:%>");
5326       c_parser_consume_token (parser);
5327       c_parser_consume_token (parser);
5328     }
5329   else
5330     {
5331       /* des_seen is 0 if there have been no designators, 1 if there
5332 	 has been a single array designator and 2 otherwise.  */
5333       int des_seen = 0;
5334       /* Location of a designator.  */
5335       location_t des_loc = UNKNOWN_LOCATION;  /* Quiet warning.  */
5336       while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
5337 	     || c_parser_next_token_is (parser, CPP_DOT))
5338 	{
5339 	  int des_prev = des_seen;
5340 	  if (!des_seen)
5341 	    des_loc = c_parser_peek_token (parser)->location;
5342 	  if (des_seen < 2)
5343 	    des_seen++;
5344 	  if (c_parser_next_token_is (parser, CPP_DOT))
5345 	    {
5346 	      des_seen = 2;
5347 	      c_parser_consume_token (parser);
5348 	      if (c_parser_next_token_is (parser, CPP_NAME))
5349 		{
5350 		  set_init_label (des_loc, c_parser_peek_token (parser)->value,
5351 				  c_parser_peek_token (parser)->location,
5352 				  braced_init_obstack);
5353 		  c_parser_consume_token (parser);
5354 		}
5355 	      else
5356 		{
5357 		  struct c_expr init;
5358 		  init.set_error ();
5359 		  init.original_code = ERROR_MARK;
5360 		  init.original_type = NULL;
5361 		  c_parser_error (parser, "expected identifier");
5362 		  c_parser_skip_until_found (parser, CPP_COMMA, NULL);
5363 		  process_init_element (input_location, init, false,
5364 					braced_init_obstack);
5365 		  return;
5366 		}
5367 	    }
5368 	  else
5369 	    {
5370 	      tree first, second;
5371 	      location_t ellipsis_loc = UNKNOWN_LOCATION;  /* Quiet warning.  */
5372 	      location_t array_index_loc = UNKNOWN_LOCATION;
5373 	      /* ??? Following the old parser, [ objc-receiver
5374 		 objc-message-args ] is accepted as an initializer,
5375 		 being distinguished from a designator by what follows
5376 		 the first assignment expression inside the square
5377 		 brackets, but after a first array designator a
5378 		 subsequent square bracket is for Objective-C taken to
5379 		 start an expression, using the obsolete form of
5380 		 designated initializer without '=', rather than
5381 		 possibly being a second level of designation: in LALR
5382 		 terms, the '[' is shifted rather than reducing
5383 		 designator to designator-list.  */
5384 	      if (des_prev == 1 && c_dialect_objc ())
5385 		{
5386 		  des_seen = des_prev;
5387 		  break;
5388 		}
5389 	      if (des_prev == 0 && c_dialect_objc ())
5390 		{
5391 		  /* This might be an array designator or an
5392 		     Objective-C message expression.  If the former,
5393 		     continue parsing here; if the latter, parse the
5394 		     remainder of the initializer given the starting
5395 		     primary-expression.  ??? It might make sense to
5396 		     distinguish when des_prev == 1 as well; see
5397 		     previous comment.  */
5398 		  tree rec, args;
5399 		  struct c_expr mexpr;
5400 		  c_parser_consume_token (parser);
5401 		  if (c_parser_peek_token (parser)->type == CPP_NAME
5402 		      && ((c_parser_peek_token (parser)->id_kind
5403 			   == C_ID_TYPENAME)
5404 			  || (c_parser_peek_token (parser)->id_kind
5405 			      == C_ID_CLASSNAME)))
5406 		    {
5407 		      /* Type name receiver.  */
5408 		      tree id = c_parser_peek_token (parser)->value;
5409 		      c_parser_consume_token (parser);
5410 		      rec = objc_get_class_reference (id);
5411 		      goto parse_message_args;
5412 		    }
5413 		  first = c_parser_expr_no_commas (parser, NULL).value;
5414 		  mark_exp_read (first);
5415 		  if (c_parser_next_token_is (parser, CPP_ELLIPSIS)
5416 		      || c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
5417 		    goto array_desig_after_first;
5418 		  /* Expression receiver.  So far only one part
5419 		     without commas has been parsed; there might be
5420 		     more of the expression.  */
5421 		  rec = first;
5422 		  while (c_parser_next_token_is (parser, CPP_COMMA))
5423 		    {
5424 		      struct c_expr next;
5425 		      location_t comma_loc, exp_loc;
5426 		      comma_loc = c_parser_peek_token (parser)->location;
5427 		      c_parser_consume_token (parser);
5428 		      exp_loc = c_parser_peek_token (parser)->location;
5429 		      next = c_parser_expr_no_commas (parser, NULL);
5430 		      next = convert_lvalue_to_rvalue (exp_loc, next,
5431 						       true, true);
5432 		      rec = build_compound_expr (comma_loc, rec, next.value);
5433 		    }
5434 		parse_message_args:
5435 		  /* Now parse the objc-message-args.  */
5436 		  args = c_parser_objc_message_args (parser);
5437 		  c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5438 					     "expected %<]%>");
5439 		  mexpr.value
5440 		    = objc_build_message_expr (rec, args);
5441 		  mexpr.original_code = ERROR_MARK;
5442 		  mexpr.original_type = NULL;
5443 		  /* Now parse and process the remainder of the
5444 		     initializer, starting with this message
5445 		     expression as a primary-expression.  */
5446 		  c_parser_initval (parser, &mexpr, braced_init_obstack);
5447 		  return;
5448 		}
5449 	      c_parser_consume_token (parser);
5450 	      array_index_loc = c_parser_peek_token (parser)->location;
5451 	      first = c_parser_expr_no_commas (parser, NULL).value;
5452 	      mark_exp_read (first);
5453 	    array_desig_after_first:
5454 	      if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
5455 		{
5456 		  ellipsis_loc = c_parser_peek_token (parser)->location;
5457 		  c_parser_consume_token (parser);
5458 		  second = c_parser_expr_no_commas (parser, NULL).value;
5459 		  mark_exp_read (second);
5460 		}
5461 	      else
5462 		second = NULL_TREE;
5463 	      if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
5464 		{
5465 		  c_parser_consume_token (parser);
5466 		  set_init_index (array_index_loc, first, second,
5467 				  braced_init_obstack);
5468 		  if (second)
5469 		    pedwarn (ellipsis_loc, OPT_Wpedantic,
5470 			     "ISO C forbids specifying range of elements to initialize");
5471 		}
5472 	      else
5473 		c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5474 					   "expected %<]%>");
5475 	    }
5476 	}
5477       if (des_seen >= 1)
5478 	{
5479 	  if (c_parser_next_token_is (parser, CPP_EQ))
5480 	    {
5481 	      pedwarn_c90 (des_loc, OPT_Wpedantic,
5482 			   "ISO C90 forbids specifying subobject "
5483 			   "to initialize");
5484 	      c_parser_consume_token (parser);
5485 	    }
5486 	  else
5487 	    {
5488 	      if (des_seen == 1)
5489 		pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
5490 			 "obsolete use of designated initializer without %<=%>");
5491 	      else
5492 		{
5493 		  struct c_expr init;
5494 		  init.set_error ();
5495 		  init.original_code = ERROR_MARK;
5496 		  init.original_type = NULL;
5497 		  c_parser_error (parser, "expected %<=%>");
5498 		  c_parser_skip_until_found (parser, CPP_COMMA, NULL);
5499 		  process_init_element (input_location, init, false,
5500 					braced_init_obstack);
5501 		  return;
5502 		}
5503 	    }
5504 	}
5505     }
5506   c_parser_initval (parser, NULL, braced_init_obstack);
5507 }
5508 
5509 /* Parse a nested initializer; as c_parser_initializer but parses
5510    initializers within braced lists, after any designators have been
5511    applied.  If AFTER is not NULL then it is an Objective-C message
5512    expression which is the primary-expression starting the
5513    initializer.  */
5514 
5515 static void
c_parser_initval(c_parser * parser,struct c_expr * after,struct obstack * braced_init_obstack)5516 c_parser_initval (c_parser *parser, struct c_expr *after,
5517 		  struct obstack * braced_init_obstack)
5518 {
5519   struct c_expr init;
5520   gcc_assert (!after || c_dialect_objc ());
5521   location_t loc = c_parser_peek_token (parser)->location;
5522 
5523   if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after)
5524     init = c_parser_braced_init (parser, NULL_TREE, true,
5525 				 braced_init_obstack);
5526   else
5527     {
5528       init = c_parser_expr_no_commas (parser, after);
5529       if (init.value != NULL_TREE
5530 	  && TREE_CODE (init.value) != STRING_CST
5531 	  && TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR)
5532 	init = convert_lvalue_to_rvalue (loc, init, true, true);
5533     }
5534   process_init_element (loc, init, false, braced_init_obstack);
5535 }
5536 
5537 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
5538    C99 6.8.2, C11 6.8.2).
5539 
5540    compound-statement:
5541      { block-item-list[opt] }
5542      { label-declarations block-item-list }
5543 
5544    block-item-list:
5545      block-item
5546      block-item-list block-item
5547 
5548    block-item:
5549      nested-declaration
5550      statement
5551 
5552    nested-declaration:
5553      declaration
5554 
5555    GNU extensions:
5556 
5557    compound-statement:
5558      { label-declarations block-item-list }
5559 
5560    nested-declaration:
5561      __extension__ nested-declaration
5562      nested-function-definition
5563 
5564    label-declarations:
5565      label-declaration
5566      label-declarations label-declaration
5567 
5568    label-declaration:
5569      __label__ identifier-list ;
5570 
5571    Allowing the mixing of declarations and code is new in C99.  The
5572    GNU syntax also permits (not shown above) labels at the end of
5573    compound statements, which yield an error.  We don't allow labels
5574    on declarations; this might seem like a natural extension, but
5575    there would be a conflict between gnu-attributes on the label and
5576    prefix gnu-attributes on the declaration.  ??? The syntax follows the
5577    old parser in requiring something after label declarations.
5578    Although they are erroneous if the labels declared aren't defined,
5579    is it useful for the syntax to be this way?
5580 
5581    OpenACC:
5582 
5583    block-item:
5584      openacc-directive
5585 
5586    openacc-directive:
5587      update-directive
5588 
5589    OpenMP:
5590 
5591    block-item:
5592      openmp-directive
5593 
5594    openmp-directive:
5595      barrier-directive
5596      flush-directive
5597      taskwait-directive
5598      taskyield-directive
5599      cancel-directive
5600      cancellation-point-directive  */
5601 
5602 static tree
c_parser_compound_statement(c_parser * parser,location_t * endlocp)5603 c_parser_compound_statement (c_parser *parser, location_t *endlocp)
5604 {
5605   tree stmt;
5606   location_t brace_loc;
5607   brace_loc = c_parser_peek_token (parser)->location;
5608   if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
5609     {
5610       /* Ensure a scope is entered and left anyway to avoid confusion
5611 	 if we have just prepared to enter a function body.  */
5612       stmt = c_begin_compound_stmt (true);
5613       c_end_compound_stmt (brace_loc, stmt, true);
5614       return error_mark_node;
5615     }
5616   stmt = c_begin_compound_stmt (true);
5617   location_t end_loc = c_parser_compound_statement_nostart (parser);
5618   if (endlocp)
5619     *endlocp = end_loc;
5620 
5621   return c_end_compound_stmt (brace_loc, stmt, true);
5622 }
5623 
5624 /* Parse a compound statement except for the opening brace.  This is
5625    used for parsing both compound statements and statement expressions
5626    (which follow different paths to handling the opening).  */
5627 
5628 static location_t
c_parser_compound_statement_nostart(c_parser * parser)5629 c_parser_compound_statement_nostart (c_parser *parser)
5630 {
5631   bool last_stmt = false;
5632   bool last_label = false;
5633   bool save_valid_for_pragma = valid_location_for_stdc_pragma_p ();
5634   location_t label_loc = UNKNOWN_LOCATION;  /* Quiet warning.  */
5635   if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5636     {
5637       location_t endloc = c_parser_peek_token (parser)->location;
5638       add_debug_begin_stmt (endloc);
5639       c_parser_consume_token (parser);
5640       return endloc;
5641     }
5642   mark_valid_location_for_stdc_pragma (true);
5643   if (c_parser_next_token_is_keyword (parser, RID_LABEL))
5644     {
5645       /* Read zero or more forward-declarations for labels that nested
5646 	 functions can jump to.  */
5647       mark_valid_location_for_stdc_pragma (false);
5648       while (c_parser_next_token_is_keyword (parser, RID_LABEL))
5649 	{
5650 	  label_loc = c_parser_peek_token (parser)->location;
5651 	  c_parser_consume_token (parser);
5652 	  /* Any identifiers, including those declared as type names,
5653 	     are OK here.  */
5654 	  while (true)
5655 	    {
5656 	      tree label;
5657 	      if (c_parser_next_token_is_not (parser, CPP_NAME))
5658 		{
5659 		  c_parser_error (parser, "expected identifier");
5660 		  break;
5661 		}
5662 	      label
5663 		= declare_label (c_parser_peek_token (parser)->value);
5664 	      C_DECLARED_LABEL_FLAG (label) = 1;
5665 	      add_stmt (build_stmt (label_loc, DECL_EXPR, label));
5666 	      c_parser_consume_token (parser);
5667 	      if (c_parser_next_token_is (parser, CPP_COMMA))
5668 		c_parser_consume_token (parser);
5669 	      else
5670 		break;
5671 	    }
5672 	  c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
5673 	}
5674       pedwarn (label_loc, OPT_Wpedantic, "ISO C forbids label declarations");
5675     }
5676   /* We must now have at least one statement, label or declaration.  */
5677   if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5678     {
5679       mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5680       c_parser_error (parser, "expected declaration or statement");
5681       location_t endloc = c_parser_peek_token (parser)->location;
5682       c_parser_consume_token (parser);
5683       return endloc;
5684     }
5685   while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
5686     {
5687       location_t loc = c_parser_peek_token (parser)->location;
5688       loc = expansion_point_location_if_in_system_header (loc);
5689       /* Standard attributes may start a statement or a declaration.  */
5690       bool have_std_attrs
5691 	= c_parser_nth_token_starts_std_attributes (parser, 1);
5692       tree std_attrs = NULL_TREE;
5693       if (have_std_attrs)
5694 	std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5695       if (c_parser_next_token_is_keyword (parser, RID_CASE)
5696 	  || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
5697 	  || (c_parser_next_token_is (parser, CPP_NAME)
5698 	      && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5699 	{
5700 	  c_warn_unused_attributes (std_attrs);
5701 	  if (c_parser_next_token_is_keyword (parser, RID_CASE))
5702 	    label_loc = c_parser_peek_2nd_token (parser)->location;
5703 	  else
5704 	    label_loc = c_parser_peek_token (parser)->location;
5705 	  last_label = true;
5706 	  last_stmt = false;
5707 	  mark_valid_location_for_stdc_pragma (false);
5708 	  c_parser_label (parser);
5709 	}
5710       else if (!last_label
5711 	       && (c_parser_next_tokens_start_declaration (parser)
5712 		   || (have_std_attrs
5713 		       && c_parser_next_token_is (parser, CPP_SEMICOLON))))
5714 	{
5715 	  last_label = false;
5716 	  mark_valid_location_for_stdc_pragma (false);
5717 	  bool fallthru_attr_p = false;
5718 	  c_parser_declaration_or_fndef (parser, true, !have_std_attrs,
5719 					 true, true, true, NULL,
5720 					 vNULL, have_std_attrs, std_attrs,
5721 					 NULL, &fallthru_attr_p);
5722 	  if (last_stmt && !fallthru_attr_p)
5723 	    pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
5724 			 "ISO C90 forbids mixed declarations and code");
5725 	  last_stmt = fallthru_attr_p;
5726 	}
5727       else if (!last_label
5728 	       && c_parser_next_token_is_keyword (parser, RID_EXTENSION))
5729 	{
5730 	  /* __extension__ can start a declaration, but is also an
5731 	     unary operator that can start an expression.  Consume all
5732 	     but the last of a possible series of __extension__ to
5733 	     determine which.  If standard attributes have already
5734 	     been seen, it must start a statement, not a declaration,
5735 	     but standard attributes starting a declaration may appear
5736 	     after __extension__.  */
5737 	  while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
5738 		 && (c_parser_peek_2nd_token (parser)->keyword
5739 		     == RID_EXTENSION))
5740 	    c_parser_consume_token (parser);
5741 	  if (!have_std_attrs
5742 	      && (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
5743 		  || c_parser_nth_token_starts_std_attributes (parser, 2)))
5744 	    {
5745 	      int ext;
5746 	      ext = disable_extension_diagnostics ();
5747 	      c_parser_consume_token (parser);
5748 	      last_label = false;
5749 	      mark_valid_location_for_stdc_pragma (false);
5750 	      c_parser_declaration_or_fndef (parser, true, true, true, true,
5751 					     true, NULL, vNULL);
5752 	      /* Following the old parser, __extension__ does not
5753 		 disable this diagnostic.  */
5754 	      restore_extension_diagnostics (ext);
5755 	      if (last_stmt)
5756 		pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
5757 			     "ISO C90 forbids mixed declarations and code");
5758 	      last_stmt = false;
5759 	    }
5760 	  else
5761 	    goto statement;
5762 	}
5763       else if (c_parser_next_token_is (parser, CPP_PRAGMA))
5764 	{
5765 	  if (have_std_attrs)
5766 	    c_parser_error (parser, "expected declaration or statement");
5767 	  /* External pragmas, and some omp pragmas, are not associated
5768 	     with regular c code, and so are not to be considered statements
5769 	     syntactically.  This ensures that the user doesn't put them
5770 	     places that would turn into syntax errors if the directive
5771 	     were ignored.  */
5772 	  if (c_parser_pragma (parser,
5773 			       last_label ? pragma_stmt : pragma_compound,
5774 			       NULL))
5775 	    last_label = false, last_stmt = true;
5776 	}
5777       else if (c_parser_next_token_is (parser, CPP_EOF))
5778 	{
5779 	  mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5780 	  c_parser_error (parser, "expected declaration or statement");
5781 	  return c_parser_peek_token (parser)->location;
5782 	}
5783       else if (c_parser_next_token_is_keyword (parser, RID_ELSE))
5784         {
5785           if (parser->in_if_block)
5786             {
5787 	      mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5788 	      error_at (loc, "expected %<}%> before %<else%>");
5789 	      return c_parser_peek_token (parser)->location;
5790             }
5791           else
5792             {
5793               error_at (loc, "%<else%> without a previous %<if%>");
5794               c_parser_consume_token (parser);
5795               continue;
5796             }
5797         }
5798       else
5799 	{
5800 	statement:
5801 	  c_warn_unused_attributes (std_attrs);
5802 	  last_label = false;
5803 	  last_stmt = true;
5804 	  mark_valid_location_for_stdc_pragma (false);
5805 	  c_parser_statement_after_labels (parser, NULL);
5806 	}
5807 
5808       parser->error = false;
5809     }
5810   if (last_label)
5811     error_at (label_loc, "label at end of compound statement");
5812   location_t endloc = c_parser_peek_token (parser)->location;
5813   c_parser_consume_token (parser);
5814   /* Restore the value we started with.  */
5815   mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5816   return endloc;
5817 }
5818 
5819 /* Parse all consecutive labels, possibly preceded by standard
5820    attributes.  In this context, a statement is required, not a
5821    declaration, so attributes must be followed by a statement that is
5822    not just a semicolon.  */
5823 
5824 static void
c_parser_all_labels(c_parser * parser)5825 c_parser_all_labels (c_parser *parser)
5826 {
5827   if (c_parser_nth_token_starts_std_attributes (parser, 1))
5828     {
5829       tree std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5830       if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5831 	c_parser_error (parser, "expected statement");
5832       else
5833 	c_warn_unused_attributes (std_attrs);
5834     }
5835   while (c_parser_next_token_is_keyword (parser, RID_CASE)
5836 	 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
5837 	 || (c_parser_next_token_is (parser, CPP_NAME)
5838 	     && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5839     c_parser_label (parser);
5840 }
5841 
5842 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
5843 
5844    label:
5845      identifier : gnu-attributes[opt]
5846      case constant-expression :
5847      default :
5848 
5849    GNU extensions:
5850 
5851    label:
5852      case constant-expression ... constant-expression :
5853 
5854    The use of gnu-attributes on labels is a GNU extension.  The syntax in
5855    GNU C accepts any expressions without commas, non-constant
5856    expressions being rejected later.  Any standard
5857    attribute-specifier-sequence before the first label has been parsed
5858    in the caller, to distinguish statements from declarations.  Any
5859    attribute-specifier-sequence after the label is parsed in this
5860    function.  */
5861 
5862 static void
c_parser_label(c_parser * parser)5863 c_parser_label (c_parser *parser)
5864 {
5865   location_t loc1 = c_parser_peek_token (parser)->location;
5866   tree label = NULL_TREE;
5867 
5868   /* Remember whether this case or a user-defined label is allowed to fall
5869      through to.  */
5870   bool fallthrough_p = c_parser_peek_token (parser)->flags & PREV_FALLTHROUGH;
5871 
5872   if (c_parser_next_token_is_keyword (parser, RID_CASE))
5873     {
5874       tree exp1, exp2;
5875       c_parser_consume_token (parser);
5876       exp1 = c_parser_expr_no_commas (parser, NULL).value;
5877       if (c_parser_next_token_is (parser, CPP_COLON))
5878 	{
5879 	  c_parser_consume_token (parser);
5880 	  label = do_case (loc1, exp1, NULL_TREE);
5881 	}
5882       else if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
5883 	{
5884 	  c_parser_consume_token (parser);
5885 	  exp2 = c_parser_expr_no_commas (parser, NULL).value;
5886 	  if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
5887 	    label = do_case (loc1, exp1, exp2);
5888 	}
5889       else
5890 	c_parser_error (parser, "expected %<:%> or %<...%>");
5891     }
5892   else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
5893     {
5894       c_parser_consume_token (parser);
5895       if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
5896 	label = do_case (loc1, NULL_TREE, NULL_TREE);
5897     }
5898   else
5899     {
5900       tree name = c_parser_peek_token (parser)->value;
5901       tree tlab;
5902       tree attrs;
5903       location_t loc2 = c_parser_peek_token (parser)->location;
5904       gcc_assert (c_parser_next_token_is (parser, CPP_NAME));
5905       c_parser_consume_token (parser);
5906       gcc_assert (c_parser_next_token_is (parser, CPP_COLON));
5907       c_parser_consume_token (parser);
5908       attrs = c_parser_gnu_attributes (parser);
5909       tlab = define_label (loc2, name);
5910       if (tlab)
5911 	{
5912 	  decl_attributes (&tlab, attrs, 0);
5913 	  label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab));
5914 	}
5915     }
5916   if (label)
5917     {
5918       if (TREE_CODE (label) == LABEL_EXPR)
5919 	FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label)) = fallthrough_p;
5920       else
5921 	FALLTHROUGH_LABEL_P (CASE_LABEL (label)) = fallthrough_p;
5922 
5923       /* Standard attributes are only allowed here if they start a
5924 	 statement, not a declaration (including the case of an
5925 	 attribute-declaration with only attributes).  */
5926       bool have_std_attrs
5927 	= c_parser_nth_token_starts_std_attributes (parser, 1);
5928       tree std_attrs = NULL_TREE;
5929       if (have_std_attrs)
5930 	std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5931 
5932       /* Allow '__attribute__((fallthrough));'.  */
5933       if (!have_std_attrs
5934 	  && c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
5935 	{
5936 	  location_t loc = c_parser_peek_token (parser)->location;
5937 	  tree attrs = c_parser_gnu_attributes (parser);
5938 	  if (attribute_fallthrough_p (attrs))
5939 	    {
5940 	      if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5941 		{
5942 		  tree fn = build_call_expr_internal_loc (loc,
5943 							  IFN_FALLTHROUGH,
5944 							  void_type_node, 0);
5945 		  add_stmt (fn);
5946 		}
5947 	      else
5948 		warning_at (loc, OPT_Wattributes, "%<fallthrough%> attribute "
5949 			    "not followed by %<;%>");
5950 	    }
5951 	  else if (attrs != NULL_TREE)
5952 	    warning_at (loc, OPT_Wattributes, "only attribute %<fallthrough%>"
5953 			" can be applied to a null statement");
5954 	}
5955       if (c_parser_next_tokens_start_declaration (parser)
5956 	  || (have_std_attrs
5957 	      && c_parser_next_token_is (parser, CPP_SEMICOLON)))
5958 	{
5959 	  error_at (c_parser_peek_token (parser)->location,
5960 		    "a label can only be part of a statement and "
5961 		    "a declaration is not a statement");
5962 	  c_parser_declaration_or_fndef (parser, /*fndef_ok*/ false,
5963 					 /*static_assert_ok*/ true,
5964 					 /*empty_ok*/ true, /*nested*/ true,
5965 					 /*start_attr_ok*/ true, NULL,
5966 					 vNULL, have_std_attrs, std_attrs);
5967 	}
5968       else if (std_attrs)
5969 	/* Nonempty attributes on the following statement are ignored.  */
5970 	c_warn_unused_attributes (std_attrs);
5971     }
5972 }
5973 
5974 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
5975 
5976    statement:
5977      labeled-statement
5978      attribute-specifier-sequence[opt] compound-statement
5979      expression-statement
5980      attribute-specifier-sequence[opt] selection-statement
5981      attribute-specifier-sequence[opt] iteration-statement
5982      attribute-specifier-sequence[opt] jump-statement
5983 
5984    labeled-statement:
5985      attribute-specifier-sequence[opt] label statement
5986 
5987    expression-statement:
5988      expression[opt] ;
5989      attribute-specifier-sequence expression ;
5990 
5991    selection-statement:
5992      if-statement
5993      switch-statement
5994 
5995    iteration-statement:
5996      while-statement
5997      do-statement
5998      for-statement
5999 
6000    jump-statement:
6001      goto identifier ;
6002      continue ;
6003      break ;
6004      return expression[opt] ;
6005 
6006    GNU extensions:
6007 
6008    statement:
6009      attribute-specifier-sequence[opt] asm-statement
6010 
6011    jump-statement:
6012      goto * expression ;
6013 
6014    expression-statement:
6015      gnu-attributes ;
6016 
6017    Objective-C:
6018 
6019    statement:
6020      attribute-specifier-sequence[opt] objc-throw-statement
6021      attribute-specifier-sequence[opt] objc-try-catch-statement
6022      attribute-specifier-sequence[opt] objc-synchronized-statement
6023 
6024    objc-throw-statement:
6025      @throw expression ;
6026      @throw ;
6027 
6028    OpenACC:
6029 
6030    statement:
6031      attribute-specifier-sequence[opt] openacc-construct
6032 
6033    openacc-construct:
6034      parallel-construct
6035      kernels-construct
6036      data-construct
6037      loop-construct
6038 
6039    parallel-construct:
6040      parallel-directive structured-block
6041 
6042    kernels-construct:
6043      kernels-directive structured-block
6044 
6045    data-construct:
6046      data-directive structured-block
6047 
6048    loop-construct:
6049      loop-directive structured-block
6050 
6051    OpenMP:
6052 
6053    statement:
6054      attribute-specifier-sequence[opt] openmp-construct
6055 
6056    openmp-construct:
6057      parallel-construct
6058      for-construct
6059      simd-construct
6060      for-simd-construct
6061      sections-construct
6062      single-construct
6063      parallel-for-construct
6064      parallel-for-simd-construct
6065      parallel-sections-construct
6066      master-construct
6067      critical-construct
6068      atomic-construct
6069      ordered-construct
6070 
6071    parallel-construct:
6072      parallel-directive structured-block
6073 
6074    for-construct:
6075      for-directive iteration-statement
6076 
6077    simd-construct:
6078      simd-directive iteration-statements
6079 
6080    for-simd-construct:
6081      for-simd-directive iteration-statements
6082 
6083    sections-construct:
6084      sections-directive section-scope
6085 
6086    single-construct:
6087      single-directive structured-block
6088 
6089    parallel-for-construct:
6090      parallel-for-directive iteration-statement
6091 
6092    parallel-for-simd-construct:
6093      parallel-for-simd-directive iteration-statement
6094 
6095    parallel-sections-construct:
6096      parallel-sections-directive section-scope
6097 
6098    master-construct:
6099      master-directive structured-block
6100 
6101    critical-construct:
6102      critical-directive structured-block
6103 
6104    atomic-construct:
6105      atomic-directive expression-statement
6106 
6107    ordered-construct:
6108      ordered-directive structured-block
6109 
6110    Transactional Memory:
6111 
6112    statement:
6113      attribute-specifier-sequence[opt] transaction-statement
6114      attribute-specifier-sequence[opt] transaction-cancel-statement
6115 
6116    IF_P is used to track whether there's a (possibly labeled) if statement
6117    which is not enclosed in braces and has an else clause.  This is used to
6118    implement -Wparentheses.  */
6119 
6120 static void
c_parser_statement(c_parser * parser,bool * if_p,location_t * loc_after_labels)6121 c_parser_statement (c_parser *parser, bool *if_p, location_t *loc_after_labels)
6122 {
6123   c_parser_all_labels (parser);
6124   if (loc_after_labels)
6125     *loc_after_labels = c_parser_peek_token (parser)->location;
6126   c_parser_statement_after_labels (parser, if_p, NULL);
6127 }
6128 
6129 /* Parse a statement, other than a labeled statement.  CHAIN is a vector
6130    of if-else-if conditions.  All labels and standard attributes have
6131    been parsed in the caller.
6132 
6133    IF_P is used to track whether there's a (possibly labeled) if statement
6134    which is not enclosed in braces and has an else clause.  This is used to
6135    implement -Wparentheses.  */
6136 
6137 static void
c_parser_statement_after_labels(c_parser * parser,bool * if_p,vec<tree> * chain)6138 c_parser_statement_after_labels (c_parser *parser, bool *if_p,
6139 				 vec<tree> *chain)
6140 {
6141   location_t loc = c_parser_peek_token (parser)->location;
6142   tree stmt = NULL_TREE;
6143   bool in_if_block = parser->in_if_block;
6144   parser->in_if_block = false;
6145   if (if_p != NULL)
6146     *if_p = false;
6147 
6148   if (c_parser_peek_token (parser)->type != CPP_OPEN_BRACE)
6149     add_debug_begin_stmt (loc);
6150 
6151   switch (c_parser_peek_token (parser)->type)
6152     {
6153     case CPP_OPEN_BRACE:
6154       add_stmt (c_parser_compound_statement (parser));
6155       break;
6156     case CPP_KEYWORD:
6157       switch (c_parser_peek_token (parser)->keyword)
6158 	{
6159 	case RID_IF:
6160 	  c_parser_if_statement (parser, if_p, chain);
6161 	  break;
6162 	case RID_SWITCH:
6163 	  c_parser_switch_statement (parser, if_p);
6164 	  break;
6165 	case RID_WHILE:
6166 	  c_parser_while_statement (parser, false, 0, if_p);
6167 	  break;
6168 	case RID_DO:
6169 	  c_parser_do_statement (parser, 0, false);
6170 	  break;
6171 	case RID_FOR:
6172 	  c_parser_for_statement (parser, false, 0, if_p);
6173 	  break;
6174 	case RID_GOTO:
6175 	  c_parser_consume_token (parser);
6176 	  if (c_parser_next_token_is (parser, CPP_NAME))
6177 	    {
6178 	      stmt = c_finish_goto_label (loc,
6179 					  c_parser_peek_token (parser)->value);
6180 	      c_parser_consume_token (parser);
6181 	    }
6182 	  else if (c_parser_next_token_is (parser, CPP_MULT))
6183 	    {
6184 	      struct c_expr val;
6185 
6186 	      c_parser_consume_token (parser);
6187 	      val = c_parser_expression (parser);
6188 	      val = convert_lvalue_to_rvalue (loc, val, false, true);
6189 	      stmt = c_finish_goto_ptr (loc, val.value);
6190 	    }
6191 	  else
6192 	    c_parser_error (parser, "expected identifier or %<*%>");
6193 	  goto expect_semicolon;
6194 	case RID_CONTINUE:
6195 	  c_parser_consume_token (parser);
6196 	  stmt = c_finish_bc_stmt (loc, &c_cont_label, false);
6197 	  goto expect_semicolon;
6198 	case RID_BREAK:
6199 	  c_parser_consume_token (parser);
6200 	  stmt = c_finish_bc_stmt (loc, &c_break_label, true);
6201 	  goto expect_semicolon;
6202 	case RID_RETURN:
6203 	  c_parser_consume_token (parser);
6204 	  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6205 	    {
6206 	      stmt = c_finish_return (loc, NULL_TREE, NULL_TREE);
6207 	      c_parser_consume_token (parser);
6208 	    }
6209 	  else
6210 	    {
6211 	      location_t xloc = c_parser_peek_token (parser)->location;
6212 	      struct c_expr expr = c_parser_expression_conv (parser);
6213 	      mark_exp_read (expr.value);
6214 	      stmt = c_finish_return (EXPR_LOC_OR_LOC (expr.value, xloc),
6215 				      expr.value, expr.original_type);
6216 	      goto expect_semicolon;
6217 	    }
6218 	  break;
6219 	case RID_ASM:
6220 	  stmt = c_parser_asm_statement (parser);
6221 	  break;
6222 	case RID_TRANSACTION_ATOMIC:
6223 	case RID_TRANSACTION_RELAXED:
6224 	  stmt = c_parser_transaction (parser,
6225 	      c_parser_peek_token (parser)->keyword);
6226 	  break;
6227 	case RID_TRANSACTION_CANCEL:
6228 	  stmt = c_parser_transaction_cancel (parser);
6229 	  goto expect_semicolon;
6230 	case RID_AT_THROW:
6231 	  gcc_assert (c_dialect_objc ());
6232 	  c_parser_consume_token (parser);
6233 	  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6234 	    {
6235 	      stmt = objc_build_throw_stmt (loc, NULL_TREE);
6236 	      c_parser_consume_token (parser);
6237 	    }
6238 	  else
6239 	    {
6240 	      struct c_expr expr = c_parser_expression (parser);
6241 	      expr = convert_lvalue_to_rvalue (loc, expr, false, false);
6242 	      expr.value = c_fully_fold (expr.value, false, NULL);
6243 	      stmt = objc_build_throw_stmt (loc, expr.value);
6244 	      goto expect_semicolon;
6245 	    }
6246 	  break;
6247 	case RID_AT_TRY:
6248 	  gcc_assert (c_dialect_objc ());
6249 	  c_parser_objc_try_catch_finally_statement (parser);
6250 	  break;
6251 	case RID_AT_SYNCHRONIZED:
6252 	  gcc_assert (c_dialect_objc ());
6253 	  c_parser_objc_synchronized_statement (parser);
6254 	  break;
6255 	case RID_ATTRIBUTE:
6256 	  {
6257 	    /* Allow '__attribute__((fallthrough));'.  */
6258 	    tree attrs = c_parser_gnu_attributes (parser);
6259 	    if (attribute_fallthrough_p (attrs))
6260 	      {
6261 		if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6262 		  {
6263 		    tree fn = build_call_expr_internal_loc (loc,
6264 							    IFN_FALLTHROUGH,
6265 							    void_type_node, 0);
6266 		    add_stmt (fn);
6267 		    /* Eat the ';'.  */
6268 		    c_parser_consume_token (parser);
6269 		  }
6270 		else
6271 		  warning_at (loc, OPT_Wattributes,
6272 			      "%<fallthrough%> attribute not followed "
6273 			      "by %<;%>");
6274 	      }
6275 	    else if (attrs != NULL_TREE)
6276 	      warning_at (loc, OPT_Wattributes, "only attribute %<fallthrough%>"
6277 			  " can be applied to a null statement");
6278 	    break;
6279 	  }
6280 	default:
6281 	  goto expr_stmt;
6282 	}
6283       break;
6284     case CPP_SEMICOLON:
6285       c_parser_consume_token (parser);
6286       break;
6287     case CPP_CLOSE_PAREN:
6288     case CPP_CLOSE_SQUARE:
6289       /* Avoid infinite loop in error recovery:
6290 	 c_parser_skip_until_found stops at a closing nesting
6291 	 delimiter without consuming it, but here we need to consume
6292 	 it to proceed further.  */
6293       c_parser_error (parser, "expected statement");
6294       c_parser_consume_token (parser);
6295       break;
6296     case CPP_PRAGMA:
6297       c_parser_pragma (parser, pragma_stmt, if_p);
6298       break;
6299     default:
6300     expr_stmt:
6301       stmt = c_finish_expr_stmt (loc, c_parser_expression_conv (parser).value);
6302     expect_semicolon:
6303       c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
6304       break;
6305     }
6306   /* Two cases cannot and do not have line numbers associated: If stmt
6307      is degenerate, such as "2;", then stmt is an INTEGER_CST, which
6308      cannot hold line numbers.  But that's OK because the statement
6309      will either be changed to a MODIFY_EXPR during gimplification of
6310      the statement expr, or discarded.  If stmt was compound, but
6311      without new variables, we will have skipped the creation of a
6312      BIND and will have a bare STATEMENT_LIST.  But that's OK because
6313      (recursively) all of the component statements should already have
6314      line numbers assigned.  ??? Can we discard no-op statements
6315      earlier?  */
6316   if (EXPR_LOCATION (stmt) == UNKNOWN_LOCATION)
6317     protected_set_expr_location (stmt, loc);
6318 
6319   parser->in_if_block = in_if_block;
6320 }
6321 
6322 /* Parse the condition from an if, do, while or for statements.  */
6323 
6324 static tree
c_parser_condition(c_parser * parser)6325 c_parser_condition (c_parser *parser)
6326 {
6327   location_t loc = c_parser_peek_token (parser)->location;
6328   tree cond;
6329   cond = c_parser_expression_conv (parser).value;
6330   cond = c_objc_common_truthvalue_conversion (loc, cond);
6331   cond = c_fully_fold (cond, false, NULL);
6332   if (warn_sequence_point)
6333     verify_sequence_points (cond);
6334   return cond;
6335 }
6336 
6337 /* Parse a parenthesized condition from an if, do or while statement.
6338 
6339    condition:
6340      ( expression )
6341 */
6342 static tree
c_parser_paren_condition(c_parser * parser)6343 c_parser_paren_condition (c_parser *parser)
6344 {
6345   tree cond;
6346   matching_parens parens;
6347   if (!parens.require_open (parser))
6348     return error_mark_node;
6349   cond = c_parser_condition (parser);
6350   parens.skip_until_found_close (parser);
6351   return cond;
6352 }
6353 
6354 /* Parse a statement which is a block in C99.
6355 
6356    IF_P is used to track whether there's a (possibly labeled) if statement
6357    which is not enclosed in braces and has an else clause.  This is used to
6358    implement -Wparentheses.  */
6359 
6360 static tree
c_parser_c99_block_statement(c_parser * parser,bool * if_p,location_t * loc_after_labels)6361 c_parser_c99_block_statement (c_parser *parser, bool *if_p,
6362 			      location_t *loc_after_labels)
6363 {
6364   tree block = c_begin_compound_stmt (flag_isoc99);
6365   location_t loc = c_parser_peek_token (parser)->location;
6366   c_parser_statement (parser, if_p, loc_after_labels);
6367   return c_end_compound_stmt (loc, block, flag_isoc99);
6368 }
6369 
6370 /* Parse the body of an if statement.  This is just parsing a
6371    statement but (a) it is a block in C99, (b) we track whether the
6372    body is an if statement for the sake of -Wparentheses warnings, (c)
6373    we handle an empty body specially for the sake of -Wempty-body
6374    warnings, and (d) we call parser_compound_statement directly
6375    because c_parser_statement_after_labels resets
6376    parser->in_if_block.
6377 
6378    IF_P is used to track whether there's a (possibly labeled) if statement
6379    which is not enclosed in braces and has an else clause.  This is used to
6380    implement -Wparentheses.  */
6381 
6382 static tree
c_parser_if_body(c_parser * parser,bool * if_p,const token_indent_info & if_tinfo)6383 c_parser_if_body (c_parser *parser, bool *if_p,
6384 		  const token_indent_info &if_tinfo)
6385 {
6386   tree block = c_begin_compound_stmt (flag_isoc99);
6387   location_t body_loc = c_parser_peek_token (parser)->location;
6388   location_t body_loc_after_labels = UNKNOWN_LOCATION;
6389   token_indent_info body_tinfo
6390     = get_token_indent_info (c_parser_peek_token (parser));
6391 
6392   c_parser_all_labels (parser);
6393   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6394     {
6395       location_t loc = c_parser_peek_token (parser)->location;
6396       add_stmt (build_empty_stmt (loc));
6397       c_parser_consume_token (parser);
6398       if (!c_parser_next_token_is_keyword (parser, RID_ELSE))
6399 	warning_at (loc, OPT_Wempty_body,
6400 		    "suggest braces around empty body in an %<if%> statement");
6401     }
6402   else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6403     add_stmt (c_parser_compound_statement (parser));
6404   else
6405     {
6406       body_loc_after_labels = c_parser_peek_token (parser)->location;
6407       c_parser_statement_after_labels (parser, if_p);
6408     }
6409 
6410   token_indent_info next_tinfo
6411     = get_token_indent_info (c_parser_peek_token (parser));
6412   warn_for_misleading_indentation (if_tinfo, body_tinfo, next_tinfo);
6413   if (body_loc_after_labels != UNKNOWN_LOCATION
6414       && next_tinfo.type != CPP_SEMICOLON)
6415     warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
6416 				    if_tinfo.location, RID_IF);
6417 
6418   return c_end_compound_stmt (body_loc, block, flag_isoc99);
6419 }
6420 
6421 /* Parse the else body of an if statement.  This is just parsing a
6422    statement but (a) it is a block in C99, (b) we handle an empty body
6423    specially for the sake of -Wempty-body warnings.  CHAIN is a vector
6424    of if-else-if conditions.  */
6425 
6426 static tree
c_parser_else_body(c_parser * parser,const token_indent_info & else_tinfo,vec<tree> * chain)6427 c_parser_else_body (c_parser *parser, const token_indent_info &else_tinfo,
6428 		    vec<tree> *chain)
6429 {
6430   location_t body_loc = c_parser_peek_token (parser)->location;
6431   tree block = c_begin_compound_stmt (flag_isoc99);
6432   token_indent_info body_tinfo
6433     = get_token_indent_info (c_parser_peek_token (parser));
6434   location_t body_loc_after_labels = UNKNOWN_LOCATION;
6435 
6436   c_parser_all_labels (parser);
6437   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6438     {
6439       location_t loc = c_parser_peek_token (parser)->location;
6440       warning_at (loc,
6441 		  OPT_Wempty_body,
6442 	         "suggest braces around empty body in an %<else%> statement");
6443       add_stmt (build_empty_stmt (loc));
6444       c_parser_consume_token (parser);
6445     }
6446   else
6447     {
6448       if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6449 	body_loc_after_labels = c_parser_peek_token (parser)->location;
6450       c_parser_statement_after_labels (parser, NULL, chain);
6451     }
6452 
6453   token_indent_info next_tinfo
6454     = get_token_indent_info (c_parser_peek_token (parser));
6455   warn_for_misleading_indentation (else_tinfo, body_tinfo, next_tinfo);
6456   if (body_loc_after_labels != UNKNOWN_LOCATION
6457       && next_tinfo.type != CPP_SEMICOLON)
6458     warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
6459 				    else_tinfo.location, RID_ELSE);
6460 
6461   return c_end_compound_stmt (body_loc, block, flag_isoc99);
6462 }
6463 
6464 /* We might need to reclassify any previously-lexed identifier, e.g.
6465    when we've left a for loop with an if-statement without else in the
6466    body - we might have used a wrong scope for the token.  See PR67784.  */
6467 
6468 static void
c_parser_maybe_reclassify_token(c_parser * parser)6469 c_parser_maybe_reclassify_token (c_parser *parser)
6470 {
6471   if (c_parser_next_token_is (parser, CPP_NAME))
6472     {
6473       c_token *token = c_parser_peek_token (parser);
6474 
6475       if (token->id_kind != C_ID_CLASSNAME)
6476 	{
6477 	  tree decl = lookup_name (token->value);
6478 
6479 	  token->id_kind = C_ID_ID;
6480 	  if (decl)
6481 	    {
6482 	      if (TREE_CODE (decl) == TYPE_DECL)
6483 		token->id_kind = C_ID_TYPENAME;
6484 	    }
6485 	  else if (c_dialect_objc ())
6486 	    {
6487 	      tree objc_interface_decl = objc_is_class_name (token->value);
6488 	      /* Objective-C class names are in the same namespace as
6489 		 variables and typedefs, and hence are shadowed by local
6490 		 declarations.  */
6491 	      if (objc_interface_decl)
6492 		{
6493 		  token->value = objc_interface_decl;
6494 		  token->id_kind = C_ID_CLASSNAME;
6495 		}
6496 	    }
6497 	}
6498     }
6499 }
6500 
6501 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6502 
6503    if-statement:
6504      if ( expression ) statement
6505      if ( expression ) statement else statement
6506 
6507    CHAIN is a vector of if-else-if conditions.
6508    IF_P is used to track whether there's a (possibly labeled) if statement
6509    which is not enclosed in braces and has an else clause.  This is used to
6510    implement -Wparentheses.  */
6511 
6512 static void
c_parser_if_statement(c_parser * parser,bool * if_p,vec<tree> * chain)6513 c_parser_if_statement (c_parser *parser, bool *if_p, vec<tree> *chain)
6514 {
6515   tree block;
6516   location_t loc;
6517   tree cond;
6518   bool nested_if = false;
6519   tree first_body, second_body;
6520   bool in_if_block;
6521 
6522   gcc_assert (c_parser_next_token_is_keyword (parser, RID_IF));
6523   token_indent_info if_tinfo
6524     = get_token_indent_info (c_parser_peek_token (parser));
6525   c_parser_consume_token (parser);
6526   block = c_begin_compound_stmt (flag_isoc99);
6527   loc = c_parser_peek_token (parser)->location;
6528   cond = c_parser_paren_condition (parser);
6529   in_if_block = parser->in_if_block;
6530   parser->in_if_block = true;
6531   first_body = c_parser_if_body (parser, &nested_if, if_tinfo);
6532   parser->in_if_block = in_if_block;
6533 
6534   if (warn_duplicated_cond)
6535     warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond), cond, &chain);
6536 
6537   if (c_parser_next_token_is_keyword (parser, RID_ELSE))
6538     {
6539       token_indent_info else_tinfo
6540 	= get_token_indent_info (c_parser_peek_token (parser));
6541       c_parser_consume_token (parser);
6542       if (warn_duplicated_cond)
6543 	{
6544 	  if (c_parser_next_token_is_keyword (parser, RID_IF)
6545 	      && chain == NULL)
6546 	    {
6547 	      /* We've got "if (COND) else if (COND2)".  Start the
6548 		 condition chain and add COND as the first element.  */
6549 	      chain = new vec<tree> ();
6550 	      if (!CONSTANT_CLASS_P (cond) && !TREE_SIDE_EFFECTS (cond))
6551 		chain->safe_push (cond);
6552 	    }
6553 	  else if (!c_parser_next_token_is_keyword (parser, RID_IF))
6554 	    {
6555 	      /* This is if-else without subsequent if.  Zap the condition
6556 		 chain; we would have already warned at this point.  */
6557 	      delete chain;
6558 	      chain = NULL;
6559 	    }
6560 	}
6561       second_body = c_parser_else_body (parser, else_tinfo, chain);
6562       /* Set IF_P to true to indicate that this if statement has an
6563 	 else clause.  This may trigger the Wparentheses warning
6564 	 below when we get back up to the parent if statement.  */
6565       if (if_p != NULL)
6566 	*if_p = true;
6567     }
6568   else
6569     {
6570       second_body = NULL_TREE;
6571 
6572       /* Diagnose an ambiguous else if if-then-else is nested inside
6573 	 if-then.  */
6574       if (nested_if)
6575 	warning_at (loc, OPT_Wdangling_else,
6576 		    "suggest explicit braces to avoid ambiguous %<else%>");
6577 
6578       if (warn_duplicated_cond)
6579 	{
6580 	  /* This if statement does not have an else clause.  We don't
6581 	     need the condition chain anymore.  */
6582 	  delete chain;
6583 	  chain = NULL;
6584 	}
6585     }
6586   c_finish_if_stmt (loc, cond, first_body, second_body);
6587   add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6588 
6589   c_parser_maybe_reclassify_token (parser);
6590 }
6591 
6592 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6593 
6594    switch-statement:
6595      switch (expression) statement
6596 */
6597 
6598 static void
c_parser_switch_statement(c_parser * parser,bool * if_p)6599 c_parser_switch_statement (c_parser *parser, bool *if_p)
6600 {
6601   struct c_expr ce;
6602   tree block, expr, body, save_break;
6603   location_t switch_loc = c_parser_peek_token (parser)->location;
6604   location_t switch_cond_loc;
6605   gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH));
6606   c_parser_consume_token (parser);
6607   block = c_begin_compound_stmt (flag_isoc99);
6608   bool explicit_cast_p = false;
6609   matching_parens parens;
6610   if (parens.require_open (parser))
6611     {
6612       switch_cond_loc = c_parser_peek_token (parser)->location;
6613       if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
6614 	  && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
6615 	explicit_cast_p = true;
6616       ce = c_parser_expression (parser);
6617       ce = convert_lvalue_to_rvalue (switch_cond_loc, ce, true, true);
6618       expr = ce.value;
6619       /* ??? expr has no valid location?  */
6620       parens.skip_until_found_close (parser);
6621     }
6622   else
6623     {
6624       switch_cond_loc = UNKNOWN_LOCATION;
6625       expr = error_mark_node;
6626       ce.original_type = error_mark_node;
6627     }
6628   c_start_case (switch_loc, switch_cond_loc, expr, explicit_cast_p);
6629   save_break = c_break_label;
6630   c_break_label = NULL_TREE;
6631   location_t loc_after_labels;
6632   bool open_brace_p = c_parser_peek_token (parser)->type == CPP_OPEN_BRACE;
6633   body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6634   location_t next_loc = c_parser_peek_token (parser)->location;
6635   if (!open_brace_p && c_parser_peek_token (parser)->type != CPP_SEMICOLON)
6636     warn_for_multistatement_macros (loc_after_labels, next_loc, switch_loc,
6637 				    RID_SWITCH);
6638   if (c_break_label)
6639     {
6640       location_t here = c_parser_peek_token (parser)->location;
6641       tree t = build1 (LABEL_EXPR, void_type_node, c_break_label);
6642       SET_EXPR_LOCATION (t, here);
6643       SWITCH_BREAK_LABEL_P (c_break_label) = 1;
6644       append_to_statement_list_force (t, &body);
6645     }
6646   c_finish_case (body, ce.original_type);
6647   c_break_label = save_break;
6648   add_stmt (c_end_compound_stmt (switch_loc, block, flag_isoc99));
6649   c_parser_maybe_reclassify_token (parser);
6650 }
6651 
6652 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6653 
6654    while-statement:
6655       while (expression) statement
6656 
6657    IF_P is used to track whether there's a (possibly labeled) if statement
6658    which is not enclosed in braces and has an else clause.  This is used to
6659    implement -Wparentheses.  */
6660 
6661 static void
c_parser_while_statement(c_parser * parser,bool ivdep,unsigned short unroll,bool * if_p)6662 c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6663 			  bool *if_p)
6664 {
6665   tree block, cond, body, save_break, save_cont;
6666   location_t loc;
6667   gcc_assert (c_parser_next_token_is_keyword (parser, RID_WHILE));
6668   token_indent_info while_tinfo
6669     = get_token_indent_info (c_parser_peek_token (parser));
6670   c_parser_consume_token (parser);
6671   block = c_begin_compound_stmt (flag_isoc99);
6672   loc = c_parser_peek_token (parser)->location;
6673   cond = c_parser_paren_condition (parser);
6674   if (ivdep && cond != error_mark_node)
6675     cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6676 		   build_int_cst (integer_type_node,
6677 				  annot_expr_ivdep_kind),
6678 		   integer_zero_node);
6679   if (unroll && cond != error_mark_node)
6680     cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6681 		   build_int_cst (integer_type_node,
6682 				  annot_expr_unroll_kind),
6683 		   build_int_cst (integer_type_node, unroll));
6684   save_break = c_break_label;
6685   c_break_label = NULL_TREE;
6686   save_cont = c_cont_label;
6687   c_cont_label = NULL_TREE;
6688 
6689   token_indent_info body_tinfo
6690     = get_token_indent_info (c_parser_peek_token (parser));
6691 
6692   location_t loc_after_labels;
6693   bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
6694   body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6695   c_finish_loop (loc, loc, cond, UNKNOWN_LOCATION, NULL, body,
6696 		 c_break_label, c_cont_label, true);
6697   add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6698   c_parser_maybe_reclassify_token (parser);
6699 
6700   token_indent_info next_tinfo
6701     = get_token_indent_info (c_parser_peek_token (parser));
6702   warn_for_misleading_indentation (while_tinfo, body_tinfo, next_tinfo);
6703 
6704   if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
6705     warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
6706 				    while_tinfo.location, RID_WHILE);
6707 
6708   c_break_label = save_break;
6709   c_cont_label = save_cont;
6710 }
6711 
6712 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6713 
6714    do-statement:
6715      do statement while ( expression ) ;
6716 */
6717 
6718 static void
c_parser_do_statement(c_parser * parser,bool ivdep,unsigned short unroll)6719 c_parser_do_statement (c_parser *parser, bool ivdep, unsigned short unroll)
6720 {
6721   tree block, cond, body, save_break, save_cont, new_break, new_cont;
6722   location_t loc;
6723   gcc_assert (c_parser_next_token_is_keyword (parser, RID_DO));
6724   c_parser_consume_token (parser);
6725   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6726     warning_at (c_parser_peek_token (parser)->location,
6727 		OPT_Wempty_body,
6728 		"suggest braces around empty body in %<do%> statement");
6729   block = c_begin_compound_stmt (flag_isoc99);
6730   loc = c_parser_peek_token (parser)->location;
6731   save_break = c_break_label;
6732   c_break_label = NULL_TREE;
6733   save_cont = c_cont_label;
6734   c_cont_label = NULL_TREE;
6735   body = c_parser_c99_block_statement (parser, NULL);
6736   c_parser_require_keyword (parser, RID_WHILE, "expected %<while%>");
6737   new_break = c_break_label;
6738   c_break_label = save_break;
6739   new_cont = c_cont_label;
6740   c_cont_label = save_cont;
6741   location_t cond_loc = c_parser_peek_token (parser)->location;
6742   cond = c_parser_paren_condition (parser);
6743   if (ivdep && cond != error_mark_node)
6744     cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6745 		   build_int_cst (integer_type_node,
6746 				  annot_expr_ivdep_kind),
6747 		   integer_zero_node);
6748   if (unroll && cond != error_mark_node)
6749     cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6750 		   build_int_cst (integer_type_node,
6751 				  annot_expr_unroll_kind),
6752  		   build_int_cst (integer_type_node, unroll));
6753   if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
6754     c_parser_skip_to_end_of_block_or_statement (parser);
6755   c_finish_loop (loc, cond_loc, cond, UNKNOWN_LOCATION, NULL, body,
6756 		 new_break, new_cont, false);
6757   add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6758 }
6759 
6760 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6761 
6762    for-statement:
6763      for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
6764      for ( nested-declaration expression[opt] ; expression[opt] ) statement
6765 
6766    The form with a declaration is new in C99.
6767 
6768    ??? In accordance with the old parser, the declaration may be a
6769    nested function, which is then rejected in check_for_loop_decls,
6770    but does it make any sense for this to be included in the grammar?
6771    Note in particular that the nested function does not include a
6772    trailing ';', whereas the "declaration" production includes one.
6773    Also, can we reject bad declarations earlier and cheaper than
6774    check_for_loop_decls?
6775 
6776    In Objective-C, there are two additional variants:
6777 
6778    foreach-statement:
6779      for ( expression in expresssion ) statement
6780      for ( declaration in expression ) statement
6781 
6782    This is inconsistent with C, because the second variant is allowed
6783    even if c99 is not enabled.
6784 
6785    The rest of the comment documents these Objective-C foreach-statement.
6786 
6787    Here is the canonical example of the first variant:
6788     for (object in array)    { do something with object }
6789    we call the first expression ("object") the "object_expression" and
6790    the second expression ("array") the "collection_expression".
6791    object_expression must be an lvalue of type "id" (a generic Objective-C
6792    object) because the loop works by assigning to object_expression the
6793    various objects from the collection_expression.  collection_expression
6794    must evaluate to something of type "id" which responds to the method
6795    countByEnumeratingWithState:objects:count:.
6796 
6797    The canonical example of the second variant is:
6798     for (id object in array)    { do something with object }
6799    which is completely equivalent to
6800     {
6801       id object;
6802       for (object in array) { do something with object }
6803     }
6804    Note that initizializing 'object' in some way (eg, "for ((object =
6805    xxx) in array) { do something with object }") is possibly
6806    technically valid, but completely pointless as 'object' will be
6807    assigned to something else as soon as the loop starts.  We should
6808    most likely reject it (TODO).
6809 
6810    The beginning of the Objective-C foreach-statement looks exactly
6811    like the beginning of the for-statement, and we can tell it is a
6812    foreach-statement only because the initial declaration or
6813    expression is terminated by 'in' instead of ';'.
6814 
6815    IF_P is used to track whether there's a (possibly labeled) if statement
6816    which is not enclosed in braces and has an else clause.  This is used to
6817    implement -Wparentheses.  */
6818 
6819 static void
c_parser_for_statement(c_parser * parser,bool ivdep,unsigned short unroll,bool * if_p)6820 c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6821 			bool *if_p)
6822 {
6823   tree block, cond, incr, save_break, save_cont, body;
6824   /* The following are only used when parsing an ObjC foreach statement.  */
6825   tree object_expression;
6826   /* Silence the bogus uninitialized warning.  */
6827   tree collection_expression = NULL;
6828   location_t loc = c_parser_peek_token (parser)->location;
6829   location_t for_loc = loc;
6830   location_t cond_loc = UNKNOWN_LOCATION;
6831   location_t incr_loc = UNKNOWN_LOCATION;
6832   bool is_foreach_statement = false;
6833   gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
6834   token_indent_info for_tinfo
6835     = get_token_indent_info (c_parser_peek_token (parser));
6836   c_parser_consume_token (parser);
6837   /* Open a compound statement in Objective-C as well, just in case this is
6838      as foreach expression.  */
6839   block = c_begin_compound_stmt (flag_isoc99 || c_dialect_objc ());
6840   cond = error_mark_node;
6841   incr = error_mark_node;
6842   matching_parens parens;
6843   if (parens.require_open (parser))
6844     {
6845       /* Parse the initialization declaration or expression.  */
6846       object_expression = error_mark_node;
6847       parser->objc_could_be_foreach_context = c_dialect_objc ();
6848       if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6849 	{
6850 	  parser->objc_could_be_foreach_context = false;
6851 	  c_parser_consume_token (parser);
6852 	  c_finish_expr_stmt (loc, NULL_TREE);
6853 	}
6854       else if (c_parser_next_tokens_start_declaration (parser)
6855 	       || c_parser_nth_token_starts_std_attributes (parser, 1))
6856 	{
6857 	  c_parser_declaration_or_fndef (parser, true, true, true, true, true,
6858 					 &object_expression, vNULL);
6859 	  parser->objc_could_be_foreach_context = false;
6860 
6861 	  if (c_parser_next_token_is_keyword (parser, RID_IN))
6862 	    {
6863 	      c_parser_consume_token (parser);
6864 	      is_foreach_statement = true;
6865 	      if (check_for_loop_decls (for_loc, true) == NULL_TREE)
6866 		c_parser_error (parser, "multiple iterating variables in "
6867 					"fast enumeration");
6868 	    }
6869 	  else
6870 	    check_for_loop_decls (for_loc, flag_isoc99);
6871 	}
6872       else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
6873 	{
6874 	  /* __extension__ can start a declaration, but is also an
6875 	     unary operator that can start an expression.  Consume all
6876 	     but the last of a possible series of __extension__ to
6877 	     determine which.  */
6878 	  while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
6879 		 && (c_parser_peek_2nd_token (parser)->keyword
6880 		     == RID_EXTENSION))
6881 	    c_parser_consume_token (parser);
6882 	  if (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
6883 	      || c_parser_nth_token_starts_std_attributes (parser, 2))
6884 	    {
6885 	      int ext;
6886 	      ext = disable_extension_diagnostics ();
6887 	      c_parser_consume_token (parser);
6888 	      c_parser_declaration_or_fndef (parser, true, true, true, true,
6889 					     true, &object_expression, vNULL);
6890 	      parser->objc_could_be_foreach_context = false;
6891 
6892 	      restore_extension_diagnostics (ext);
6893 	      if (c_parser_next_token_is_keyword (parser, RID_IN))
6894 		{
6895 		  c_parser_consume_token (parser);
6896 		  is_foreach_statement = true;
6897 		  if (check_for_loop_decls (for_loc, true) == NULL_TREE)
6898 		    c_parser_error (parser, "multiple iterating variables in "
6899 					    "fast enumeration");
6900 		}
6901 	      else
6902 		check_for_loop_decls (for_loc, flag_isoc99);
6903 	    }
6904 	  else
6905 	    goto init_expr;
6906 	}
6907       else
6908 	{
6909 	init_expr:
6910 	  {
6911 	    struct c_expr ce;
6912 	    tree init_expression;
6913 	    ce = c_parser_expression (parser);
6914 	    init_expression = ce.value;
6915 	    parser->objc_could_be_foreach_context = false;
6916 	    if (c_parser_next_token_is_keyword (parser, RID_IN))
6917 	      {
6918 		c_parser_consume_token (parser);
6919 		is_foreach_statement = true;
6920 		if (! lvalue_p (init_expression))
6921 		  c_parser_error (parser, "invalid iterating variable in "
6922 					  "fast enumeration");
6923 		object_expression
6924 		  = c_fully_fold (init_expression, false, NULL);
6925 	      }
6926 	    else
6927 	      {
6928 		ce = convert_lvalue_to_rvalue (loc, ce, true, false);
6929 		init_expression = ce.value;
6930 		c_finish_expr_stmt (loc, init_expression);
6931 		c_parser_skip_until_found (parser, CPP_SEMICOLON,
6932 					   "expected %<;%>");
6933 	      }
6934 	  }
6935 	}
6936       /* Parse the loop condition.  In the case of a foreach
6937 	 statement, there is no loop condition.  */
6938       gcc_assert (!parser->objc_could_be_foreach_context);
6939       if (!is_foreach_statement)
6940 	{
6941 	  cond_loc = c_parser_peek_token (parser)->location;
6942 	  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6943 	    {
6944 	      if (ivdep)
6945 		{
6946 		  c_parser_error (parser, "missing loop condition in loop "
6947 					  "with %<GCC ivdep%> pragma");
6948 		  cond = error_mark_node;
6949 		}
6950 	      else if (unroll)
6951 		{
6952 		  c_parser_error (parser, "missing loop condition in loop "
6953 					  "with %<GCC unroll%> pragma");
6954 		  cond = error_mark_node;
6955 		}
6956 	      else
6957 		{
6958 		  c_parser_consume_token (parser);
6959 		  cond = NULL_TREE;
6960 		}
6961 	    }
6962 	  else
6963 	    {
6964 	      cond = c_parser_condition (parser);
6965 	      c_parser_skip_until_found (parser, CPP_SEMICOLON,
6966 					 "expected %<;%>");
6967 	    }
6968 	  if (ivdep && cond != error_mark_node)
6969 	    cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6970 			   build_int_cst (integer_type_node,
6971 					  annot_expr_ivdep_kind),
6972 			   integer_zero_node);
6973 	  if (unroll && cond != error_mark_node)
6974 	    cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6975  			   build_int_cst (integer_type_node,
6976 					  annot_expr_unroll_kind),
6977 			   build_int_cst (integer_type_node, unroll));
6978 	}
6979       /* Parse the increment expression (the third expression in a
6980 	 for-statement).  In the case of a foreach-statement, this is
6981 	 the expression that follows the 'in'.  */
6982       loc = incr_loc = c_parser_peek_token (parser)->location;
6983       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
6984 	{
6985 	  if (is_foreach_statement)
6986 	    {
6987 	      c_parser_error (parser,
6988 			      "missing collection in fast enumeration");
6989 	      collection_expression = error_mark_node;
6990 	    }
6991 	  else
6992 	    incr = c_process_expr_stmt (loc, NULL_TREE);
6993 	}
6994       else
6995 	{
6996 	  if (is_foreach_statement)
6997 	    collection_expression
6998 	      = c_fully_fold (c_parser_expression (parser).value, false, NULL);
6999 	  else
7000 	    {
7001 	      struct c_expr ce = c_parser_expression (parser);
7002 	      ce = convert_lvalue_to_rvalue (loc, ce, true, false);
7003 	      incr = c_process_expr_stmt (loc, ce.value);
7004 	    }
7005 	}
7006       parens.skip_until_found_close (parser);
7007     }
7008   save_break = c_break_label;
7009   c_break_label = NULL_TREE;
7010   save_cont = c_cont_label;
7011   c_cont_label = NULL_TREE;
7012 
7013   token_indent_info body_tinfo
7014     = get_token_indent_info (c_parser_peek_token (parser));
7015 
7016   location_t loc_after_labels;
7017   bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
7018   body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
7019 
7020   if (is_foreach_statement)
7021     objc_finish_foreach_loop (for_loc, object_expression,
7022 			      collection_expression, body, c_break_label,
7023 			      c_cont_label);
7024   else
7025     c_finish_loop (for_loc, cond_loc, cond, incr_loc, incr, body,
7026 		   c_break_label, c_cont_label, true);
7027   add_stmt (c_end_compound_stmt (for_loc, block,
7028 				 flag_isoc99 || c_dialect_objc ()));
7029   c_parser_maybe_reclassify_token (parser);
7030 
7031   token_indent_info next_tinfo
7032     = get_token_indent_info (c_parser_peek_token (parser));
7033   warn_for_misleading_indentation (for_tinfo, body_tinfo, next_tinfo);
7034 
7035   if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
7036     warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
7037 				    for_tinfo.location, RID_FOR);
7038 
7039   c_break_label = save_break;
7040   c_cont_label = save_cont;
7041 }
7042 
7043 /* Parse an asm statement, a GNU extension.  This is a full-blown asm
7044    statement with inputs, outputs, clobbers, and volatile, inline, and goto
7045    tags allowed.
7046 
7047    asm-qualifier:
7048      volatile
7049      inline
7050      goto
7051 
7052    asm-qualifier-list:
7053      asm-qualifier-list asm-qualifier
7054      asm-qualifier
7055 
7056    asm-statement:
7057      asm asm-qualifier-list[opt] ( asm-argument ) ;
7058 
7059    asm-argument:
7060      asm-string-literal
7061      asm-string-literal : asm-operands[opt]
7062      asm-string-literal : asm-operands[opt] : asm-operands[opt]
7063      asm-string-literal : asm-operands[opt] : asm-operands[opt] \
7064        : asm-clobbers[opt]
7065      asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
7066        : asm-goto-operands
7067 
7068    The form with asm-goto-operands is valid if and only if the
7069    asm-qualifier-list contains goto, and is the only allowed form in that case.
7070    Duplicate asm-qualifiers are not allowed.
7071 
7072    The :: token is considered equivalent to two consecutive : tokens.  */
7073 
7074 static tree
c_parser_asm_statement(c_parser * parser)7075 c_parser_asm_statement (c_parser *parser)
7076 {
7077   tree str, outputs, inputs, clobbers, labels, ret;
7078   bool simple;
7079   location_t asm_loc = c_parser_peek_token (parser)->location;
7080   int section, nsections;
7081 
7082   gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
7083   c_parser_consume_token (parser);
7084 
7085   /* Handle the asm-qualifier-list.  */
7086   location_t volatile_loc = UNKNOWN_LOCATION;
7087   location_t inline_loc = UNKNOWN_LOCATION;
7088   location_t goto_loc = UNKNOWN_LOCATION;
7089   for (;;)
7090     {
7091       c_token *token = c_parser_peek_token (parser);
7092       location_t loc = token->location;
7093       switch (token->keyword)
7094 	{
7095 	case RID_VOLATILE:
7096 	  if (volatile_loc)
7097 	    {
7098 	      error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7099 	      inform (volatile_loc, "first seen here");
7100 	    }
7101 	  else
7102 	    volatile_loc = loc;
7103 	  c_parser_consume_token (parser);
7104 	  continue;
7105 
7106 	case RID_INLINE:
7107 	  if (inline_loc)
7108 	    {
7109 	      error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7110 	      inform (inline_loc, "first seen here");
7111 	    }
7112 	  else
7113 	    inline_loc = loc;
7114 	  c_parser_consume_token (parser);
7115 	  continue;
7116 
7117 	case RID_GOTO:
7118 	  if (goto_loc)
7119 	    {
7120 	      error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7121 	      inform (goto_loc, "first seen here");
7122 	    }
7123 	  else
7124 	    goto_loc = loc;
7125 	  c_parser_consume_token (parser);
7126 	  continue;
7127 
7128 	case RID_CONST:
7129 	case RID_RESTRICT:
7130 	  error_at (loc, "%qE is not a valid %<asm%> qualifier", token->value);
7131 	  c_parser_consume_token (parser);
7132 	  continue;
7133 
7134 	default:
7135 	  break;
7136 	}
7137       break;
7138     }
7139 
7140   bool is_volatile = (volatile_loc != UNKNOWN_LOCATION);
7141   bool is_inline = (inline_loc != UNKNOWN_LOCATION);
7142   bool is_goto = (goto_loc != UNKNOWN_LOCATION);
7143 
7144   ret = NULL;
7145 
7146   matching_parens parens;
7147   if (!parens.require_open (parser))
7148     goto error;
7149 
7150   str = c_parser_asm_string_literal (parser);
7151   if (str == NULL_TREE)
7152     goto error_close_paren;
7153 
7154   simple = true;
7155   outputs = NULL_TREE;
7156   inputs = NULL_TREE;
7157   clobbers = NULL_TREE;
7158   labels = NULL_TREE;
7159 
7160   if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
7161     goto done_asm;
7162 
7163   /* Parse each colon-delimited section of operands.  */
7164   nsections = 3 + is_goto;
7165   for (section = 0; section < nsections; ++section)
7166     {
7167       if (c_parser_next_token_is (parser, CPP_SCOPE))
7168 	{
7169 	  ++section;
7170 	  if (section == nsections)
7171 	    {
7172 	      c_parser_error (parser, "expected %<)%>");
7173 	      goto error_close_paren;
7174 	    }
7175 	  c_parser_consume_token (parser);
7176 	}
7177       else if (!c_parser_require (parser, CPP_COLON,
7178 				  is_goto
7179 				  ? G_("expected %<:%>")
7180 				  : G_("expected %<:%> or %<)%>"),
7181 				  UNKNOWN_LOCATION, is_goto))
7182 	goto error_close_paren;
7183 
7184       /* Once past any colon, we're no longer a simple asm.  */
7185       simple = false;
7186 
7187       if ((!c_parser_next_token_is (parser, CPP_COLON)
7188 	   && !c_parser_next_token_is (parser, CPP_SCOPE)
7189 	   && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
7190 	  || section == 3)
7191 	switch (section)
7192 	  {
7193 	  case 0:
7194 	    /* For asm goto, we don't allow output operands, but reserve
7195 	       the slot for a future extension that does allow them.  */
7196 	    if (!is_goto)
7197 	      outputs = c_parser_asm_operands (parser);
7198 	    break;
7199 	  case 1:
7200 	    inputs = c_parser_asm_operands (parser);
7201 	    break;
7202 	  case 2:
7203 	    clobbers = c_parser_asm_clobbers (parser);
7204 	    break;
7205 	  case 3:
7206 	    labels = c_parser_asm_goto_operands (parser);
7207 	    break;
7208 	  default:
7209 	    gcc_unreachable ();
7210 	  }
7211 
7212       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
7213 	goto done_asm;
7214     }
7215 
7216  done_asm:
7217   if (!parens.require_close (parser))
7218     {
7219       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7220       goto error;
7221     }
7222 
7223   if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
7224     c_parser_skip_to_end_of_block_or_statement (parser);
7225 
7226   ret = build_asm_stmt (is_volatile,
7227 			build_asm_expr (asm_loc, str, outputs, inputs,
7228 					clobbers, labels, simple, is_inline));
7229 
7230  error:
7231   return ret;
7232 
7233  error_close_paren:
7234   c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7235   goto error;
7236 }
7237 
7238 /* Parse asm operands, a GNU extension.
7239 
7240    asm-operands:
7241      asm-operand
7242      asm-operands , asm-operand
7243 
7244    asm-operand:
7245      asm-string-literal ( expression )
7246      [ identifier ] asm-string-literal ( expression )
7247 */
7248 
7249 static tree
c_parser_asm_operands(c_parser * parser)7250 c_parser_asm_operands (c_parser *parser)
7251 {
7252   tree list = NULL_TREE;
7253   while (true)
7254     {
7255       tree name, str;
7256       struct c_expr expr;
7257       if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
7258 	{
7259 	  c_parser_consume_token (parser);
7260 	  if (c_parser_next_token_is (parser, CPP_NAME))
7261 	    {
7262 	      tree id = c_parser_peek_token (parser)->value;
7263 	      c_parser_consume_token (parser);
7264 	      name = build_string (IDENTIFIER_LENGTH (id),
7265 				   IDENTIFIER_POINTER (id));
7266 	    }
7267 	  else
7268 	    {
7269 	      c_parser_error (parser, "expected identifier");
7270 	      c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
7271 	      return NULL_TREE;
7272 	    }
7273 	  c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
7274 				     "expected %<]%>");
7275 	}
7276       else
7277 	name = NULL_TREE;
7278       str = c_parser_asm_string_literal (parser);
7279       if (str == NULL_TREE)
7280 	return NULL_TREE;
7281       matching_parens parens;
7282       if (!parens.require_open (parser))
7283 	return NULL_TREE;
7284       expr = c_parser_expression (parser);
7285       mark_exp_read (expr.value);
7286       if (!parens.require_close (parser))
7287 	{
7288 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7289 	  return NULL_TREE;
7290 	}
7291       list = chainon (list, build_tree_list (build_tree_list (name, str),
7292 					     expr.value));
7293       if (c_parser_next_token_is (parser, CPP_COMMA))
7294 	c_parser_consume_token (parser);
7295       else
7296 	break;
7297     }
7298   return list;
7299 }
7300 
7301 /* Parse asm clobbers, a GNU extension.
7302 
7303    asm-clobbers:
7304      asm-string-literal
7305      asm-clobbers , asm-string-literal
7306 */
7307 
7308 static tree
c_parser_asm_clobbers(c_parser * parser)7309 c_parser_asm_clobbers (c_parser *parser)
7310 {
7311   tree list = NULL_TREE;
7312   while (true)
7313     {
7314       tree str = c_parser_asm_string_literal (parser);
7315       if (str)
7316 	list = tree_cons (NULL_TREE, str, list);
7317       else
7318 	return NULL_TREE;
7319       if (c_parser_next_token_is (parser, CPP_COMMA))
7320 	c_parser_consume_token (parser);
7321       else
7322 	break;
7323     }
7324   return list;
7325 }
7326 
7327 /* Parse asm goto labels, a GNU extension.
7328 
7329    asm-goto-operands:
7330      identifier
7331      asm-goto-operands , identifier
7332 */
7333 
7334 static tree
c_parser_asm_goto_operands(c_parser * parser)7335 c_parser_asm_goto_operands (c_parser *parser)
7336 {
7337   tree list = NULL_TREE;
7338   while (true)
7339     {
7340       tree name, label;
7341 
7342       if (c_parser_next_token_is (parser, CPP_NAME))
7343 	{
7344 	  c_token *tok = c_parser_peek_token (parser);
7345 	  name = tok->value;
7346 	  label = lookup_label_for_goto (tok->location, name);
7347 	  c_parser_consume_token (parser);
7348 	  TREE_USED (label) = 1;
7349 	}
7350       else
7351 	{
7352 	  c_parser_error (parser, "expected identifier");
7353 	  return NULL_TREE;
7354 	}
7355 
7356       name = build_string (IDENTIFIER_LENGTH (name),
7357 			   IDENTIFIER_POINTER (name));
7358       list = tree_cons (name, label, list);
7359       if (c_parser_next_token_is (parser, CPP_COMMA))
7360 	c_parser_consume_token (parser);
7361       else
7362 	return nreverse (list);
7363     }
7364 }
7365 
7366 /* Parse a possibly concatenated sequence of string literals.
7367    TRANSLATE says whether to translate them to the execution character
7368    set; WIDE_OK says whether any kind of prefixed string literal is
7369    permitted in this context.  This code is based on that in
7370    lex_string.  */
7371 
7372 struct c_expr
c_parser_string_literal(c_parser * parser,bool translate,bool wide_ok)7373 c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok)
7374 {
7375   struct c_expr ret;
7376   size_t count;
7377   struct obstack str_ob;
7378   struct obstack loc_ob;
7379   cpp_string str, istr, *strs;
7380   c_token *tok;
7381   location_t loc, last_tok_loc;
7382   enum cpp_ttype type;
7383   tree value, string_tree;
7384 
7385   tok = c_parser_peek_token (parser);
7386   loc = tok->location;
7387   last_tok_loc = linemap_resolve_location (line_table, loc,
7388 					   LRK_MACRO_DEFINITION_LOCATION,
7389 					   NULL);
7390   type = tok->type;
7391   switch (type)
7392     {
7393     case CPP_STRING:
7394     case CPP_WSTRING:
7395     case CPP_STRING16:
7396     case CPP_STRING32:
7397     case CPP_UTF8STRING:
7398       string_tree = tok->value;
7399       break;
7400 
7401     default:
7402       c_parser_error (parser, "expected string literal");
7403       ret.set_error ();
7404       ret.value = NULL_TREE;
7405       ret.original_code = ERROR_MARK;
7406       ret.original_type = NULL_TREE;
7407       return ret;
7408     }
7409 
7410   /* Try to avoid the overhead of creating and destroying an obstack
7411      for the common case of just one string.  */
7412   switch (c_parser_peek_2nd_token (parser)->type)
7413     {
7414     default:
7415       c_parser_consume_token (parser);
7416       str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
7417       str.len = TREE_STRING_LENGTH (string_tree);
7418       count = 1;
7419       strs = &str;
7420       break;
7421 
7422     case CPP_STRING:
7423     case CPP_WSTRING:
7424     case CPP_STRING16:
7425     case CPP_STRING32:
7426     case CPP_UTF8STRING:
7427       gcc_obstack_init (&str_ob);
7428       gcc_obstack_init (&loc_ob);
7429       count = 0;
7430       do
7431 	{
7432 	  c_parser_consume_token (parser);
7433 	  count++;
7434 	  str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
7435 	  str.len = TREE_STRING_LENGTH (string_tree);
7436 	  if (type != tok->type)
7437 	    {
7438 	      if (type == CPP_STRING)
7439 		type = tok->type;
7440 	      else if (tok->type != CPP_STRING)
7441 		error ("unsupported non-standard concatenation "
7442 		       "of string literals");
7443 	    }
7444 	  obstack_grow (&str_ob, &str, sizeof (cpp_string));
7445 	  obstack_grow (&loc_ob, &last_tok_loc, sizeof (location_t));
7446 	  tok = c_parser_peek_token (parser);
7447 	  string_tree = tok->value;
7448 	  last_tok_loc
7449 	    = linemap_resolve_location (line_table, tok->location,
7450 					LRK_MACRO_DEFINITION_LOCATION, NULL);
7451 	}
7452       while (tok->type == CPP_STRING
7453 	     || tok->type == CPP_WSTRING
7454 	     || tok->type == CPP_STRING16
7455 	     || tok->type == CPP_STRING32
7456 	     || tok->type == CPP_UTF8STRING);
7457       strs = (cpp_string *) obstack_finish (&str_ob);
7458     }
7459 
7460   if (count > 1 && !in_system_header_at (input_location))
7461     warning (OPT_Wtraditional,
7462 	     "traditional C rejects string constant concatenation");
7463 
7464   if ((type == CPP_STRING || wide_ok)
7465       && ((translate
7466 	  ? cpp_interpret_string : cpp_interpret_string_notranslate)
7467 	  (parse_in, strs, count, &istr, type)))
7468     {
7469       value = build_string (istr.len, (const char *) istr.text);
7470       free (CONST_CAST (unsigned char *, istr.text));
7471       if (count > 1)
7472 	{
7473 	  location_t *locs = (location_t *) obstack_finish (&loc_ob);
7474 	  gcc_assert (g_string_concat_db);
7475 	  g_string_concat_db->record_string_concatenation (count, locs);
7476 	}
7477     }
7478   else
7479     {
7480       if (type != CPP_STRING && !wide_ok)
7481 	{
7482 	  error_at (loc, "a wide string is invalid in this context");
7483 	  type = CPP_STRING;
7484 	}
7485       /* Callers cannot generally handle error_mark_node in this
7486 	 context, so return the empty string instead.  An error has
7487 	 been issued, either above or from cpp_interpret_string.  */
7488       switch (type)
7489 	{
7490 	default:
7491 	case CPP_STRING:
7492 	case CPP_UTF8STRING:
7493 	  value = build_string (1, "");
7494 	  break;
7495 	case CPP_STRING16:
7496 	  value = build_string (TYPE_PRECISION (char16_type_node)
7497 				/ TYPE_PRECISION (char_type_node),
7498 				"\0");  /* char16_t is 16 bits */
7499 	  break;
7500 	case CPP_STRING32:
7501 	  value = build_string (TYPE_PRECISION (char32_type_node)
7502 				/ TYPE_PRECISION (char_type_node),
7503 				"\0\0\0");  /* char32_t is 32 bits */
7504 	  break;
7505 	case CPP_WSTRING:
7506 	  value = build_string (TYPE_PRECISION (wchar_type_node)
7507 				/ TYPE_PRECISION (char_type_node),
7508 				"\0\0\0");  /* widest supported wchar_t
7509 					       is 32 bits */
7510 	  break;
7511         }
7512     }
7513 
7514   switch (type)
7515     {
7516     default:
7517     case CPP_STRING:
7518     case CPP_UTF8STRING:
7519       TREE_TYPE (value) = char_array_type_node;
7520       break;
7521     case CPP_STRING16:
7522       TREE_TYPE (value) = char16_array_type_node;
7523       break;
7524     case CPP_STRING32:
7525       TREE_TYPE (value) = char32_array_type_node;
7526       break;
7527     case CPP_WSTRING:
7528       TREE_TYPE (value) = wchar_array_type_node;
7529     }
7530   value = fix_string_type (value);
7531 
7532   if (count > 1)
7533     {
7534       obstack_free (&str_ob, 0);
7535       obstack_free (&loc_ob, 0);
7536     }
7537 
7538   ret.value = value;
7539   ret.original_code = STRING_CST;
7540   ret.original_type = NULL_TREE;
7541   set_c_expr_source_range (&ret, get_range_from_loc (line_table, loc));
7542   return ret;
7543 }
7544 
7545 /* Parse an expression other than a compound expression; that is, an
7546    assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16).  If
7547    AFTER is not NULL then it is an Objective-C message expression which
7548    is the primary-expression starting the expression as an initializer.
7549 
7550    assignment-expression:
7551      conditional-expression
7552      unary-expression assignment-operator assignment-expression
7553 
7554    assignment-operator: one of
7555      = *= /= %= += -= <<= >>= &= ^= |=
7556 
7557    In GNU C we accept any conditional expression on the LHS and
7558    diagnose the invalid lvalue rather than producing a syntax
7559    error.  */
7560 
7561 static struct c_expr
c_parser_expr_no_commas(c_parser * parser,struct c_expr * after,tree omp_atomic_lhs)7562 c_parser_expr_no_commas (c_parser *parser, struct c_expr *after,
7563 			 tree omp_atomic_lhs)
7564 {
7565   struct c_expr lhs, rhs, ret;
7566   enum tree_code code;
7567   location_t op_location, exp_location;
7568   gcc_assert (!after || c_dialect_objc ());
7569   lhs = c_parser_conditional_expression (parser, after, omp_atomic_lhs);
7570   op_location = c_parser_peek_token (parser)->location;
7571   switch (c_parser_peek_token (parser)->type)
7572     {
7573     case CPP_EQ:
7574       code = NOP_EXPR;
7575       break;
7576     case CPP_MULT_EQ:
7577       code = MULT_EXPR;
7578       break;
7579     case CPP_DIV_EQ:
7580       code = TRUNC_DIV_EXPR;
7581       break;
7582     case CPP_MOD_EQ:
7583       code = TRUNC_MOD_EXPR;
7584       break;
7585     case CPP_PLUS_EQ:
7586       code = PLUS_EXPR;
7587       break;
7588     case CPP_MINUS_EQ:
7589       code = MINUS_EXPR;
7590       break;
7591     case CPP_LSHIFT_EQ:
7592       code = LSHIFT_EXPR;
7593       break;
7594     case CPP_RSHIFT_EQ:
7595       code = RSHIFT_EXPR;
7596       break;
7597     case CPP_AND_EQ:
7598       code = BIT_AND_EXPR;
7599       break;
7600     case CPP_XOR_EQ:
7601       code = BIT_XOR_EXPR;
7602       break;
7603     case CPP_OR_EQ:
7604       code = BIT_IOR_EXPR;
7605       break;
7606     default:
7607       return lhs;
7608     }
7609   c_parser_consume_token (parser);
7610   exp_location = c_parser_peek_token (parser)->location;
7611   rhs = c_parser_expr_no_commas (parser, NULL);
7612   rhs = convert_lvalue_to_rvalue (exp_location, rhs, true, true);
7613 
7614   ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
7615 				 code, exp_location, rhs.value,
7616 				 rhs.original_type);
7617   set_c_expr_source_range (&ret, lhs.get_start (), rhs.get_finish ());
7618   if (code == NOP_EXPR)
7619     ret.original_code = MODIFY_EXPR;
7620   else
7621     {
7622       TREE_NO_WARNING (ret.value) = 1;
7623       ret.original_code = ERROR_MARK;
7624     }
7625   ret.original_type = NULL;
7626   return ret;
7627 }
7628 
7629 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15).  If
7630    AFTER is not NULL then it is an Objective-C message expression which is
7631    the primary-expression starting the expression as an initializer.
7632 
7633    conditional-expression:
7634      logical-OR-expression
7635      logical-OR-expression ? expression : conditional-expression
7636 
7637    GNU extensions:
7638 
7639    conditional-expression:
7640      logical-OR-expression ? : conditional-expression
7641 */
7642 
7643 static struct c_expr
c_parser_conditional_expression(c_parser * parser,struct c_expr * after,tree omp_atomic_lhs)7644 c_parser_conditional_expression (c_parser *parser, struct c_expr *after,
7645 				 tree omp_atomic_lhs)
7646 {
7647   struct c_expr cond, exp1, exp2, ret;
7648   location_t start, cond_loc, colon_loc;
7649 
7650   gcc_assert (!after || c_dialect_objc ());
7651 
7652   cond = c_parser_binary_expression (parser, after, omp_atomic_lhs);
7653 
7654   if (c_parser_next_token_is_not (parser, CPP_QUERY))
7655     return cond;
7656   if (cond.value != error_mark_node)
7657     start = cond.get_start ();
7658   else
7659     start = UNKNOWN_LOCATION;
7660   cond_loc = c_parser_peek_token (parser)->location;
7661   cond = convert_lvalue_to_rvalue (cond_loc, cond, true, true);
7662   c_parser_consume_token (parser);
7663   if (c_parser_next_token_is (parser, CPP_COLON))
7664     {
7665       tree eptype = NULL_TREE;
7666 
7667       location_t middle_loc = c_parser_peek_token (parser)->location;
7668       pedwarn (middle_loc, OPT_Wpedantic,
7669 	       "ISO C forbids omitting the middle term of a %<?:%> expression");
7670       if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR)
7671 	{
7672 	  eptype = TREE_TYPE (cond.value);
7673 	  cond.value = TREE_OPERAND (cond.value, 0);
7674 	}
7675       tree e = cond.value;
7676       while (TREE_CODE (e) == COMPOUND_EXPR)
7677 	e = TREE_OPERAND (e, 1);
7678       warn_for_omitted_condop (middle_loc, e);
7679       /* Make sure first operand is calculated only once.  */
7680       exp1.value = save_expr (default_conversion (cond.value));
7681       if (eptype)
7682 	exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value);
7683       exp1.original_type = NULL;
7684       exp1.src_range = cond.src_range;
7685       cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value);
7686       c_inhibit_evaluation_warnings += cond.value == truthvalue_true_node;
7687     }
7688   else
7689     {
7690       cond.value
7691 	= c_objc_common_truthvalue_conversion
7692 	(cond_loc, default_conversion (cond.value));
7693       c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node;
7694       exp1 = c_parser_expression_conv (parser);
7695       mark_exp_read (exp1.value);
7696       c_inhibit_evaluation_warnings +=
7697 	((cond.value == truthvalue_true_node)
7698 	 - (cond.value == truthvalue_false_node));
7699     }
7700 
7701   colon_loc = c_parser_peek_token (parser)->location;
7702   if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
7703     {
7704       c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
7705       ret.set_error ();
7706       ret.original_code = ERROR_MARK;
7707       ret.original_type = NULL;
7708       return ret;
7709     }
7710   {
7711     location_t exp2_loc = c_parser_peek_token (parser)->location;
7712     exp2 = c_parser_conditional_expression (parser, NULL, NULL_TREE);
7713     exp2 = convert_lvalue_to_rvalue (exp2_loc, exp2, true, true);
7714   }
7715   c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
7716   location_t loc1 = make_location (exp1.get_start (), exp1.src_range);
7717   location_t loc2 = make_location (exp2.get_start (), exp2.src_range);
7718   ret.value = build_conditional_expr (colon_loc, cond.value,
7719 				      cond.original_code == C_MAYBE_CONST_EXPR,
7720 				      exp1.value, exp1.original_type, loc1,
7721 				      exp2.value, exp2.original_type, loc2);
7722   ret.original_code = ERROR_MARK;
7723   if (exp1.value == error_mark_node || exp2.value == error_mark_node)
7724     ret.original_type = NULL;
7725   else
7726     {
7727       tree t1, t2;
7728 
7729       /* If both sides are enum type, the default conversion will have
7730 	 made the type of the result be an integer type.  We want to
7731 	 remember the enum types we started with.  */
7732       t1 = exp1.original_type ? exp1.original_type : TREE_TYPE (exp1.value);
7733       t2 = exp2.original_type ? exp2.original_type : TREE_TYPE (exp2.value);
7734       ret.original_type = ((t1 != error_mark_node
7735 			    && t2 != error_mark_node
7736 			    && (TYPE_MAIN_VARIANT (t1)
7737 				== TYPE_MAIN_VARIANT (t2)))
7738 			   ? t1
7739 			   : NULL);
7740     }
7741   set_c_expr_source_range (&ret, start, exp2.get_finish ());
7742   return ret;
7743 }
7744 
7745 /* Parse a binary expression; that is, a logical-OR-expression (C90
7746    6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14).  If AFTER is not
7747    NULL then it is an Objective-C message expression which is the
7748    primary-expression starting the expression as an initializer.
7749 
7750    OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
7751    when it should be the unfolded lhs.  In a valid OpenMP source,
7752    one of the operands of the toplevel binary expression must be equal
7753    to it.  In that case, just return a build2 created binary operation
7754    rather than result of parser_build_binary_op.
7755 
7756    multiplicative-expression:
7757      cast-expression
7758      multiplicative-expression * cast-expression
7759      multiplicative-expression / cast-expression
7760      multiplicative-expression % cast-expression
7761 
7762    additive-expression:
7763      multiplicative-expression
7764      additive-expression + multiplicative-expression
7765      additive-expression - multiplicative-expression
7766 
7767    shift-expression:
7768      additive-expression
7769      shift-expression << additive-expression
7770      shift-expression >> additive-expression
7771 
7772    relational-expression:
7773      shift-expression
7774      relational-expression < shift-expression
7775      relational-expression > shift-expression
7776      relational-expression <= shift-expression
7777      relational-expression >= shift-expression
7778 
7779    equality-expression:
7780      relational-expression
7781      equality-expression == relational-expression
7782      equality-expression != relational-expression
7783 
7784    AND-expression:
7785      equality-expression
7786      AND-expression & equality-expression
7787 
7788    exclusive-OR-expression:
7789      AND-expression
7790      exclusive-OR-expression ^ AND-expression
7791 
7792    inclusive-OR-expression:
7793      exclusive-OR-expression
7794      inclusive-OR-expression | exclusive-OR-expression
7795 
7796    logical-AND-expression:
7797      inclusive-OR-expression
7798      logical-AND-expression && inclusive-OR-expression
7799 
7800    logical-OR-expression:
7801      logical-AND-expression
7802      logical-OR-expression || logical-AND-expression
7803 */
7804 
7805 static struct c_expr
c_parser_binary_expression(c_parser * parser,struct c_expr * after,tree omp_atomic_lhs)7806 c_parser_binary_expression (c_parser *parser, struct c_expr *after,
7807 			    tree omp_atomic_lhs)
7808 {
7809   /* A binary expression is parsed using operator-precedence parsing,
7810      with the operands being cast expressions.  All the binary
7811      operators are left-associative.  Thus a binary expression is of
7812      form:
7813 
7814      E0 op1 E1 op2 E2 ...
7815 
7816      which we represent on a stack.  On the stack, the precedence
7817      levels are strictly increasing.  When a new operator is
7818      encountered of higher precedence than that at the top of the
7819      stack, it is pushed; its LHS is the top expression, and its RHS
7820      is everything parsed until it is popped.  When a new operator is
7821      encountered with precedence less than or equal to that at the top
7822      of the stack, triples E[i-1] op[i] E[i] are popped and replaced
7823      by the result of the operation until the operator at the top of
7824      the stack has lower precedence than the new operator or there is
7825      only one element on the stack; then the top expression is the LHS
7826      of the new operator.  In the case of logical AND and OR
7827      expressions, we also need to adjust c_inhibit_evaluation_warnings
7828      as appropriate when the operators are pushed and popped.  */
7829 
7830   struct {
7831     /* The expression at this stack level.  */
7832     struct c_expr expr;
7833     /* The precedence of the operator on its left, PREC_NONE at the
7834        bottom of the stack.  */
7835     enum c_parser_prec prec;
7836     /* The operation on its left.  */
7837     enum tree_code op;
7838     /* The source location of this operation.  */
7839     location_t loc;
7840     /* The sizeof argument if expr.original_code == SIZEOF_EXPR.  */
7841     tree sizeof_arg;
7842   } stack[NUM_PRECS];
7843   int sp;
7844   /* Location of the binary operator.  */
7845   location_t binary_loc = UNKNOWN_LOCATION;  /* Quiet warning.  */
7846 #define POP								      \
7847   do {									      \
7848     switch (stack[sp].op)						      \
7849       {									      \
7850       case TRUTH_ANDIF_EXPR:						      \
7851 	c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value	      \
7852 					  == truthvalue_false_node);	      \
7853 	break;								      \
7854       case TRUTH_ORIF_EXPR:						      \
7855 	c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value	      \
7856 					  == truthvalue_true_node);	      \
7857 	break;								      \
7858       case TRUNC_DIV_EXPR: 						      \
7859 	if (stack[sp - 1].expr.original_code == SIZEOF_EXPR		      \
7860 	    && stack[sp].expr.original_code == SIZEOF_EXPR)		      \
7861 	  {								      \
7862 	    tree type0 = stack[sp - 1].sizeof_arg;			      \
7863 	    tree type1 = stack[sp].sizeof_arg;				      \
7864 	    tree first_arg = type0;					      \
7865 	    if (!TYPE_P (type0))					      \
7866 	      type0 = TREE_TYPE (type0);				      \
7867 	    if (!TYPE_P (type1))					      \
7868 	      type1 = TREE_TYPE (type1);				      \
7869 	    if (POINTER_TYPE_P (type0)					      \
7870 		&& comptypes (TREE_TYPE (type0), type1)			      \
7871 		&& !(TREE_CODE (first_arg) == PARM_DECL			      \
7872 		     && C_ARRAY_PARAMETER (first_arg)			      \
7873 		     && warn_sizeof_array_argument))			      \
7874 	      {								\
7875 		auto_diagnostic_group d;					\
7876 		if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
7877 				  "division %<sizeof (%T) / sizeof (%T)%> " \
7878 				  "does not compute the number of array " \
7879 				  "elements",				\
7880 				  type0, type1))			\
7881 		  if (DECL_P (first_arg))				\
7882 		    inform (DECL_SOURCE_LOCATION (first_arg),		\
7883 			      "first %<sizeof%> operand was declared here"); \
7884 	      }								\
7885 	  }								\
7886 	break;								      \
7887       default:								      \
7888 	break;								      \
7889       }									      \
7890     stack[sp - 1].expr							      \
7891       = convert_lvalue_to_rvalue (stack[sp - 1].loc,			      \
7892 				  stack[sp - 1].expr, true, true);	      \
7893     stack[sp].expr							      \
7894       = convert_lvalue_to_rvalue (stack[sp].loc,			      \
7895 				  stack[sp].expr, true, true);		      \
7896     if (__builtin_expect (omp_atomic_lhs != NULL_TREE, 0) && sp == 1	      \
7897 	&& c_parser_peek_token (parser)->type == CPP_SEMICOLON		      \
7898 	&& ((1 << stack[sp].prec)					      \
7899 	    & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) | (1 << PREC_BITAND)    \
7900 	       | (1 << PREC_SHIFT) | (1 << PREC_ADD) | (1 << PREC_MULT)))     \
7901 	&& stack[sp].op != TRUNC_MOD_EXPR				      \
7902 	&& stack[0].expr.value != error_mark_node			      \
7903 	&& stack[1].expr.value != error_mark_node			      \
7904 	&& (c_tree_equal (stack[0].expr.value, omp_atomic_lhs)		      \
7905 	    || c_tree_equal (stack[1].expr.value, omp_atomic_lhs)))	      \
7906       {									      \
7907 	tree t = make_node (stack[1].op);				      \
7908 	TREE_TYPE (t) = TREE_TYPE (stack[0].expr.value);		      \
7909 	TREE_OPERAND (t, 0) = stack[0].expr.value;			      \
7910 	TREE_OPERAND (t, 1) = stack[1].expr.value;			      \
7911 	stack[0].expr.value = t;					      \
7912       }									      \
7913     else								      \
7914       stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc,	      \
7915 						   stack[sp].op,	      \
7916 						   stack[sp - 1].expr,	      \
7917 						   stack[sp].expr);	      \
7918     sp--;								      \
7919   } while (0)
7920   gcc_assert (!after || c_dialect_objc ());
7921   stack[0].loc = c_parser_peek_token (parser)->location;
7922   stack[0].expr = c_parser_cast_expression (parser, after);
7923   stack[0].prec = PREC_NONE;
7924   stack[0].sizeof_arg = c_last_sizeof_arg;
7925   sp = 0;
7926   while (true)
7927     {
7928       enum c_parser_prec oprec;
7929       enum tree_code ocode;
7930       source_range src_range;
7931       if (parser->error)
7932 	goto out;
7933       switch (c_parser_peek_token (parser)->type)
7934 	{
7935 	case CPP_MULT:
7936 	  oprec = PREC_MULT;
7937 	  ocode = MULT_EXPR;
7938 	  break;
7939 	case CPP_DIV:
7940 	  oprec = PREC_MULT;
7941 	  ocode = TRUNC_DIV_EXPR;
7942 	  break;
7943 	case CPP_MOD:
7944 	  oprec = PREC_MULT;
7945 	  ocode = TRUNC_MOD_EXPR;
7946 	  break;
7947 	case CPP_PLUS:
7948 	  oprec = PREC_ADD;
7949 	  ocode = PLUS_EXPR;
7950 	  break;
7951 	case CPP_MINUS:
7952 	  oprec = PREC_ADD;
7953 	  ocode = MINUS_EXPR;
7954 	  break;
7955 	case CPP_LSHIFT:
7956 	  oprec = PREC_SHIFT;
7957 	  ocode = LSHIFT_EXPR;
7958 	  break;
7959 	case CPP_RSHIFT:
7960 	  oprec = PREC_SHIFT;
7961 	  ocode = RSHIFT_EXPR;
7962 	  break;
7963 	case CPP_LESS:
7964 	  oprec = PREC_REL;
7965 	  ocode = LT_EXPR;
7966 	  break;
7967 	case CPP_GREATER:
7968 	  oprec = PREC_REL;
7969 	  ocode = GT_EXPR;
7970 	  break;
7971 	case CPP_LESS_EQ:
7972 	  oprec = PREC_REL;
7973 	  ocode = LE_EXPR;
7974 	  break;
7975 	case CPP_GREATER_EQ:
7976 	  oprec = PREC_REL;
7977 	  ocode = GE_EXPR;
7978 	  break;
7979 	case CPP_EQ_EQ:
7980 	  oprec = PREC_EQ;
7981 	  ocode = EQ_EXPR;
7982 	  break;
7983 	case CPP_NOT_EQ:
7984 	  oprec = PREC_EQ;
7985 	  ocode = NE_EXPR;
7986 	  break;
7987 	case CPP_AND:
7988 	  oprec = PREC_BITAND;
7989 	  ocode = BIT_AND_EXPR;
7990 	  break;
7991 	case CPP_XOR:
7992 	  oprec = PREC_BITXOR;
7993 	  ocode = BIT_XOR_EXPR;
7994 	  break;
7995 	case CPP_OR:
7996 	  oprec = PREC_BITOR;
7997 	  ocode = BIT_IOR_EXPR;
7998 	  break;
7999 	case CPP_AND_AND:
8000 	  oprec = PREC_LOGAND;
8001 	  ocode = TRUTH_ANDIF_EXPR;
8002 	  break;
8003 	case CPP_OR_OR:
8004 	  oprec = PREC_LOGOR;
8005 	  ocode = TRUTH_ORIF_EXPR;
8006 	  break;
8007 	default:
8008 	  /* Not a binary operator, so end of the binary
8009 	     expression.  */
8010 	  goto out;
8011 	}
8012       binary_loc = c_parser_peek_token (parser)->location;
8013       while (oprec <= stack[sp].prec)
8014 	POP;
8015       c_parser_consume_token (parser);
8016       switch (ocode)
8017 	{
8018 	case TRUTH_ANDIF_EXPR:
8019 	  src_range = stack[sp].expr.src_range;
8020 	  stack[sp].expr
8021 	    = convert_lvalue_to_rvalue (stack[sp].loc,
8022 					stack[sp].expr, true, true);
8023 	  stack[sp].expr.value = c_objc_common_truthvalue_conversion
8024 	    (stack[sp].loc, default_conversion (stack[sp].expr.value));
8025 	  c_inhibit_evaluation_warnings += (stack[sp].expr.value
8026 					    == truthvalue_false_node);
8027 	  set_c_expr_source_range (&stack[sp].expr, src_range);
8028 	  break;
8029 	case TRUTH_ORIF_EXPR:
8030 	  src_range = stack[sp].expr.src_range;
8031 	  stack[sp].expr
8032 	    = convert_lvalue_to_rvalue (stack[sp].loc,
8033 					stack[sp].expr, true, true);
8034 	  stack[sp].expr.value = c_objc_common_truthvalue_conversion
8035 	    (stack[sp].loc, default_conversion (stack[sp].expr.value));
8036 	  c_inhibit_evaluation_warnings += (stack[sp].expr.value
8037 					    == truthvalue_true_node);
8038 	  set_c_expr_source_range (&stack[sp].expr, src_range);
8039 	  break;
8040 	default:
8041 	  break;
8042 	}
8043       sp++;
8044       stack[sp].loc = binary_loc;
8045       stack[sp].expr = c_parser_cast_expression (parser, NULL);
8046       stack[sp].prec = oprec;
8047       stack[sp].op = ocode;
8048       stack[sp].sizeof_arg = c_last_sizeof_arg;
8049     }
8050  out:
8051   while (sp > 0)
8052     POP;
8053   return stack[0].expr;
8054 #undef POP
8055 }
8056 
8057 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4).  If AFTER
8058    is not NULL then it is an Objective-C message expression which is the
8059    primary-expression starting the expression as an initializer.
8060 
8061    cast-expression:
8062      unary-expression
8063      ( type-name ) unary-expression
8064 */
8065 
8066 static struct c_expr
c_parser_cast_expression(c_parser * parser,struct c_expr * after)8067 c_parser_cast_expression (c_parser *parser, struct c_expr *after)
8068 {
8069   location_t cast_loc = c_parser_peek_token (parser)->location;
8070   gcc_assert (!after || c_dialect_objc ());
8071   if (after)
8072     return c_parser_postfix_expression_after_primary (parser,
8073 						      cast_loc, *after);
8074   /* If the expression begins with a parenthesized type name, it may
8075      be either a cast or a compound literal; we need to see whether
8076      the next character is '{' to tell the difference.  If not, it is
8077      an unary expression.  Full detection of unknown typenames here
8078      would require a 3-token lookahead.  */
8079   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8080       && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8081     {
8082       struct c_type_name *type_name;
8083       struct c_expr ret;
8084       struct c_expr expr;
8085       matching_parens parens;
8086       parens.consume_open (parser);
8087       type_name = c_parser_type_name (parser, true);
8088       parens.skip_until_found_close (parser);
8089       if (type_name == NULL)
8090 	{
8091 	  ret.set_error ();
8092 	  ret.original_code = ERROR_MARK;
8093 	  ret.original_type = NULL;
8094 	  return ret;
8095 	}
8096 
8097       /* Save casted types in the function's used types hash table.  */
8098       used_types_insert (type_name->specs->type);
8099 
8100       if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8101 	return c_parser_postfix_expression_after_paren_type (parser, type_name,
8102 							     cast_loc);
8103       if (type_name->specs->alignas_p)
8104 	error_at (type_name->specs->locations[cdw_alignas],
8105 		  "alignment specified for type name in cast");
8106       {
8107 	location_t expr_loc = c_parser_peek_token (parser)->location;
8108 	expr = c_parser_cast_expression (parser, NULL);
8109 	expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
8110       }
8111       ret.value = c_cast_expr (cast_loc, type_name, expr.value);
8112       if (ret.value && expr.value)
8113 	set_c_expr_source_range (&ret, cast_loc, expr.get_finish ());
8114       ret.original_code = ERROR_MARK;
8115       ret.original_type = NULL;
8116       return ret;
8117     }
8118   else
8119     return c_parser_unary_expression (parser);
8120 }
8121 
8122 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
8123 
8124    unary-expression:
8125      postfix-expression
8126      ++ unary-expression
8127      -- unary-expression
8128      unary-operator cast-expression
8129      sizeof unary-expression
8130      sizeof ( type-name )
8131 
8132    unary-operator: one of
8133      & * + - ~ !
8134 
8135    GNU extensions:
8136 
8137    unary-expression:
8138      __alignof__ unary-expression
8139      __alignof__ ( type-name )
8140      && identifier
8141 
8142    (C11 permits _Alignof with type names only.)
8143 
8144    unary-operator: one of
8145      __extension__ __real__ __imag__
8146 
8147    Transactional Memory:
8148 
8149    unary-expression:
8150      transaction-expression
8151 
8152    In addition, the GNU syntax treats ++ and -- as unary operators, so
8153    they may be applied to cast expressions with errors for non-lvalues
8154    given later.  */
8155 
8156 static struct c_expr
c_parser_unary_expression(c_parser * parser)8157 c_parser_unary_expression (c_parser *parser)
8158 {
8159   int ext;
8160   struct c_expr ret, op;
8161   location_t op_loc = c_parser_peek_token (parser)->location;
8162   location_t exp_loc;
8163   location_t finish;
8164   ret.original_code = ERROR_MARK;
8165   ret.original_type = NULL;
8166   switch (c_parser_peek_token (parser)->type)
8167     {
8168     case CPP_PLUS_PLUS:
8169       c_parser_consume_token (parser);
8170       exp_loc = c_parser_peek_token (parser)->location;
8171       op = c_parser_cast_expression (parser, NULL);
8172 
8173       op = default_function_array_read_conversion (exp_loc, op);
8174       return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
8175     case CPP_MINUS_MINUS:
8176       c_parser_consume_token (parser);
8177       exp_loc = c_parser_peek_token (parser)->location;
8178       op = c_parser_cast_expression (parser, NULL);
8179 
8180       op = default_function_array_read_conversion (exp_loc, op);
8181       return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
8182     case CPP_AND:
8183       c_parser_consume_token (parser);
8184       op = c_parser_cast_expression (parser, NULL);
8185       mark_exp_read (op.value);
8186       return parser_build_unary_op (op_loc, ADDR_EXPR, op);
8187     case CPP_MULT:
8188       {
8189 	c_parser_consume_token (parser);
8190 	exp_loc = c_parser_peek_token (parser)->location;
8191 	op = c_parser_cast_expression (parser, NULL);
8192 	finish = op.get_finish ();
8193 	op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8194 	location_t combined_loc = make_location (op_loc, op_loc, finish);
8195 	ret.value = build_indirect_ref (combined_loc, op.value, RO_UNARY_STAR);
8196 	ret.src_range.m_start = op_loc;
8197 	ret.src_range.m_finish = finish;
8198 	return ret;
8199       }
8200     case CPP_PLUS:
8201       if (!c_dialect_objc () && !in_system_header_at (input_location))
8202 	warning_at (op_loc,
8203 		    OPT_Wtraditional,
8204 		    "traditional C rejects the unary plus operator");
8205       c_parser_consume_token (parser);
8206       exp_loc = c_parser_peek_token (parser)->location;
8207       op = c_parser_cast_expression (parser, NULL);
8208       op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8209       return parser_build_unary_op (op_loc, CONVERT_EXPR, op);
8210     case CPP_MINUS:
8211       c_parser_consume_token (parser);
8212       exp_loc = c_parser_peek_token (parser)->location;
8213       op = c_parser_cast_expression (parser, NULL);
8214       op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8215       return parser_build_unary_op (op_loc, NEGATE_EXPR, op);
8216     case CPP_COMPL:
8217       c_parser_consume_token (parser);
8218       exp_loc = c_parser_peek_token (parser)->location;
8219       op = c_parser_cast_expression (parser, NULL);
8220       op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8221       return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
8222     case CPP_NOT:
8223       c_parser_consume_token (parser);
8224       exp_loc = c_parser_peek_token (parser)->location;
8225       op = c_parser_cast_expression (parser, NULL);
8226       op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8227       return parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op);
8228     case CPP_AND_AND:
8229       /* Refer to the address of a label as a pointer.  */
8230       c_parser_consume_token (parser);
8231       if (c_parser_next_token_is (parser, CPP_NAME))
8232 	{
8233 	  ret.value = finish_label_address_expr
8234 	    (c_parser_peek_token (parser)->value, op_loc);
8235 	  set_c_expr_source_range (&ret, op_loc,
8236 				   c_parser_peek_token (parser)->get_finish ());
8237 	  c_parser_consume_token (parser);
8238 	}
8239       else
8240 	{
8241 	  c_parser_error (parser, "expected identifier");
8242 	  ret.set_error ();
8243 	}
8244       return ret;
8245     case CPP_KEYWORD:
8246       switch (c_parser_peek_token (parser)->keyword)
8247 	{
8248 	case RID_SIZEOF:
8249 	  return c_parser_sizeof_expression (parser);
8250 	case RID_ALIGNOF:
8251 	  return c_parser_alignof_expression (parser);
8252 	case RID_BUILTIN_HAS_ATTRIBUTE:
8253 	  return c_parser_has_attribute_expression (parser);
8254 	case RID_EXTENSION:
8255 	  c_parser_consume_token (parser);
8256 	  ext = disable_extension_diagnostics ();
8257 	  ret = c_parser_cast_expression (parser, NULL);
8258 	  restore_extension_diagnostics (ext);
8259 	  return ret;
8260 	case RID_REALPART:
8261 	  c_parser_consume_token (parser);
8262 	  exp_loc = c_parser_peek_token (parser)->location;
8263 	  op = c_parser_cast_expression (parser, NULL);
8264 	  op = default_function_array_conversion (exp_loc, op);
8265 	  return parser_build_unary_op (op_loc, REALPART_EXPR, op);
8266 	case RID_IMAGPART:
8267 	  c_parser_consume_token (parser);
8268 	  exp_loc = c_parser_peek_token (parser)->location;
8269 	  op = c_parser_cast_expression (parser, NULL);
8270 	  op = default_function_array_conversion (exp_loc, op);
8271 	  return parser_build_unary_op (op_loc, IMAGPART_EXPR, op);
8272 	case RID_TRANSACTION_ATOMIC:
8273 	case RID_TRANSACTION_RELAXED:
8274 	  return c_parser_transaction_expression (parser,
8275 	      c_parser_peek_token (parser)->keyword);
8276 	default:
8277 	  return c_parser_postfix_expression (parser);
8278 	}
8279     default:
8280       return c_parser_postfix_expression (parser);
8281     }
8282 }
8283 
8284 /* Parse a sizeof expression.  */
8285 
8286 static struct c_expr
c_parser_sizeof_expression(c_parser * parser)8287 c_parser_sizeof_expression (c_parser *parser)
8288 {
8289   struct c_expr expr;
8290   struct c_expr result;
8291   location_t expr_loc;
8292   gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF));
8293 
8294   location_t start;
8295   location_t finish = UNKNOWN_LOCATION;
8296 
8297   start = c_parser_peek_token (parser)->location;
8298 
8299   c_parser_consume_token (parser);
8300   c_inhibit_evaluation_warnings++;
8301   in_sizeof++;
8302   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8303       && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8304     {
8305       /* Either sizeof ( type-name ) or sizeof unary-expression
8306 	 starting with a compound literal.  */
8307       struct c_type_name *type_name;
8308       matching_parens parens;
8309       parens.consume_open (parser);
8310       expr_loc = c_parser_peek_token (parser)->location;
8311       type_name = c_parser_type_name (parser, true);
8312       parens.skip_until_found_close (parser);
8313       finish = parser->tokens_buf[0].location;
8314       if (type_name == NULL)
8315 	{
8316 	  struct c_expr ret;
8317 	  c_inhibit_evaluation_warnings--;
8318 	  in_sizeof--;
8319 	  ret.set_error ();
8320 	  ret.original_code = ERROR_MARK;
8321 	  ret.original_type = NULL;
8322 	  return ret;
8323 	}
8324       if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8325 	{
8326 	  expr = c_parser_postfix_expression_after_paren_type (parser,
8327 							       type_name,
8328 							       expr_loc);
8329 	  finish = expr.get_finish ();
8330 	  goto sizeof_expr;
8331 	}
8332       /* sizeof ( type-name ).  */
8333       if (type_name->specs->alignas_p)
8334 	error_at (type_name->specs->locations[cdw_alignas],
8335 		  "alignment specified for type name in %<sizeof%>");
8336       c_inhibit_evaluation_warnings--;
8337       in_sizeof--;
8338       result = c_expr_sizeof_type (expr_loc, type_name);
8339     }
8340   else
8341     {
8342       expr_loc = c_parser_peek_token (parser)->location;
8343       expr = c_parser_unary_expression (parser);
8344       finish = expr.get_finish ();
8345     sizeof_expr:
8346       c_inhibit_evaluation_warnings--;
8347       in_sizeof--;
8348       mark_exp_read (expr.value);
8349       if (TREE_CODE (expr.value) == COMPONENT_REF
8350 	  && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
8351 	error_at (expr_loc, "%<sizeof%> applied to a bit-field");
8352       result = c_expr_sizeof_expr (expr_loc, expr);
8353     }
8354   if (finish == UNKNOWN_LOCATION)
8355     finish = start;
8356   set_c_expr_source_range (&result, start, finish);
8357   return result;
8358 }
8359 
8360 /* Parse an alignof expression.  */
8361 
8362 static struct c_expr
c_parser_alignof_expression(c_parser * parser)8363 c_parser_alignof_expression (c_parser *parser)
8364 {
8365   struct c_expr expr;
8366   location_t start_loc = c_parser_peek_token (parser)->location;
8367   location_t end_loc;
8368   tree alignof_spelling = c_parser_peek_token (parser)->value;
8369   gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF));
8370   bool is_c11_alignof = strcmp (IDENTIFIER_POINTER (alignof_spelling),
8371 				"_Alignof") == 0;
8372   /* A diagnostic is not required for the use of this identifier in
8373      the implementation namespace; only diagnose it for the C11
8374      spelling because of existing code using the other spellings.  */
8375   if (is_c11_alignof)
8376     {
8377       if (flag_isoc99)
8378 	pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C99 does not support %qE",
8379 		     alignof_spelling);
8380       else
8381 	pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C90 does not support %qE",
8382 		     alignof_spelling);
8383     }
8384   c_parser_consume_token (parser);
8385   c_inhibit_evaluation_warnings++;
8386   in_alignof++;
8387   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8388       && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8389     {
8390       /* Either __alignof__ ( type-name ) or __alignof__
8391 	 unary-expression starting with a compound literal.  */
8392       location_t loc;
8393       struct c_type_name *type_name;
8394       struct c_expr ret;
8395       matching_parens parens;
8396       parens.consume_open (parser);
8397       loc = c_parser_peek_token (parser)->location;
8398       type_name = c_parser_type_name (parser, true);
8399       end_loc = c_parser_peek_token (parser)->location;
8400       parens.skip_until_found_close (parser);
8401       if (type_name == NULL)
8402 	{
8403 	  struct c_expr ret;
8404 	  c_inhibit_evaluation_warnings--;
8405 	  in_alignof--;
8406 	  ret.set_error ();
8407 	  ret.original_code = ERROR_MARK;
8408 	  ret.original_type = NULL;
8409 	  return ret;
8410 	}
8411       if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8412 	{
8413 	  expr = c_parser_postfix_expression_after_paren_type (parser,
8414 							       type_name,
8415 							       loc);
8416 	  goto alignof_expr;
8417 	}
8418       /* alignof ( type-name ).  */
8419       if (type_name->specs->alignas_p)
8420 	error_at (type_name->specs->locations[cdw_alignas],
8421 		  "alignment specified for type name in %qE",
8422 		  alignof_spelling);
8423       c_inhibit_evaluation_warnings--;
8424       in_alignof--;
8425       ret.value = c_sizeof_or_alignof_type (loc, groktypename (type_name,
8426 							       NULL, NULL),
8427 					    false, is_c11_alignof, 1);
8428       ret.original_code = ERROR_MARK;
8429       ret.original_type = NULL;
8430       set_c_expr_source_range (&ret, start_loc, end_loc);
8431       return ret;
8432     }
8433   else
8434     {
8435       struct c_expr ret;
8436       expr = c_parser_unary_expression (parser);
8437       end_loc = expr.src_range.m_finish;
8438     alignof_expr:
8439       mark_exp_read (expr.value);
8440       c_inhibit_evaluation_warnings--;
8441       in_alignof--;
8442       if (is_c11_alignof)
8443 	pedwarn (start_loc,
8444 		 OPT_Wpedantic, "ISO C does not allow %<%E (expression)%>",
8445 		 alignof_spelling);
8446       ret.value = c_alignof_expr (start_loc, expr.value);
8447       ret.original_code = ERROR_MARK;
8448       ret.original_type = NULL;
8449       set_c_expr_source_range (&ret, start_loc, end_loc);
8450       return ret;
8451     }
8452 }
8453 
8454 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
8455    expression.  */
8456 
8457 static struct c_expr
c_parser_has_attribute_expression(c_parser * parser)8458 c_parser_has_attribute_expression (c_parser *parser)
8459 {
8460   gcc_assert (c_parser_next_token_is_keyword (parser,
8461 					      RID_BUILTIN_HAS_ATTRIBUTE));
8462   c_parser_consume_token (parser);
8463 
8464   c_inhibit_evaluation_warnings++;
8465 
8466   matching_parens parens;
8467   if (!parens.require_open (parser))
8468     {
8469       c_inhibit_evaluation_warnings--;
8470       in_typeof--;
8471 
8472       struct c_expr result;
8473       result.set_error ();
8474       result.original_code = ERROR_MARK;
8475       result.original_type = NULL;
8476       return result;
8477     }
8478 
8479   /* Treat the type argument the same way as in typeof for the purposes
8480      of warnings.  FIXME: Generalize this so the warning refers to
8481      __builtin_has_attribute rather than typeof.  */
8482   in_typeof++;
8483 
8484   /* The first operand: one of DECL, EXPR, or TYPE.  */
8485   tree oper = NULL_TREE;
8486   if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
8487     {
8488       struct c_type_name *tname = c_parser_type_name (parser);
8489       in_typeof--;
8490       if (tname)
8491 	{
8492 	  oper = groktypename (tname, NULL, NULL);
8493 	  pop_maybe_used (variably_modified_type_p (oper, NULL_TREE));
8494 	}
8495     }
8496   else
8497     {
8498       struct c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
8499       c_inhibit_evaluation_warnings--;
8500       in_typeof--;
8501       if (cexpr.value != error_mark_node)
8502 	{
8503 	  mark_exp_read (cexpr.value);
8504 	  oper = cexpr.value;
8505 	  tree etype = TREE_TYPE (oper);
8506 	  bool was_vm = variably_modified_type_p (etype, NULL_TREE);
8507 	  /* This is returned with the type so that when the type is
8508 	     evaluated, this can be evaluated.  */
8509 	  if (was_vm)
8510 	    oper = c_fully_fold (oper, false, NULL);
8511 	  pop_maybe_used (was_vm);
8512 	}
8513     }
8514 
8515   struct c_expr result;
8516   result.original_code = ERROR_MARK;
8517   result.original_type = NULL;
8518 
8519   if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8520     {
8521       /* Consume the closing parenthesis if that's the next token
8522 	 in the likely case the built-in was invoked with fewer
8523 	 than two arguments.  */
8524       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8525 	c_parser_consume_token (parser);
8526       c_inhibit_evaluation_warnings--;
8527       result.set_error ();
8528       return result;
8529     }
8530 
8531   bool save_translate_strings_p = parser->translate_strings_p;
8532 
8533   location_t atloc = c_parser_peek_token (parser)->location;
8534   /* Parse a single attribute.  Require no leading comma and do not
8535      allow empty attributes.  */
8536   tree attr = c_parser_gnu_attribute (parser, NULL_TREE, false, false);
8537 
8538   parser->translate_strings_p = save_translate_strings_p;
8539 
8540   if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8541     c_parser_consume_token (parser);
8542   else
8543     {
8544       c_parser_error (parser, "expected identifier");
8545       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8546 
8547       result.set_error ();
8548       return result;
8549     }
8550 
8551   if (!attr)
8552     {
8553       error_at (atloc, "expected identifier");
8554       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
8555 				 "expected %<)%>");
8556       result.set_error ();
8557       return result;
8558     }
8559 
8560   result.original_code = INTEGER_CST;
8561   result.original_type = boolean_type_node;
8562 
8563   if (has_attribute (atloc, oper, attr, default_conversion))
8564     result.value = boolean_true_node;
8565   else
8566     result.value =  boolean_false_node;
8567 
8568   return result;
8569 }
8570 
8571 /* Helper function to read arguments of builtins which are interfaces
8572    for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
8573    others.  The name of the builtin is passed using BNAME parameter.
8574    Function returns true if there were no errors while parsing and
8575    stores the arguments in CEXPR_LIST.  If it returns true,
8576    *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
8577    parenthesis.  */
8578 static bool
c_parser_get_builtin_args(c_parser * parser,const char * bname,vec<c_expr_t,va_gc> ** ret_cexpr_list,bool choose_expr_p,location_t * out_close_paren_loc)8579 c_parser_get_builtin_args (c_parser *parser, const char *bname,
8580 			   vec<c_expr_t, va_gc> **ret_cexpr_list,
8581 			   bool choose_expr_p,
8582 			   location_t *out_close_paren_loc)
8583 {
8584   location_t loc = c_parser_peek_token (parser)->location;
8585   vec<c_expr_t, va_gc> *cexpr_list;
8586   c_expr_t expr;
8587   bool saved_force_folding_builtin_constant_p;
8588 
8589   *ret_cexpr_list = NULL;
8590   if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
8591     {
8592       error_at (loc, "cannot take address of %qs", bname);
8593       return false;
8594     }
8595 
8596   c_parser_consume_token (parser);
8597 
8598   if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8599     {
8600       *out_close_paren_loc = c_parser_peek_token (parser)->location;
8601       c_parser_consume_token (parser);
8602       return true;
8603     }
8604 
8605   saved_force_folding_builtin_constant_p
8606     = force_folding_builtin_constant_p;
8607   force_folding_builtin_constant_p |= choose_expr_p;
8608   expr = c_parser_expr_no_commas (parser, NULL);
8609   force_folding_builtin_constant_p
8610     = saved_force_folding_builtin_constant_p;
8611   vec_alloc (cexpr_list, 1);
8612   vec_safe_push (cexpr_list, expr);
8613   while (c_parser_next_token_is (parser, CPP_COMMA))
8614     {
8615       c_parser_consume_token (parser);
8616       expr = c_parser_expr_no_commas (parser, NULL);
8617       vec_safe_push (cexpr_list, expr);
8618     }
8619 
8620   *out_close_paren_loc = c_parser_peek_token (parser)->location;
8621   if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
8622     return false;
8623 
8624   *ret_cexpr_list = cexpr_list;
8625   return true;
8626 }
8627 
8628 /* This represents a single generic-association.  */
8629 
8630 struct c_generic_association
8631 {
8632   /* The location of the starting token of the type.  */
8633   location_t type_location;
8634   /* The association's type, or NULL_TREE for 'default'.  */
8635   tree type;
8636   /* The association's expression.  */
8637   struct c_expr expression;
8638 };
8639 
8640 /* Parse a generic-selection.  (C11 6.5.1.1).
8641 
8642    generic-selection:
8643      _Generic ( assignment-expression , generic-assoc-list )
8644 
8645    generic-assoc-list:
8646      generic-association
8647      generic-assoc-list , generic-association
8648 
8649    generic-association:
8650      type-name : assignment-expression
8651      default : assignment-expression
8652 */
8653 
8654 static struct c_expr
c_parser_generic_selection(c_parser * parser)8655 c_parser_generic_selection (c_parser *parser)
8656 {
8657   struct c_expr selector, error_expr;
8658   tree selector_type;
8659   struct c_generic_association matched_assoc;
8660   int match_found = -1;
8661   location_t generic_loc, selector_loc;
8662 
8663   error_expr.original_code = ERROR_MARK;
8664   error_expr.original_type = NULL;
8665   error_expr.set_error ();
8666   matched_assoc.type_location = UNKNOWN_LOCATION;
8667   matched_assoc.type = NULL_TREE;
8668   matched_assoc.expression = error_expr;
8669 
8670   gcc_assert (c_parser_next_token_is_keyword (parser, RID_GENERIC));
8671   generic_loc = c_parser_peek_token (parser)->location;
8672   c_parser_consume_token (parser);
8673   if (flag_isoc99)
8674     pedwarn_c99 (generic_loc, OPT_Wpedantic,
8675 		 "ISO C99 does not support %<_Generic%>");
8676   else
8677     pedwarn_c99 (generic_loc, OPT_Wpedantic,
8678 		 "ISO C90 does not support %<_Generic%>");
8679 
8680   matching_parens parens;
8681   if (!parens.require_open (parser))
8682     return error_expr;
8683 
8684   c_inhibit_evaluation_warnings++;
8685   selector_loc = c_parser_peek_token (parser)->location;
8686   selector = c_parser_expr_no_commas (parser, NULL);
8687   selector = default_function_array_conversion (selector_loc, selector);
8688   c_inhibit_evaluation_warnings--;
8689 
8690   if (selector.value == error_mark_node)
8691     {
8692       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8693       return selector;
8694     }
8695   mark_exp_read (selector.value);
8696   selector_type = TREE_TYPE (selector.value);
8697   /* In ISO C terms, rvalues (including the controlling expression of
8698      _Generic) do not have qualified types.  */
8699   if (TREE_CODE (selector_type) != ARRAY_TYPE)
8700     selector_type = TYPE_MAIN_VARIANT (selector_type);
8701   /* In ISO C terms, _Noreturn is not part of the type of expressions
8702      such as &abort, but in GCC it is represented internally as a type
8703      qualifier.  */
8704   if (FUNCTION_POINTER_TYPE_P (selector_type)
8705       && TYPE_QUALS (TREE_TYPE (selector_type)) != TYPE_UNQUALIFIED)
8706     selector_type
8707       = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type)));
8708 
8709   if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8710     {
8711       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8712       return error_expr;
8713     }
8714 
8715   auto_vec<c_generic_association> associations;
8716   while (1)
8717     {
8718       struct c_generic_association assoc, *iter;
8719       unsigned int ix;
8720       c_token *token = c_parser_peek_token (parser);
8721 
8722       assoc.type_location = token->location;
8723       if (token->type == CPP_KEYWORD && token->keyword == RID_DEFAULT)
8724 	{
8725 	  c_parser_consume_token (parser);
8726 	  assoc.type = NULL_TREE;
8727 	}
8728       else
8729 	{
8730 	  struct c_type_name *type_name;
8731 
8732 	  type_name = c_parser_type_name (parser);
8733 	  if (type_name == NULL)
8734 	    {
8735 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8736 	      return error_expr;
8737 	    }
8738 	  assoc.type = groktypename (type_name, NULL, NULL);
8739 	  if (assoc.type == error_mark_node)
8740 	    {
8741 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8742 	      return error_expr;
8743 	    }
8744 
8745 	  if (TREE_CODE (assoc.type) == FUNCTION_TYPE)
8746 	    error_at (assoc.type_location,
8747 		      "%<_Generic%> association has function type");
8748 	  else if (!COMPLETE_TYPE_P (assoc.type))
8749 	    error_at (assoc.type_location,
8750 		      "%<_Generic%> association has incomplete type");
8751 
8752 	  if (variably_modified_type_p (assoc.type, NULL_TREE))
8753 	    error_at (assoc.type_location,
8754 		      "%<_Generic%> association has "
8755 		      "variable length type");
8756 	}
8757 
8758       if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
8759 	{
8760 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8761 	  return error_expr;
8762 	}
8763 
8764       assoc.expression = c_parser_expr_no_commas (parser, NULL);
8765       if (assoc.expression.value == error_mark_node)
8766 	{
8767 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8768 	  return error_expr;
8769 	}
8770 
8771       for (ix = 0; associations.iterate (ix, &iter); ++ix)
8772 	{
8773 	  if (assoc.type == NULL_TREE)
8774 	    {
8775 	      if (iter->type == NULL_TREE)
8776 		{
8777 		  error_at (assoc.type_location,
8778 			    "duplicate %<default%> case in %<_Generic%>");
8779 		  inform (iter->type_location, "original %<default%> is here");
8780 		}
8781 	    }
8782 	  else if (iter->type != NULL_TREE)
8783 	    {
8784 	      if (comptypes (assoc.type, iter->type))
8785 		{
8786 		  error_at (assoc.type_location,
8787 			    "%<_Generic%> specifies two compatible types");
8788 		  inform (iter->type_location, "compatible type is here");
8789 		}
8790 	    }
8791 	}
8792 
8793       if (assoc.type == NULL_TREE)
8794 	{
8795 	  if (match_found < 0)
8796 	    {
8797 	      matched_assoc = assoc;
8798 	      match_found = associations.length ();
8799 	    }
8800 	}
8801       else if (comptypes (assoc.type, selector_type))
8802 	{
8803 	  if (match_found < 0 || matched_assoc.type == NULL_TREE)
8804 	    {
8805 	      matched_assoc = assoc;
8806 	      match_found = associations.length ();
8807 	    }
8808 	  else
8809 	    {
8810 	      error_at (assoc.type_location,
8811 			"%<_Generic%> selector matches multiple associations");
8812 	      inform (matched_assoc.type_location,
8813 		      "other match is here");
8814 	    }
8815 	}
8816 
8817       associations.safe_push (assoc);
8818 
8819       if (c_parser_peek_token (parser)->type != CPP_COMMA)
8820 	break;
8821       c_parser_consume_token (parser);
8822     }
8823 
8824   unsigned int ix;
8825   struct c_generic_association *iter;
8826   FOR_EACH_VEC_ELT (associations, ix, iter)
8827     if (ix != (unsigned) match_found)
8828       mark_exp_read (iter->expression.value);
8829 
8830   if (!parens.require_close (parser))
8831     {
8832       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8833       return error_expr;
8834     }
8835 
8836   if (match_found < 0)
8837     {
8838       error_at (selector_loc, "%<_Generic%> selector of type %qT is not "
8839 		"compatible with any association",
8840 		selector_type);
8841       return error_expr;
8842     }
8843 
8844   return matched_assoc.expression;
8845 }
8846 
8847 /* Check the validity of a function pointer argument *EXPR (argument
8848    position POS) to __builtin_tgmath.  Return the number of function
8849    arguments if possibly valid; return 0 having reported an error if
8850    not valid.  */
8851 
8852 static unsigned int
check_tgmath_function(c_expr * expr,unsigned int pos)8853 check_tgmath_function (c_expr *expr, unsigned int pos)
8854 {
8855   tree type = TREE_TYPE (expr->value);
8856   if (!FUNCTION_POINTER_TYPE_P (type))
8857     {
8858       error_at (expr->get_location (),
8859 		"argument %u of %<__builtin_tgmath%> is not a function pointer",
8860 		pos);
8861       return 0;
8862     }
8863   type = TREE_TYPE (type);
8864   if (!prototype_p (type))
8865     {
8866       error_at (expr->get_location (),
8867 		"argument %u of %<__builtin_tgmath%> is unprototyped", pos);
8868       return 0;
8869     }
8870   if (stdarg_p (type))
8871     {
8872       error_at (expr->get_location (),
8873 		"argument %u of %<__builtin_tgmath%> has variable arguments",
8874 		pos);
8875       return 0;
8876     }
8877   unsigned int nargs = 0;
8878   function_args_iterator iter;
8879   tree t;
8880   FOREACH_FUNCTION_ARGS (type, t, iter)
8881     {
8882       if (t == void_type_node)
8883 	break;
8884       nargs++;
8885     }
8886   if (nargs == 0)
8887     {
8888       error_at (expr->get_location (),
8889 		"argument %u of %<__builtin_tgmath%> has no arguments", pos);
8890       return 0;
8891     }
8892   return nargs;
8893 }
8894 
8895 /* Ways in which a parameter or return value of a type-generic macro
8896    may vary between the different functions the macro may call.  */
8897 enum tgmath_parm_kind
8898   {
8899     tgmath_fixed, tgmath_real, tgmath_complex
8900   };
8901 
8902 /* Helper function for c_parser_postfix_expression.  Parse predefined
8903    identifiers.  */
8904 
8905 static struct c_expr
c_parser_predefined_identifier(c_parser * parser)8906 c_parser_predefined_identifier (c_parser *parser)
8907 {
8908   location_t loc = c_parser_peek_token (parser)->location;
8909   switch (c_parser_peek_token (parser)->keyword)
8910     {
8911     case RID_FUNCTION_NAME:
8912       pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
8913 	       "identifier", "__FUNCTION__");
8914       break;
8915     case RID_PRETTY_FUNCTION_NAME:
8916       pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
8917 	       "identifier", "__PRETTY_FUNCTION__");
8918       break;
8919     case RID_C99_FUNCTION_NAME:
8920       pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not support "
8921 		   "%<__func__%> predefined identifier");
8922       break;
8923     default:
8924       gcc_unreachable ();
8925     }
8926 
8927   struct c_expr expr;
8928   expr.original_code = ERROR_MARK;
8929   expr.original_type = NULL;
8930   expr.value = fname_decl (loc, c_parser_peek_token (parser)->keyword,
8931 			   c_parser_peek_token (parser)->value);
8932   set_c_expr_source_range (&expr, loc, loc);
8933   c_parser_consume_token (parser);
8934   return expr;
8935 }
8936 
8937 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
8938    C11 6.5.1-6.5.2).  Compound literals aren't handled here; callers have to
8939    call c_parser_postfix_expression_after_paren_type on encountering them.
8940 
8941    postfix-expression:
8942      primary-expression
8943      postfix-expression [ expression ]
8944      postfix-expression ( argument-expression-list[opt] )
8945      postfix-expression . identifier
8946      postfix-expression -> identifier
8947      postfix-expression ++
8948      postfix-expression --
8949      ( type-name ) { initializer-list }
8950      ( type-name ) { initializer-list , }
8951 
8952    argument-expression-list:
8953      argument-expression
8954      argument-expression-list , argument-expression
8955 
8956    primary-expression:
8957      identifier
8958      constant
8959      string-literal
8960      ( expression )
8961      generic-selection
8962 
8963    GNU extensions:
8964 
8965    primary-expression:
8966      __func__
8967        (treated as a keyword in GNU C)
8968      __FUNCTION__
8969      __PRETTY_FUNCTION__
8970      ( compound-statement )
8971      __builtin_va_arg ( assignment-expression , type-name )
8972      __builtin_offsetof ( type-name , offsetof-member-designator )
8973      __builtin_choose_expr ( assignment-expression ,
8974 			     assignment-expression ,
8975 			     assignment-expression )
8976      __builtin_types_compatible_p ( type-name , type-name )
8977      __builtin_tgmath ( expr-list )
8978      __builtin_complex ( assignment-expression , assignment-expression )
8979      __builtin_shuffle ( assignment-expression , assignment-expression )
8980      __builtin_shuffle ( assignment-expression ,
8981 			 assignment-expression ,
8982 			 assignment-expression, )
8983      __builtin_convertvector ( assignment-expression , type-name )
8984 
8985    offsetof-member-designator:
8986      identifier
8987      offsetof-member-designator . identifier
8988      offsetof-member-designator [ expression ]
8989 
8990    Objective-C:
8991 
8992    primary-expression:
8993      [ objc-receiver objc-message-args ]
8994      @selector ( objc-selector-arg )
8995      @protocol ( identifier )
8996      @encode ( type-name )
8997      objc-string-literal
8998      Classname . identifier
8999 */
9000 
9001 static struct c_expr
c_parser_postfix_expression(c_parser * parser)9002 c_parser_postfix_expression (c_parser *parser)
9003 {
9004   struct c_expr expr, e1;
9005   struct c_type_name *t1, *t2;
9006   location_t loc = c_parser_peek_token (parser)->location;
9007   source_range tok_range = c_parser_peek_token (parser)->get_range ();
9008   expr.original_code = ERROR_MARK;
9009   expr.original_type = NULL;
9010   switch (c_parser_peek_token (parser)->type)
9011     {
9012     case CPP_NUMBER:
9013       expr.value = c_parser_peek_token (parser)->value;
9014       set_c_expr_source_range (&expr, tok_range);
9015       loc = c_parser_peek_token (parser)->location;
9016       c_parser_consume_token (parser);
9017       if (TREE_CODE (expr.value) == FIXED_CST
9018 	  && !targetm.fixed_point_supported_p ())
9019 	{
9020 	  error_at (loc, "fixed-point types not supported for this target");
9021 	  expr.set_error ();
9022 	}
9023       break;
9024     case CPP_CHAR:
9025     case CPP_CHAR16:
9026     case CPP_CHAR32:
9027     case CPP_UTF8CHAR:
9028     case CPP_WCHAR:
9029       expr.value = c_parser_peek_token (parser)->value;
9030       /* For the purpose of warning when a pointer is compared with
9031 	 a zero character constant.  */
9032       expr.original_type = char_type_node;
9033       set_c_expr_source_range (&expr, tok_range);
9034       c_parser_consume_token (parser);
9035       break;
9036     case CPP_STRING:
9037     case CPP_STRING16:
9038     case CPP_STRING32:
9039     case CPP_WSTRING:
9040     case CPP_UTF8STRING:
9041       expr = c_parser_string_literal (parser, parser->translate_strings_p,
9042 				      true);
9043       break;
9044     case CPP_OBJC_STRING:
9045       gcc_assert (c_dialect_objc ());
9046       expr.value
9047 	= objc_build_string_object (c_parser_peek_token (parser)->value);
9048       set_c_expr_source_range (&expr, tok_range);
9049       c_parser_consume_token (parser);
9050       break;
9051     case CPP_NAME:
9052       switch (c_parser_peek_token (parser)->id_kind)
9053 	{
9054 	case C_ID_ID:
9055 	  {
9056 	    tree id = c_parser_peek_token (parser)->value;
9057 	    c_parser_consume_token (parser);
9058 	    expr.value = build_external_ref (loc, id,
9059 					     (c_parser_peek_token (parser)->type
9060 					      == CPP_OPEN_PAREN),
9061 					     &expr.original_type);
9062 	    set_c_expr_source_range (&expr, tok_range);
9063 	    break;
9064 	  }
9065 	case C_ID_CLASSNAME:
9066 	  {
9067 	    /* Here we parse the Objective-C 2.0 Class.name dot
9068 	       syntax.  */
9069 	    tree class_name = c_parser_peek_token (parser)->value;
9070 	    tree component;
9071 	    c_parser_consume_token (parser);
9072 	    gcc_assert (c_dialect_objc ());
9073 	    if (!c_parser_require (parser, CPP_DOT, "expected %<.%>"))
9074 	      {
9075 		expr.set_error ();
9076 		break;
9077 	      }
9078 	    if (c_parser_next_token_is_not (parser, CPP_NAME))
9079 	      {
9080 		c_parser_error (parser, "expected identifier");
9081 		expr.set_error ();
9082 		break;
9083 	      }
9084 	    c_token *component_tok = c_parser_peek_token (parser);
9085 	    component = component_tok->value;
9086 	    location_t end_loc = component_tok->get_finish ();
9087 	    c_parser_consume_token (parser);
9088 	    expr.value = objc_build_class_component_ref (class_name,
9089 							 component);
9090 	    set_c_expr_source_range (&expr, loc, end_loc);
9091 	    break;
9092 	  }
9093 	default:
9094 	  c_parser_error (parser, "expected expression");
9095 	  expr.set_error ();
9096 	  break;
9097 	}
9098       break;
9099     case CPP_OPEN_PAREN:
9100       /* A parenthesized expression, statement expression or compound
9101 	 literal.  */
9102       if (c_parser_peek_2nd_token (parser)->type == CPP_OPEN_BRACE)
9103 	{
9104 	  /* A statement expression.  */
9105 	  tree stmt;
9106 	  location_t brace_loc;
9107 	  c_parser_consume_token (parser);
9108 	  brace_loc = c_parser_peek_token (parser)->location;
9109 	  c_parser_consume_token (parser);
9110 	  /* If we've not yet started the current function's statement list,
9111 	     or we're in the parameter scope of an old-style function
9112 	     declaration, statement expressions are not allowed.  */
9113 	  if (!building_stmt_list_p () || old_style_parameter_scope ())
9114 	    {
9115 	      error_at (loc, "braced-group within expression allowed "
9116 			"only inside a function");
9117 	      parser->error = true;
9118 	      c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
9119 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9120 	      expr.set_error ();
9121 	      break;
9122 	    }
9123 	  stmt = c_begin_stmt_expr ();
9124 	  c_parser_compound_statement_nostart (parser);
9125 	  location_t close_loc = c_parser_peek_token (parser)->location;
9126 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9127 				     "expected %<)%>");
9128 	  pedwarn (loc, OPT_Wpedantic,
9129 		   "ISO C forbids braced-groups within expressions");
9130 	  expr.value = c_finish_stmt_expr (brace_loc, stmt);
9131 	  set_c_expr_source_range (&expr, loc, close_loc);
9132 	  mark_exp_read (expr.value);
9133 	}
9134       else
9135 	{
9136 	  /* A parenthesized expression.  */
9137 	  location_t loc_open_paren = c_parser_peek_token (parser)->location;
9138 	  c_parser_consume_token (parser);
9139 	  expr = c_parser_expression (parser);
9140 	  if (TREE_CODE (expr.value) == MODIFY_EXPR)
9141 	    TREE_NO_WARNING (expr.value) = 1;
9142 	  if (expr.original_code != C_MAYBE_CONST_EXPR
9143 	      && expr.original_code != SIZEOF_EXPR)
9144 	    expr.original_code = ERROR_MARK;
9145 	  /* Don't change EXPR.ORIGINAL_TYPE.  */
9146 	  location_t loc_close_paren = c_parser_peek_token (parser)->location;
9147 	  set_c_expr_source_range (&expr, loc_open_paren, loc_close_paren);
9148 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9149 				     "expected %<)%>", loc_open_paren);
9150 	}
9151       break;
9152     case CPP_KEYWORD:
9153       switch (c_parser_peek_token (parser)->keyword)
9154 	{
9155 	case RID_FUNCTION_NAME:
9156 	case RID_PRETTY_FUNCTION_NAME:
9157 	case RID_C99_FUNCTION_NAME:
9158 	  expr = c_parser_predefined_identifier (parser);
9159 	  break;
9160 	case RID_VA_ARG:
9161 	  {
9162 	    location_t start_loc = loc;
9163 	    c_parser_consume_token (parser);
9164 	    matching_parens parens;
9165 	    if (!parens.require_open (parser))
9166 	      {
9167 		expr.set_error ();
9168 		break;
9169 	      }
9170 	    e1 = c_parser_expr_no_commas (parser, NULL);
9171 	    mark_exp_read (e1.value);
9172 	    e1.value = c_fully_fold (e1.value, false, NULL);
9173 	    if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9174 	      {
9175 		c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9176 		expr.set_error ();
9177 		break;
9178 	      }
9179 	    loc = c_parser_peek_token (parser)->location;
9180 	    t1 = c_parser_type_name (parser);
9181 	    location_t end_loc = c_parser_peek_token (parser)->get_finish ();
9182 	    c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9183 				       "expected %<)%>");
9184 	    if (t1 == NULL)
9185 	      {
9186 		expr.set_error ();
9187 	      }
9188 	    else
9189 	      {
9190 		tree type_expr = NULL_TREE;
9191 		expr.value = c_build_va_arg (start_loc, e1.value, loc,
9192 					     groktypename (t1, &type_expr, NULL));
9193 		if (type_expr)
9194 		  {
9195 		    expr.value = build2 (C_MAYBE_CONST_EXPR,
9196 					 TREE_TYPE (expr.value), type_expr,
9197 					 expr.value);
9198 		    C_MAYBE_CONST_EXPR_NON_CONST (expr.value) = true;
9199 		  }
9200 		set_c_expr_source_range (&expr, start_loc, end_loc);
9201 	      }
9202 	  }
9203 	  break;
9204 	case RID_OFFSETOF:
9205 	  {
9206 	    c_parser_consume_token (parser);
9207 	    matching_parens parens;
9208 	    if (!parens.require_open (parser))
9209 	      {
9210 		expr.set_error ();
9211 		break;
9212 	      }
9213 	    t1 = c_parser_type_name (parser);
9214 	    if (t1 == NULL)
9215 	      parser->error = true;
9216 	    if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9217 	      gcc_assert (parser->error);
9218 	    if (parser->error)
9219 	      {
9220 		c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9221 		expr.set_error ();
9222 		break;
9223 	      }
9224 	    tree type = groktypename (t1, NULL, NULL);
9225 	    tree offsetof_ref;
9226 	    if (type == error_mark_node)
9227 	      offsetof_ref = error_mark_node;
9228 	    else
9229 	      {
9230 		offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
9231 		SET_EXPR_LOCATION (offsetof_ref, loc);
9232 	      }
9233 	    /* Parse the second argument to __builtin_offsetof.  We
9234 	       must have one identifier, and beyond that we want to
9235 	       accept sub structure and sub array references.  */
9236 	    if (c_parser_next_token_is (parser, CPP_NAME))
9237 	      {
9238 		c_token *comp_tok = c_parser_peek_token (parser);
9239 		offsetof_ref = build_component_ref
9240 		  (loc, offsetof_ref, comp_tok->value, comp_tok->location);
9241 		c_parser_consume_token (parser);
9242 		while (c_parser_next_token_is (parser, CPP_DOT)
9243 		       || c_parser_next_token_is (parser,
9244 						  CPP_OPEN_SQUARE)
9245 		       || c_parser_next_token_is (parser,
9246 						  CPP_DEREF))
9247 		  {
9248 		    if (c_parser_next_token_is (parser, CPP_DEREF))
9249 		      {
9250 			loc = c_parser_peek_token (parser)->location;
9251 			offsetof_ref = build_array_ref (loc,
9252 							offsetof_ref,
9253 							integer_zero_node);
9254 			goto do_dot;
9255 		      }
9256 		    else if (c_parser_next_token_is (parser, CPP_DOT))
9257 		      {
9258 		      do_dot:
9259 			c_parser_consume_token (parser);
9260 			if (c_parser_next_token_is_not (parser,
9261 							CPP_NAME))
9262 			  {
9263 			    c_parser_error (parser, "expected identifier");
9264 			    break;
9265 			  }
9266 			c_token *comp_tok = c_parser_peek_token (parser);
9267 			offsetof_ref = build_component_ref
9268 			  (loc, offsetof_ref, comp_tok->value,
9269 			   comp_tok->location);
9270 			c_parser_consume_token (parser);
9271 		      }
9272 		    else
9273 		      {
9274 			struct c_expr ce;
9275 			tree idx;
9276 			loc = c_parser_peek_token (parser)->location;
9277 			c_parser_consume_token (parser);
9278 			ce = c_parser_expression (parser);
9279 			ce = convert_lvalue_to_rvalue (loc, ce, false, false);
9280 			idx = ce.value;
9281 			idx = c_fully_fold (idx, false, NULL);
9282 			c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
9283 						   "expected %<]%>");
9284 			offsetof_ref = build_array_ref (loc, offsetof_ref, idx);
9285 		      }
9286 		  }
9287 	      }
9288 	    else
9289 	      c_parser_error (parser, "expected identifier");
9290 	    location_t end_loc = c_parser_peek_token (parser)->get_finish ();
9291 	    c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9292 				       "expected %<)%>");
9293 	    expr.value = fold_offsetof (offsetof_ref);
9294 	    set_c_expr_source_range (&expr, loc, end_loc);
9295 	  }
9296 	  break;
9297 	case RID_CHOOSE_EXPR:
9298 	  {
9299 	    vec<c_expr_t, va_gc> *cexpr_list;
9300 	    c_expr_t *e1_p, *e2_p, *e3_p;
9301 	    tree c;
9302 	    location_t close_paren_loc;
9303 
9304 	    c_parser_consume_token (parser);
9305 	    if (!c_parser_get_builtin_args (parser,
9306 					    "__builtin_choose_expr",
9307 					    &cexpr_list, true,
9308 					    &close_paren_loc))
9309 	      {
9310 		expr.set_error ();
9311 		break;
9312 	      }
9313 
9314 	    if (vec_safe_length (cexpr_list) != 3)
9315 	      {
9316 		error_at (loc, "wrong number of arguments to "
9317 			       "%<__builtin_choose_expr%>");
9318 		expr.set_error ();
9319 		break;
9320 	      }
9321 
9322 	    e1_p = &(*cexpr_list)[0];
9323 	    e2_p = &(*cexpr_list)[1];
9324 	    e3_p = &(*cexpr_list)[2];
9325 
9326 	    c = e1_p->value;
9327 	    mark_exp_read (e2_p->value);
9328 	    mark_exp_read (e3_p->value);
9329 	    if (TREE_CODE (c) != INTEGER_CST
9330 		|| !INTEGRAL_TYPE_P (TREE_TYPE (c)))
9331 	      error_at (loc,
9332 			"first argument to %<__builtin_choose_expr%> not"
9333 			" a constant");
9334 	    constant_expression_warning (c);
9335 	    expr = integer_zerop (c) ? *e3_p : *e2_p;
9336 	    set_c_expr_source_range (&expr, loc, close_paren_loc);
9337 	    break;
9338 	  }
9339 	case RID_TYPES_COMPATIBLE_P:
9340 	  {
9341 	    c_parser_consume_token (parser);
9342 	    matching_parens parens;
9343 	    if (!parens.require_open (parser))
9344 	      {
9345 		expr.set_error ();
9346 		break;
9347 	      }
9348 	    t1 = c_parser_type_name (parser);
9349 	    if (t1 == NULL)
9350 	      {
9351 		expr.set_error ();
9352 		break;
9353 	      }
9354 	    if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9355 	      {
9356 		c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9357 		expr.set_error ();
9358 		break;
9359 	      }
9360 	    t2 = c_parser_type_name (parser);
9361 	    if (t2 == NULL)
9362 	      {
9363 		expr.set_error ();
9364 		break;
9365 	      }
9366 	    location_t close_paren_loc = c_parser_peek_token (parser)->location;
9367 	    parens.skip_until_found_close (parser);
9368 	    tree e1, e2;
9369 	    e1 = groktypename (t1, NULL, NULL);
9370 	    e2 = groktypename (t2, NULL, NULL);
9371 	    if (e1 == error_mark_node || e2 == error_mark_node)
9372 	      {
9373 		expr.set_error ();
9374 		break;
9375 	      }
9376 
9377 	    e1 = TYPE_MAIN_VARIANT (e1);
9378 	    e2 = TYPE_MAIN_VARIANT (e2);
9379 
9380 	    expr.value
9381 	      = comptypes (e1, e2) ? integer_one_node : integer_zero_node;
9382 	    set_c_expr_source_range (&expr, loc, close_paren_loc);
9383 	  }
9384 	  break;
9385 	case RID_BUILTIN_TGMATH:
9386 	  {
9387 	    vec<c_expr_t, va_gc> *cexpr_list;
9388 	    location_t close_paren_loc;
9389 
9390 	    c_parser_consume_token (parser);
9391 	    if (!c_parser_get_builtin_args (parser,
9392 					    "__builtin_tgmath",
9393 					    &cexpr_list, false,
9394 					    &close_paren_loc))
9395 	      {
9396 		expr.set_error ();
9397 		break;
9398 	      }
9399 
9400 	    if (vec_safe_length (cexpr_list) < 3)
9401 	      {
9402 		error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9403 		expr.set_error ();
9404 		break;
9405 	      }
9406 
9407 	    unsigned int i;
9408 	    c_expr_t *p;
9409 	    FOR_EACH_VEC_ELT (*cexpr_list, i, p)
9410 	      *p = convert_lvalue_to_rvalue (loc, *p, true, true);
9411 	    unsigned int nargs = check_tgmath_function (&(*cexpr_list)[0], 1);
9412 	    if (nargs == 0)
9413 	      {
9414 		expr.set_error ();
9415 		break;
9416 	      }
9417 	    if (vec_safe_length (cexpr_list) < nargs)
9418 	      {
9419 		error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9420 		expr.set_error ();
9421 		break;
9422 	      }
9423 	    unsigned int num_functions = vec_safe_length (cexpr_list) - nargs;
9424 	    if (num_functions < 2)
9425 	      {
9426 		error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9427 		expr.set_error ();
9428 		break;
9429 	      }
9430 
9431 	    /* The first NUM_FUNCTIONS expressions are the function
9432 	       pointers.  The remaining NARGS expressions are the
9433 	       arguments that are to be passed to one of those
9434 	       functions, chosen following <tgmath.h> rules.  */
9435 	    for (unsigned int j = 1; j < num_functions; j++)
9436 	      {
9437 		unsigned int this_nargs
9438 		  = check_tgmath_function (&(*cexpr_list)[j], j + 1);
9439 		if (this_nargs == 0)
9440 		  {
9441 		    expr.set_error ();
9442 		    goto out;
9443 		  }
9444 		if (this_nargs != nargs)
9445 		  {
9446 		    error_at ((*cexpr_list)[j].get_location (),
9447 			      "argument %u of %<__builtin_tgmath%> has "
9448 			      "wrong number of arguments", j + 1);
9449 		    expr.set_error ();
9450 		    goto out;
9451 		  }
9452 	      }
9453 
9454 	    /* The functions all have the same number of arguments.
9455 	       Determine whether arguments and return types vary in
9456 	       ways permitted for <tgmath.h> functions.  */
9457 	    /* The first entry in each of these vectors is for the
9458 	       return type, subsequent entries for parameter
9459 	       types.  */
9460 	    auto_vec<enum tgmath_parm_kind> parm_kind (nargs + 1);
9461 	    auto_vec<tree> parm_first (nargs + 1);
9462 	    auto_vec<bool> parm_complex (nargs + 1);
9463 	    auto_vec<bool> parm_varies (nargs + 1);
9464 	    tree first_type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[0].value));
9465 	    tree first_ret = TYPE_MAIN_VARIANT (TREE_TYPE (first_type));
9466 	    parm_first.quick_push (first_ret);
9467 	    parm_complex.quick_push (TREE_CODE (first_ret) == COMPLEX_TYPE);
9468 	    parm_varies.quick_push (false);
9469 	    function_args_iterator iter;
9470 	    tree t;
9471 	    unsigned int argpos;
9472 	    FOREACH_FUNCTION_ARGS (first_type, t, iter)
9473 	      {
9474 		if (t == void_type_node)
9475 		  break;
9476 		parm_first.quick_push (TYPE_MAIN_VARIANT (t));
9477 		parm_complex.quick_push (TREE_CODE (t) == COMPLEX_TYPE);
9478 		parm_varies.quick_push (false);
9479 	      }
9480 	    for (unsigned int j = 1; j < num_functions; j++)
9481 	      {
9482 		tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9483 		tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
9484 		if (ret != parm_first[0])
9485 		  {
9486 		    parm_varies[0] = true;
9487 		    if (!SCALAR_FLOAT_TYPE_P (parm_first[0])
9488 			&& !COMPLEX_FLOAT_TYPE_P (parm_first[0]))
9489 		      {
9490 			error_at ((*cexpr_list)[0].get_location (),
9491 				  "invalid type-generic return type for "
9492 				  "argument %u of %<__builtin_tgmath%>",
9493 				  1);
9494 			expr.set_error ();
9495 			goto out;
9496 		      }
9497 		    if (!SCALAR_FLOAT_TYPE_P (ret)
9498 			&& !COMPLEX_FLOAT_TYPE_P (ret))
9499 		      {
9500 			error_at ((*cexpr_list)[j].get_location (),
9501 				  "invalid type-generic return type for "
9502 				  "argument %u of %<__builtin_tgmath%>",
9503 				  j + 1);
9504 			expr.set_error ();
9505 			goto out;
9506 		      }
9507 		  }
9508 		if (TREE_CODE (ret) == COMPLEX_TYPE)
9509 		  parm_complex[0] = true;
9510 		argpos = 1;
9511 		FOREACH_FUNCTION_ARGS (type, t, iter)
9512 		  {
9513 		    if (t == void_type_node)
9514 		      break;
9515 		    t = TYPE_MAIN_VARIANT (t);
9516 		    if (t != parm_first[argpos])
9517 		      {
9518 			parm_varies[argpos] = true;
9519 			if (!SCALAR_FLOAT_TYPE_P (parm_first[argpos])
9520 			    && !COMPLEX_FLOAT_TYPE_P (parm_first[argpos]))
9521 			  {
9522 			    error_at ((*cexpr_list)[0].get_location (),
9523 				      "invalid type-generic type for "
9524 				      "argument %u of argument %u of "
9525 				      "%<__builtin_tgmath%>", argpos, 1);
9526 			    expr.set_error ();
9527 			    goto out;
9528 			  }
9529 			if (!SCALAR_FLOAT_TYPE_P (t)
9530 			    && !COMPLEX_FLOAT_TYPE_P (t))
9531 			  {
9532 			    error_at ((*cexpr_list)[j].get_location (),
9533 				      "invalid type-generic type for "
9534 				      "argument %u of argument %u of "
9535 				      "%<__builtin_tgmath%>", argpos, j + 1);
9536 			    expr.set_error ();
9537 			    goto out;
9538 			  }
9539 		      }
9540 		    if (TREE_CODE (t) == COMPLEX_TYPE)
9541 		      parm_complex[argpos] = true;
9542 		    argpos++;
9543 		  }
9544 	      }
9545 	    enum tgmath_parm_kind max_variation = tgmath_fixed;
9546 	    for (unsigned int j = 0; j <= nargs; j++)
9547 	      {
9548 		enum tgmath_parm_kind this_kind;
9549 		if (parm_varies[j])
9550 		  {
9551 		    if (parm_complex[j])
9552 		      max_variation = this_kind = tgmath_complex;
9553 		    else
9554 		      {
9555 			this_kind = tgmath_real;
9556 			if (max_variation != tgmath_complex)
9557 			  max_variation = tgmath_real;
9558 		      }
9559 		  }
9560 		else
9561 		  this_kind = tgmath_fixed;
9562 		parm_kind.quick_push (this_kind);
9563 	      }
9564 	    if (max_variation == tgmath_fixed)
9565 	      {
9566 		error_at (loc, "function arguments of %<__builtin_tgmath%> "
9567 			  "all have the same type");
9568 		expr.set_error ();
9569 		break;
9570 	      }
9571 
9572 	    /* Identify a parameter (not the return type) that varies,
9573 	       including with complex types if any variation includes
9574 	       complex types; there must be at least one such
9575 	       parameter.  */
9576 	    unsigned int tgarg = 0;
9577 	    for (unsigned int j = 1; j <= nargs; j++)
9578 	      if (parm_kind[j] == max_variation)
9579 		{
9580 		  tgarg = j;
9581 		  break;
9582 		}
9583 	    if (tgarg == 0)
9584 	      {
9585 		error_at (loc, "function arguments of %<__builtin_tgmath%> "
9586 			  "lack type-generic parameter");
9587 		expr.set_error ();
9588 		break;
9589 	      }
9590 
9591 	    /* Determine the type of the relevant parameter for each
9592 	       function.  */
9593 	    auto_vec<tree> tg_type (num_functions);
9594 	    for (unsigned int j = 0; j < num_functions; j++)
9595 	      {
9596 		tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9597 		argpos = 1;
9598 		FOREACH_FUNCTION_ARGS (type, t, iter)
9599 		  {
9600 		    if (argpos == tgarg)
9601 		      {
9602 			tg_type.quick_push (TYPE_MAIN_VARIANT (t));
9603 			break;
9604 		      }
9605 		    argpos++;
9606 		  }
9607 	      }
9608 
9609 	    /* Verify that the corresponding types are different for
9610 	       all the listed functions.  Also determine whether all
9611 	       the types are complex, whether all the types are
9612 	       standard or binary, and whether all the types are
9613 	       decimal.  */
9614 	    bool all_complex = true;
9615 	    bool all_binary = true;
9616 	    bool all_decimal = true;
9617 	    hash_set<tree> tg_types;
9618 	    FOR_EACH_VEC_ELT (tg_type, i, t)
9619 	      {
9620 		if (TREE_CODE (t) == COMPLEX_TYPE)
9621 		  all_decimal = false;
9622 		else
9623 		  {
9624 		    all_complex = false;
9625 		    if (DECIMAL_FLOAT_TYPE_P (t))
9626 		      all_binary = false;
9627 		    else
9628 		      all_decimal = false;
9629 		  }
9630 		if (tg_types.add (t))
9631 		  {
9632 		    error_at ((*cexpr_list)[i].get_location (),
9633 			      "duplicate type-generic parameter type for "
9634 			      "function argument %u of %<__builtin_tgmath%>",
9635 			      i + 1);
9636 		    expr.set_error ();
9637 		    goto out;
9638 		  }
9639 	      }
9640 
9641 	    /* Verify that other parameters and the return type whose
9642 	       types vary have their types varying in the correct
9643 	       way.  */
9644 	    for (unsigned int j = 0; j < num_functions; j++)
9645 	      {
9646 		tree exp_type = tg_type[j];
9647 		tree exp_real_type = exp_type;
9648 		if (TREE_CODE (exp_type) == COMPLEX_TYPE)
9649 		  exp_real_type = TREE_TYPE (exp_type);
9650 		tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9651 		tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
9652 		if ((parm_kind[0] == tgmath_complex && ret != exp_type)
9653 		    || (parm_kind[0] == tgmath_real && ret != exp_real_type))
9654 		  {
9655 		    error_at ((*cexpr_list)[j].get_location (),
9656 			      "bad return type for function argument %u "
9657 			      "of %<__builtin_tgmath%>", j + 1);
9658 		    expr.set_error ();
9659 		    goto out;
9660 		  }
9661 		argpos = 1;
9662 		FOREACH_FUNCTION_ARGS (type, t, iter)
9663 		  {
9664 		    if (t == void_type_node)
9665 		      break;
9666 		    t = TYPE_MAIN_VARIANT (t);
9667 		    if ((parm_kind[argpos] == tgmath_complex
9668 			 && t != exp_type)
9669 			|| (parm_kind[argpos] == tgmath_real
9670 			    && t != exp_real_type))
9671 		      {
9672 			error_at ((*cexpr_list)[j].get_location (),
9673 				  "bad type for argument %u of "
9674 				  "function argument %u of "
9675 				  "%<__builtin_tgmath%>", argpos, j + 1);
9676 			expr.set_error ();
9677 			goto out;
9678 		      }
9679 		    argpos++;
9680 		  }
9681 	      }
9682 
9683 	    /* The functions listed are a valid set of functions for a
9684 	       <tgmath.h> macro to select between.  Identify the
9685 	       matching function, if any.  First, the argument types
9686 	       must be combined following <tgmath.h> rules.  Integer
9687 	       types are treated as _Decimal64 if any type-generic
9688 	       argument is decimal, or if the only alternatives for
9689 	       type-generic arguments are of decimal types, and are
9690 	       otherwise treated as double (or _Complex double for
9691 	       complex integer types, or _Float64 or _Complex _Float64
9692 	       if all the return types are the same _FloatN or
9693 	       _FloatNx type).  After that adjustment, types are
9694 	       combined following the usual arithmetic conversions.
9695 	       If the function only accepts complex arguments, a
9696 	       complex type is produced.  */
9697 	    bool arg_complex = all_complex;
9698 	    bool arg_binary = all_binary;
9699 	    bool arg_int_decimal = all_decimal;
9700 	    for (unsigned int j = 1; j <= nargs; j++)
9701 	      {
9702 		if (parm_kind[j] == tgmath_fixed)
9703 		  continue;
9704 		c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
9705 		tree type = TREE_TYPE (ce->value);
9706 		if (!INTEGRAL_TYPE_P (type)
9707 		    && !SCALAR_FLOAT_TYPE_P (type)
9708 		    && TREE_CODE (type) != COMPLEX_TYPE)
9709 		  {
9710 		    error_at (ce->get_location (),
9711 			      "invalid type of argument %u of type-generic "
9712 			      "function", j);
9713 		    expr.set_error ();
9714 		    goto out;
9715 		  }
9716 		if (DECIMAL_FLOAT_TYPE_P (type))
9717 		  {
9718 		    arg_int_decimal = true;
9719 		    if (all_complex)
9720 		      {
9721 			error_at (ce->get_location (),
9722 				  "decimal floating-point argument %u to "
9723 				  "complex-only type-generic function", j);
9724 			expr.set_error ();
9725 			goto out;
9726 		      }
9727 		    else if (all_binary)
9728 		      {
9729 			error_at (ce->get_location (),
9730 				  "decimal floating-point argument %u to "
9731 				  "binary-only type-generic function", j);
9732 			expr.set_error ();
9733 			goto out;
9734 		      }
9735 		    else if (arg_complex)
9736 		      {
9737 			error_at (ce->get_location (),
9738 				  "both complex and decimal floating-point "
9739 				  "arguments to type-generic function");
9740 			expr.set_error ();
9741 			goto out;
9742 		      }
9743 		    else if (arg_binary)
9744 		      {
9745 			error_at (ce->get_location (),
9746 				  "both binary and decimal floating-point "
9747 				  "arguments to type-generic function");
9748 			expr.set_error ();
9749 			goto out;
9750 		      }
9751 		  }
9752 		else if (TREE_CODE (type) == COMPLEX_TYPE)
9753 		  {
9754 		    arg_complex = true;
9755 		    if (COMPLEX_FLOAT_TYPE_P (type))
9756 		      arg_binary = true;
9757 		    if (all_decimal)
9758 		      {
9759 			error_at (ce->get_location (),
9760 				  "complex argument %u to "
9761 				  "decimal-only type-generic function", j);
9762 			expr.set_error ();
9763 			goto out;
9764 		      }
9765 		    else if (arg_int_decimal)
9766 		      {
9767 			error_at (ce->get_location (),
9768 				  "both complex and decimal floating-point "
9769 				  "arguments to type-generic function");
9770 			expr.set_error ();
9771 			goto out;
9772 		      }
9773 		  }
9774 		else if (SCALAR_FLOAT_TYPE_P (type))
9775 		  {
9776 		    arg_binary = true;
9777 		    if (all_decimal)
9778 		      {
9779 			error_at (ce->get_location (),
9780 				  "binary argument %u to "
9781 				  "decimal-only type-generic function", j);
9782 			expr.set_error ();
9783 			goto out;
9784 		      }
9785 		    else if (arg_int_decimal)
9786 		      {
9787 			error_at (ce->get_location (),
9788 				  "both binary and decimal floating-point "
9789 				  "arguments to type-generic function");
9790 			expr.set_error ();
9791 			goto out;
9792 		      }
9793 		  }
9794 	      }
9795 	    /* For a macro rounding its result to a narrower type, map
9796 	       integer types to _Float64 not double if the return type
9797 	       is a _FloatN or _FloatNx type.  */
9798 	    bool arg_int_float64 = false;
9799 	    if (parm_kind[0] == tgmath_fixed
9800 		&& SCALAR_FLOAT_TYPE_P (parm_first[0])
9801 		&& float64_type_node != NULL_TREE)
9802 	      for (unsigned int j = 0; j < NUM_FLOATN_NX_TYPES; j++)
9803 		if (parm_first[0] == FLOATN_TYPE_NODE (j))
9804 		  {
9805 		    arg_int_float64 = true;
9806 		    break;
9807 		  }
9808 	    tree arg_real = NULL_TREE;
9809 	    for (unsigned int j = 1; j <= nargs; j++)
9810 	      {
9811 		if (parm_kind[j] == tgmath_fixed)
9812 		  continue;
9813 		c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
9814 		tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ce->value));
9815 		if (TREE_CODE (type) == COMPLEX_TYPE)
9816 		  type = TREE_TYPE (type);
9817 		if (INTEGRAL_TYPE_P (type))
9818 		  type = (arg_int_decimal
9819 			  ? dfloat64_type_node
9820 			  : arg_int_float64
9821 			  ? float64_type_node
9822 			  : double_type_node);
9823 		if (arg_real == NULL_TREE)
9824 		  arg_real = type;
9825 		else
9826 		  arg_real = common_type (arg_real, type);
9827 		if (arg_real == error_mark_node)
9828 		  {
9829 		    expr.set_error ();
9830 		    goto out;
9831 		  }
9832 	      }
9833 	    tree arg_type = (arg_complex
9834 			     ? build_complex_type (arg_real)
9835 			     : arg_real);
9836 
9837 	    /* Look for a function to call with type-generic parameter
9838 	       type ARG_TYPE.  */
9839 	    c_expr_t *fn = NULL;
9840 	    for (unsigned int j = 0; j < num_functions; j++)
9841 	      {
9842 		if (tg_type[j] == arg_type)
9843 		  {
9844 		    fn = &(*cexpr_list)[j];
9845 		    break;
9846 		  }
9847 	      }
9848 	    if (fn == NULL
9849 		&& parm_kind[0] == tgmath_fixed
9850 		&& SCALAR_FLOAT_TYPE_P (parm_first[0]))
9851 	      {
9852 		/* Presume this is a macro that rounds its result to a
9853 		   narrower type, and look for the first function with
9854 		   at least the range and precision of the argument
9855 		   type.  */
9856 		for (unsigned int j = 0; j < num_functions; j++)
9857 		  {
9858 		    if (arg_complex
9859 			!= (TREE_CODE (tg_type[j]) == COMPLEX_TYPE))
9860 		      continue;
9861 		    tree real_tg_type = (arg_complex
9862 					 ? TREE_TYPE (tg_type[j])
9863 					 : tg_type[j]);
9864 		    if (DECIMAL_FLOAT_TYPE_P (arg_real)
9865 			!= DECIMAL_FLOAT_TYPE_P (real_tg_type))
9866 		      continue;
9867 		    scalar_float_mode arg_mode
9868 		      = SCALAR_FLOAT_TYPE_MODE (arg_real);
9869 		    scalar_float_mode tg_mode
9870 		      = SCALAR_FLOAT_TYPE_MODE (real_tg_type);
9871 		    const real_format *arg_fmt = REAL_MODE_FORMAT (arg_mode);
9872 		    const real_format *tg_fmt = REAL_MODE_FORMAT (tg_mode);
9873 		    if (arg_fmt->b == tg_fmt->b
9874 			&& arg_fmt->p <= tg_fmt->p
9875 			&& arg_fmt->emax <= tg_fmt->emax
9876 			&& (arg_fmt->emin - arg_fmt->p
9877 			    >= tg_fmt->emin - tg_fmt->p))
9878 		      {
9879 			fn = &(*cexpr_list)[j];
9880 			break;
9881 		      }
9882 		  }
9883 	      }
9884 	    if (fn == NULL)
9885 	      {
9886 		error_at (loc, "no matching function for type-generic call");
9887 		expr.set_error ();
9888 		break;
9889 	      }
9890 
9891 	    /* Construct a call to FN.  */
9892 	    vec<tree, va_gc> *args;
9893 	    vec_alloc (args, nargs);
9894 	    vec<tree, va_gc> *origtypes;
9895 	    vec_alloc (origtypes, nargs);
9896 	    auto_vec<location_t> arg_loc (nargs);
9897 	    for (unsigned int j = 0; j < nargs; j++)
9898 	      {
9899 		c_expr_t *ce = &(*cexpr_list)[num_functions + j];
9900 		args->quick_push (ce->value);
9901 		arg_loc.quick_push (ce->get_location ());
9902 		origtypes->quick_push (ce->original_type);
9903 	      }
9904 	    expr.value = c_build_function_call_vec (loc, arg_loc, fn->value,
9905 						    args, origtypes);
9906 	    set_c_expr_source_range (&expr, loc, close_paren_loc);
9907 	    break;
9908 	  }
9909 	case RID_BUILTIN_CALL_WITH_STATIC_CHAIN:
9910 	  {
9911 	    vec<c_expr_t, va_gc> *cexpr_list;
9912 	    c_expr_t *e2_p;
9913 	    tree chain_value;
9914 	    location_t close_paren_loc;
9915 
9916 	    c_parser_consume_token (parser);
9917 	    if (!c_parser_get_builtin_args (parser,
9918 					    "__builtin_call_with_static_chain",
9919 					    &cexpr_list, false,
9920 					    &close_paren_loc))
9921 	      {
9922 		expr.set_error ();
9923 		break;
9924 	      }
9925 	    if (vec_safe_length (cexpr_list) != 2)
9926 	      {
9927 		error_at (loc, "wrong number of arguments to "
9928 			       "%<__builtin_call_with_static_chain%>");
9929 		expr.set_error ();
9930 		break;
9931 	      }
9932 
9933 	    expr = (*cexpr_list)[0];
9934 	    e2_p = &(*cexpr_list)[1];
9935 	    *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
9936 	    chain_value = e2_p->value;
9937 	    mark_exp_read (chain_value);
9938 
9939 	    if (TREE_CODE (expr.value) != CALL_EXPR)
9940 	      error_at (loc, "first argument to "
9941 			"%<__builtin_call_with_static_chain%> "
9942 			"must be a call expression");
9943 	    else if (TREE_CODE (TREE_TYPE (chain_value)) != POINTER_TYPE)
9944 	      error_at (loc, "second argument to "
9945 			"%<__builtin_call_with_static_chain%> "
9946 			"must be a pointer type");
9947 	    else
9948 	      CALL_EXPR_STATIC_CHAIN (expr.value) = chain_value;
9949 	    set_c_expr_source_range (&expr, loc, close_paren_loc);
9950 	    break;
9951 	  }
9952 	case RID_BUILTIN_COMPLEX:
9953 	  {
9954 	    vec<c_expr_t, va_gc> *cexpr_list;
9955 	    c_expr_t *e1_p, *e2_p;
9956 	    location_t close_paren_loc;
9957 
9958 	    c_parser_consume_token (parser);
9959 	    if (!c_parser_get_builtin_args (parser,
9960 					    "__builtin_complex",
9961 					    &cexpr_list, false,
9962 					    &close_paren_loc))
9963 	      {
9964 		expr.set_error ();
9965 		break;
9966 	      }
9967 
9968 	    if (vec_safe_length (cexpr_list) != 2)
9969 	      {
9970 		error_at (loc, "wrong number of arguments to "
9971 			       "%<__builtin_complex%>");
9972 		expr.set_error ();
9973 		break;
9974 	      }
9975 
9976 	    e1_p = &(*cexpr_list)[0];
9977 	    e2_p = &(*cexpr_list)[1];
9978 
9979 	    *e1_p = convert_lvalue_to_rvalue (loc, *e1_p, true, true);
9980 	    if (TREE_CODE (e1_p->value) == EXCESS_PRECISION_EXPR)
9981 	      e1_p->value = convert (TREE_TYPE (e1_p->value),
9982 				     TREE_OPERAND (e1_p->value, 0));
9983 	    *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
9984 	    if (TREE_CODE (e2_p->value) == EXCESS_PRECISION_EXPR)
9985 	      e2_p->value = convert (TREE_TYPE (e2_p->value),
9986 				     TREE_OPERAND (e2_p->value, 0));
9987 	    if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
9988 		|| DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
9989 		|| !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p->value))
9990 		|| DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p->value)))
9991 	      {
9992 		error_at (loc, "%<__builtin_complex%> operand "
9993 			  "not of real binary floating-point type");
9994 		expr.set_error ();
9995 		break;
9996 	      }
9997 	    if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p->value))
9998 		!= TYPE_MAIN_VARIANT (TREE_TYPE (e2_p->value)))
9999 	      {
10000 		error_at (loc,
10001 			  "%<__builtin_complex%> operands of different types");
10002 		expr.set_error ();
10003 		break;
10004 	      }
10005 	    pedwarn_c90 (loc, OPT_Wpedantic,
10006 			 "ISO C90 does not support complex types");
10007 	    expr.value = build2_loc (loc, COMPLEX_EXPR,
10008 				     build_complex_type
10009 				     (TYPE_MAIN_VARIANT
10010 				      (TREE_TYPE (e1_p->value))),
10011 				     e1_p->value, e2_p->value);
10012 	    set_c_expr_source_range (&expr, loc, close_paren_loc);
10013 	    break;
10014 	  }
10015 	case RID_BUILTIN_SHUFFLE:
10016 	  {
10017 	    vec<c_expr_t, va_gc> *cexpr_list;
10018 	    unsigned int i;
10019 	    c_expr_t *p;
10020 	    location_t close_paren_loc;
10021 
10022 	    c_parser_consume_token (parser);
10023 	    if (!c_parser_get_builtin_args (parser,
10024 					    "__builtin_shuffle",
10025 					    &cexpr_list, false,
10026 					    &close_paren_loc))
10027 	      {
10028 		expr.set_error ();
10029 		break;
10030 	      }
10031 
10032 	    FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
10033 	      *p = convert_lvalue_to_rvalue (loc, *p, true, true);
10034 
10035 	    if (vec_safe_length (cexpr_list) == 2)
10036 	      expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
10037 						  NULL_TREE,
10038 						  (*cexpr_list)[1].value);
10039 
10040 	    else if (vec_safe_length (cexpr_list) == 3)
10041 	      expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
10042 						  (*cexpr_list)[1].value,
10043 						  (*cexpr_list)[2].value);
10044 	    else
10045 	      {
10046 		error_at (loc, "wrong number of arguments to "
10047 			       "%<__builtin_shuffle%>");
10048 		expr.set_error ();
10049 	      }
10050 	    set_c_expr_source_range (&expr, loc, close_paren_loc);
10051 	    break;
10052 	  }
10053 	case RID_BUILTIN_CONVERTVECTOR:
10054 	  {
10055 	    location_t start_loc = loc;
10056 	    c_parser_consume_token (parser);
10057 	    matching_parens parens;
10058 	    if (!parens.require_open (parser))
10059 	      {
10060 		expr.set_error ();
10061 		break;
10062 	      }
10063 	    e1 = c_parser_expr_no_commas (parser, NULL);
10064 	    mark_exp_read (e1.value);
10065 	    if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10066 	      {
10067 		c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10068 		expr.set_error ();
10069 		break;
10070 	      }
10071 	    loc = c_parser_peek_token (parser)->location;
10072 	    t1 = c_parser_type_name (parser);
10073 	    location_t end_loc = c_parser_peek_token (parser)->get_finish ();
10074 	    c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10075 				       "expected %<)%>");
10076 	    if (t1 == NULL)
10077 	      expr.set_error ();
10078 	    else
10079 	      {
10080 		tree type_expr = NULL_TREE;
10081 		expr.value = c_build_vec_convert (start_loc, e1.value, loc,
10082 						  groktypename (t1, &type_expr,
10083 								NULL));
10084 		set_c_expr_source_range (&expr, start_loc, end_loc);
10085 	      }
10086 	  }
10087 	  break;
10088 	case RID_AT_SELECTOR:
10089 	  {
10090 	    gcc_assert (c_dialect_objc ());
10091 	    c_parser_consume_token (parser);
10092 	    matching_parens parens;
10093 	    if (!parens.require_open (parser))
10094 	      {
10095 		expr.set_error ();
10096 		break;
10097 	      }
10098 	    tree sel = c_parser_objc_selector_arg (parser);
10099 	    location_t close_loc = c_parser_peek_token (parser)->location;
10100 	    parens.skip_until_found_close (parser);
10101 	    expr.value = objc_build_selector_expr (loc, sel);
10102 	    set_c_expr_source_range (&expr, loc, close_loc);
10103 	  }
10104 	  break;
10105 	case RID_AT_PROTOCOL:
10106 	  {
10107 	    gcc_assert (c_dialect_objc ());
10108 	    c_parser_consume_token (parser);
10109 	    matching_parens parens;
10110 	    if (!parens.require_open (parser))
10111 	      {
10112 		expr.set_error ();
10113 		break;
10114 	      }
10115 	    if (c_parser_next_token_is_not (parser, CPP_NAME))
10116 	      {
10117 		c_parser_error (parser, "expected identifier");
10118 		c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10119 		expr.set_error ();
10120 		break;
10121 	      }
10122 	    tree id = c_parser_peek_token (parser)->value;
10123 	    c_parser_consume_token (parser);
10124 	    location_t close_loc = c_parser_peek_token (parser)->location;
10125 	    parens.skip_until_found_close (parser);
10126 	    expr.value = objc_build_protocol_expr (id);
10127 	    set_c_expr_source_range (&expr, loc, close_loc);
10128 	  }
10129 	  break;
10130 	case RID_AT_ENCODE:
10131 	  {
10132 	    /* Extension to support C-structures in the archiver.  */
10133 	    gcc_assert (c_dialect_objc ());
10134 	    c_parser_consume_token (parser);
10135 	    matching_parens parens;
10136 	    if (!parens.require_open (parser))
10137 	      {
10138 		expr.set_error ();
10139 		break;
10140 	      }
10141 	    t1 = c_parser_type_name (parser);
10142 	    if (t1 == NULL)
10143 	      {
10144 		expr.set_error ();
10145 		c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10146 		break;
10147 	      }
10148 	    location_t close_loc = c_parser_peek_token (parser)->location;
10149 	    parens.skip_until_found_close (parser);
10150 	    tree type = groktypename (t1, NULL, NULL);
10151 	    expr.value = objc_build_encode_expr (type);
10152 	    set_c_expr_source_range (&expr, loc, close_loc);
10153 	  }
10154 	  break;
10155 	case RID_GENERIC:
10156 	  expr = c_parser_generic_selection (parser);
10157 	  break;
10158 	default:
10159 	  c_parser_error (parser, "expected expression");
10160 	  expr.set_error ();
10161 	  break;
10162 	}
10163       break;
10164     case CPP_OPEN_SQUARE:
10165       if (c_dialect_objc ())
10166 	{
10167 	  tree receiver, args;
10168 	  c_parser_consume_token (parser);
10169 	  receiver = c_parser_objc_receiver (parser);
10170 	  args = c_parser_objc_message_args (parser);
10171 	  location_t close_loc = c_parser_peek_token (parser)->location;
10172 	  c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10173 				     "expected %<]%>");
10174 	  expr.value = objc_build_message_expr (receiver, args);
10175 	  set_c_expr_source_range (&expr, loc, close_loc);
10176 	  break;
10177 	}
10178       /* Else fall through to report error.  */
10179       /* FALLTHRU */
10180     default:
10181       c_parser_error (parser, "expected expression");
10182       expr.set_error ();
10183       break;
10184     }
10185  out:
10186   return c_parser_postfix_expression_after_primary
10187     (parser, EXPR_LOC_OR_LOC (expr.value, loc), expr);
10188 }
10189 
10190 /* Parse a postfix expression after a parenthesized type name: the
10191    brace-enclosed initializer of a compound literal, possibly followed
10192    by some postfix operators.  This is separate because it is not
10193    possible to tell until after the type name whether a cast
10194    expression has a cast or a compound literal, or whether the operand
10195    of sizeof is a parenthesized type name or starts with a compound
10196    literal.  TYPE_LOC is the location where TYPE_NAME starts--the
10197    location of the first token after the parentheses around the type
10198    name.  */
10199 
10200 static struct c_expr
c_parser_postfix_expression_after_paren_type(c_parser * parser,struct c_type_name * type_name,location_t type_loc)10201 c_parser_postfix_expression_after_paren_type (c_parser *parser,
10202 					      struct c_type_name *type_name,
10203 					      location_t type_loc)
10204 {
10205   tree type;
10206   struct c_expr init;
10207   bool non_const;
10208   struct c_expr expr;
10209   location_t start_loc;
10210   tree type_expr = NULL_TREE;
10211   bool type_expr_const = true;
10212   check_compound_literal_type (type_loc, type_name);
10213   rich_location richloc (line_table, type_loc);
10214   start_init (NULL_TREE, NULL, 0, &richloc);
10215   type = groktypename (type_name, &type_expr, &type_expr_const);
10216   start_loc = c_parser_peek_token (parser)->location;
10217   if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type))
10218     {
10219       error_at (type_loc, "compound literal has variable size");
10220       type = error_mark_node;
10221     }
10222   init = c_parser_braced_init (parser, type, false, NULL);
10223   finish_init ();
10224   maybe_warn_string_init (type_loc, type, init);
10225 
10226   if (type != error_mark_node
10227       && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type))
10228       && current_function_decl)
10229     {
10230       error ("compound literal qualified by address-space qualifier");
10231       type = error_mark_node;
10232     }
10233 
10234   pedwarn_c90 (start_loc, OPT_Wpedantic, "ISO C90 forbids compound literals");
10235   non_const = ((init.value && TREE_CODE (init.value) == CONSTRUCTOR)
10236 	       ? CONSTRUCTOR_NON_CONST (init.value)
10237 	       : init.original_code == C_MAYBE_CONST_EXPR);
10238   non_const |= !type_expr_const;
10239   unsigned int alignas_align = 0;
10240   if (type != error_mark_node
10241       && type_name->specs->align_log != -1)
10242     {
10243       alignas_align = 1U << type_name->specs->align_log;
10244       if (alignas_align < min_align_of_type (type))
10245 	{
10246 	  error_at (type_name->specs->locations[cdw_alignas],
10247 		    "%<_Alignas%> specifiers cannot reduce "
10248 		    "alignment of compound literal");
10249 	  alignas_align = 0;
10250 	}
10251     }
10252   expr.value = build_compound_literal (start_loc, type, init.value, non_const,
10253 				       alignas_align);
10254   set_c_expr_source_range (&expr, init.src_range);
10255   expr.original_code = ERROR_MARK;
10256   expr.original_type = NULL;
10257   if (type != error_mark_node
10258       && expr.value != error_mark_node
10259       && type_expr)
10260     {
10261       if (TREE_CODE (expr.value) == C_MAYBE_CONST_EXPR)
10262 	{
10263 	  gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr.value) == NULL_TREE);
10264 	  C_MAYBE_CONST_EXPR_PRE (expr.value) = type_expr;
10265 	}
10266       else
10267 	{
10268 	  gcc_assert (!non_const);
10269 	  expr.value = build2 (C_MAYBE_CONST_EXPR, type,
10270 			       type_expr, expr.value);
10271 	}
10272     }
10273   return c_parser_postfix_expression_after_primary (parser, start_loc, expr);
10274 }
10275 
10276 /* Callback function for sizeof_pointer_memaccess_warning to compare
10277    types.  */
10278 
10279 static bool
sizeof_ptr_memacc_comptypes(tree type1,tree type2)10280 sizeof_ptr_memacc_comptypes (tree type1, tree type2)
10281 {
10282   return comptypes (type1, type2) == 1;
10283 }
10284 
10285 /* Warn for patterns where abs-like function appears to be used incorrectly,
10286    gracefully ignore any non-abs-like function.  The warning location should
10287    be LOC.  FNDECL is the declaration of called function, it must be a
10288    BUILT_IN_NORMAL function.  ARG is the first and only argument of the
10289    call.  */
10290 
10291 static void
warn_for_abs(location_t loc,tree fndecl,tree arg)10292 warn_for_abs (location_t loc, tree fndecl, tree arg)
10293 {
10294   /* Avoid warning in unreachable subexpressions.  */
10295   if (c_inhibit_evaluation_warnings)
10296     return;
10297 
10298   tree atype = TREE_TYPE (arg);
10299 
10300   /* Casts from pointers (and thus arrays and fndecls) will generate
10301      -Wint-conversion warnings.  Most other wrong types hopefully lead to type
10302      mismatch errors.  TODO: Think about what to do with FIXED_POINT_TYPE_P
10303      types and possibly other exotic types.  */
10304   if (!INTEGRAL_TYPE_P (atype)
10305       && !SCALAR_FLOAT_TYPE_P (atype)
10306       && TREE_CODE (atype) != COMPLEX_TYPE)
10307     return;
10308 
10309   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10310 
10311   switch (fcode)
10312     {
10313     case BUILT_IN_ABS:
10314     case BUILT_IN_LABS:
10315     case BUILT_IN_LLABS:
10316     case BUILT_IN_IMAXABS:
10317       if (!INTEGRAL_TYPE_P (atype))
10318 	{
10319 	  if (SCALAR_FLOAT_TYPE_P (atype))
10320 	    warning_at (loc, OPT_Wabsolute_value,
10321 			"using integer absolute value function %qD when "
10322 			"argument is of floating-point type %qT",
10323 			fndecl, atype);
10324 	  else if (TREE_CODE (atype) == COMPLEX_TYPE)
10325 	    warning_at (loc, OPT_Wabsolute_value,
10326 			"using integer absolute value function %qD when "
10327 			"argument is of complex type %qT", fndecl, atype);
10328 	  else
10329 	    gcc_unreachable ();
10330 	  return;
10331 	}
10332       if (TYPE_UNSIGNED (atype))
10333 	warning_at (loc, OPT_Wabsolute_value,
10334 		    "taking the absolute value of unsigned type %qT "
10335 		    "has no effect", atype);
10336       break;
10337 
10338     CASE_FLT_FN (BUILT_IN_FABS):
10339     CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS):
10340       if (!SCALAR_FLOAT_TYPE_P (atype)
10341 	  || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype)))
10342 	{
10343 	  if (INTEGRAL_TYPE_P (atype))
10344 	    warning_at (loc, OPT_Wabsolute_value,
10345 			"using floating-point absolute value function %qD "
10346 			"when argument is of integer type %qT", fndecl, atype);
10347 	  else if (DECIMAL_FLOAT_TYPE_P (atype))
10348 	    warning_at (loc, OPT_Wabsolute_value,
10349 			"using floating-point absolute value function %qD "
10350 			"when argument is of decimal floating-point type %qT",
10351 			fndecl, atype);
10352 	  else if (TREE_CODE (atype) == COMPLEX_TYPE)
10353 	    warning_at (loc, OPT_Wabsolute_value,
10354 			"using floating-point absolute value function %qD when "
10355 			"argument is of complex type %qT", fndecl, atype);
10356 	  else
10357 	    gcc_unreachable ();
10358 	  return;
10359 	}
10360       break;
10361 
10362     CASE_FLT_FN (BUILT_IN_CABS):
10363       if (TREE_CODE (atype) != COMPLEX_TYPE)
10364 	{
10365 	  if (INTEGRAL_TYPE_P (atype))
10366 	    warning_at (loc, OPT_Wabsolute_value,
10367 			"using complex absolute value function %qD when "
10368 			"argument is of integer type %qT", fndecl, atype);
10369 	  else if (SCALAR_FLOAT_TYPE_P (atype))
10370 	    warning_at (loc, OPT_Wabsolute_value,
10371 			"using complex absolute value function %qD when "
10372 			"argument is of floating-point type %qT",
10373 			fndecl, atype);
10374 	  else
10375 	    gcc_unreachable ();
10376 
10377 	  return;
10378 	}
10379       break;
10380 
10381     case BUILT_IN_FABSD32:
10382     case BUILT_IN_FABSD64:
10383     case BUILT_IN_FABSD128:
10384       if (!DECIMAL_FLOAT_TYPE_P (atype))
10385 	{
10386 	  if (INTEGRAL_TYPE_P (atype))
10387 	    warning_at (loc, OPT_Wabsolute_value,
10388 			"using decimal floating-point absolute value "
10389 			"function %qD when argument is of integer type %qT",
10390 			fndecl, atype);
10391 	  else if (SCALAR_FLOAT_TYPE_P (atype))
10392 	    warning_at (loc, OPT_Wabsolute_value,
10393 			"using decimal floating-point absolute value "
10394 			"function %qD when argument is of floating-point "
10395 			"type %qT", fndecl, atype);
10396 	  else if (TREE_CODE (atype) == COMPLEX_TYPE)
10397 	    warning_at (loc, OPT_Wabsolute_value,
10398 			"using decimal floating-point absolute value "
10399 			"function %qD when argument is of complex type %qT",
10400 			fndecl, atype);
10401 	  else
10402 	    gcc_unreachable ();
10403 	  return;
10404 	}
10405       break;
10406 
10407     default:
10408       return;
10409     }
10410 
10411   if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
10412     return;
10413 
10414   tree ftype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
10415   if (TREE_CODE (atype) == COMPLEX_TYPE)
10416     {
10417       gcc_assert (TREE_CODE (ftype) == COMPLEX_TYPE);
10418       atype = TREE_TYPE (atype);
10419       ftype = TREE_TYPE (ftype);
10420     }
10421 
10422   if (TYPE_PRECISION (ftype) < TYPE_PRECISION (atype))
10423     warning_at (loc, OPT_Wabsolute_value,
10424 		"absolute value function %qD given an argument of type %qT "
10425 		"but has parameter of type %qT which may cause truncation "
10426 		"of value", fndecl, atype, ftype);
10427 }
10428 
10429 
10430 /* Parse a postfix expression after the initial primary or compound
10431    literal; that is, parse a series of postfix operators.
10432 
10433    EXPR_LOC is the location of the primary expression.  */
10434 
10435 static struct c_expr
c_parser_postfix_expression_after_primary(c_parser * parser,location_t expr_loc,struct c_expr expr)10436 c_parser_postfix_expression_after_primary (c_parser *parser,
10437 					   location_t expr_loc,
10438 					   struct c_expr expr)
10439 {
10440   struct c_expr orig_expr;
10441   tree ident, idx;
10442   location_t sizeof_arg_loc[3], comp_loc;
10443   tree sizeof_arg[3];
10444   unsigned int literal_zero_mask;
10445   unsigned int i;
10446   vec<tree, va_gc> *exprlist;
10447   vec<tree, va_gc> *origtypes = NULL;
10448   vec<location_t> arg_loc = vNULL;
10449   location_t start;
10450   location_t finish;
10451 
10452   while (true)
10453     {
10454       location_t op_loc = c_parser_peek_token (parser)->location;
10455       switch (c_parser_peek_token (parser)->type)
10456 	{
10457 	case CPP_OPEN_SQUARE:
10458 	  /* Array reference.  */
10459 	  c_parser_consume_token (parser);
10460 	  idx = c_parser_expression (parser).value;
10461 	  c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10462 				     "expected %<]%>");
10463 	  start = expr.get_start ();
10464 	  finish = parser->tokens_buf[0].location;
10465 	  expr.value = build_array_ref (op_loc, expr.value, idx);
10466 	  set_c_expr_source_range (&expr, start, finish);
10467 	  expr.original_code = ERROR_MARK;
10468 	  expr.original_type = NULL;
10469 	  break;
10470 	case CPP_OPEN_PAREN:
10471 	  /* Function call.  */
10472 	  c_parser_consume_token (parser);
10473 	  for (i = 0; i < 3; i++)
10474 	    {
10475 	      sizeof_arg[i] = NULL_TREE;
10476 	      sizeof_arg_loc[i] = UNKNOWN_LOCATION;
10477 	    }
10478 	  literal_zero_mask = 0;
10479 	  if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10480 	    exprlist = NULL;
10481 	  else
10482 	    exprlist = c_parser_expr_list (parser, true, false, &origtypes,
10483 					   sizeof_arg_loc, sizeof_arg,
10484 					   &arg_loc, &literal_zero_mask);
10485 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10486 				     "expected %<)%>");
10487 	  orig_expr = expr;
10488 	  mark_exp_read (expr.value);
10489 	  if (warn_sizeof_pointer_memaccess)
10490 	    sizeof_pointer_memaccess_warning (sizeof_arg_loc,
10491 					      expr.value, exprlist,
10492 					      sizeof_arg,
10493 					      sizeof_ptr_memacc_comptypes);
10494 	  if (TREE_CODE (expr.value) == FUNCTION_DECL)
10495 	    {
10496 	      if (fndecl_built_in_p (expr.value, BUILT_IN_MEMSET)
10497 		  && vec_safe_length (exprlist) == 3)
10498 		{
10499 		  tree arg0 = (*exprlist)[0];
10500 		  tree arg2 = (*exprlist)[2];
10501 		  warn_for_memset (expr_loc, arg0, arg2, literal_zero_mask);
10502 		}
10503 	      if (warn_absolute_value
10504 		  && fndecl_built_in_p (expr.value, BUILT_IN_NORMAL)
10505 		  && vec_safe_length (exprlist) == 1)
10506 		warn_for_abs (expr_loc, expr.value, (*exprlist)[0]);
10507 	    }
10508 
10509 	  start = expr.get_start ();
10510 	  finish = parser->tokens_buf[0].get_finish ();
10511 	  expr.value
10512 	    = c_build_function_call_vec (expr_loc, arg_loc, expr.value,
10513 					 exprlist, origtypes);
10514 	  set_c_expr_source_range (&expr, start, finish);
10515 
10516 	  expr.original_code = ERROR_MARK;
10517 	  if (TREE_CODE (expr.value) == INTEGER_CST
10518 	      && TREE_CODE (orig_expr.value) == FUNCTION_DECL
10519 	      && fndecl_built_in_p (orig_expr.value, BUILT_IN_CONSTANT_P))
10520 	    expr.original_code = C_MAYBE_CONST_EXPR;
10521 	  expr.original_type = NULL;
10522 	  if (exprlist)
10523 	    {
10524 	      release_tree_vector (exprlist);
10525 	      release_tree_vector (origtypes);
10526 	    }
10527 	  arg_loc.release ();
10528 	  break;
10529 	case CPP_DOT:
10530 	  /* Structure element reference.  */
10531 	  c_parser_consume_token (parser);
10532 	  expr = default_function_array_conversion (expr_loc, expr);
10533 	  if (c_parser_next_token_is (parser, CPP_NAME))
10534 	    {
10535 	      c_token *comp_tok = c_parser_peek_token (parser);
10536 	      ident = comp_tok->value;
10537 	      comp_loc = comp_tok->location;
10538 	    }
10539 	  else
10540 	    {
10541 	      c_parser_error (parser, "expected identifier");
10542 	      expr.set_error ();
10543 	      expr.original_code = ERROR_MARK;
10544               expr.original_type = NULL;
10545 	      return expr;
10546 	    }
10547 	  start = expr.get_start ();
10548 	  finish = c_parser_peek_token (parser)->get_finish ();
10549 	  c_parser_consume_token (parser);
10550 	  expr.value = build_component_ref (op_loc, expr.value, ident,
10551 					    comp_loc);
10552 	  set_c_expr_source_range (&expr, start, finish);
10553 	  expr.original_code = ERROR_MARK;
10554 	  if (TREE_CODE (expr.value) != COMPONENT_REF)
10555 	    expr.original_type = NULL;
10556 	  else
10557 	    {
10558 	      /* Remember the original type of a bitfield.  */
10559 	      tree field = TREE_OPERAND (expr.value, 1);
10560 	      if (TREE_CODE (field) != FIELD_DECL)
10561 		expr.original_type = NULL;
10562 	      else
10563 		expr.original_type = DECL_BIT_FIELD_TYPE (field);
10564 	    }
10565 	  break;
10566 	case CPP_DEREF:
10567 	  /* Structure element reference.  */
10568 	  c_parser_consume_token (parser);
10569 	  expr = convert_lvalue_to_rvalue (expr_loc, expr, true, false);
10570 	  if (c_parser_next_token_is (parser, CPP_NAME))
10571 	    {
10572 	      c_token *comp_tok = c_parser_peek_token (parser);
10573 	      ident = comp_tok->value;
10574 	      comp_loc = comp_tok->location;
10575 	    }
10576 	  else
10577 	    {
10578 	      c_parser_error (parser, "expected identifier");
10579 	      expr.set_error ();
10580 	      expr.original_code = ERROR_MARK;
10581 	      expr.original_type = NULL;
10582 	      return expr;
10583 	    }
10584 	  start = expr.get_start ();
10585 	  finish = c_parser_peek_token (parser)->get_finish ();
10586 	  c_parser_consume_token (parser);
10587 	  expr.value = build_component_ref (op_loc,
10588 					    build_indirect_ref (op_loc,
10589 								expr.value,
10590 								RO_ARROW),
10591 					    ident, comp_loc);
10592 	  set_c_expr_source_range (&expr, start, finish);
10593 	  expr.original_code = ERROR_MARK;
10594 	  if (TREE_CODE (expr.value) != COMPONENT_REF)
10595 	    expr.original_type = NULL;
10596 	  else
10597 	    {
10598 	      /* Remember the original type of a bitfield.  */
10599 	      tree field = TREE_OPERAND (expr.value, 1);
10600 	      if (TREE_CODE (field) != FIELD_DECL)
10601 		expr.original_type = NULL;
10602 	      else
10603 		expr.original_type = DECL_BIT_FIELD_TYPE (field);
10604 	    }
10605 	  break;
10606 	case CPP_PLUS_PLUS:
10607 	  /* Postincrement.  */
10608 	  start = expr.get_start ();
10609 	  finish = c_parser_peek_token (parser)->get_finish ();
10610 	  c_parser_consume_token (parser);
10611 	  expr = default_function_array_read_conversion (expr_loc, expr);
10612 	  expr.value = build_unary_op (op_loc, POSTINCREMENT_EXPR,
10613 				       expr.value, false);
10614 	  set_c_expr_source_range (&expr, start, finish);
10615 	  expr.original_code = ERROR_MARK;
10616 	  expr.original_type = NULL;
10617 	  break;
10618 	case CPP_MINUS_MINUS:
10619 	  /* Postdecrement.  */
10620 	  start = expr.get_start ();
10621 	  finish = c_parser_peek_token (parser)->get_finish ();
10622 	  c_parser_consume_token (parser);
10623 	  expr = default_function_array_read_conversion (expr_loc, expr);
10624 	  expr.value = build_unary_op (op_loc, POSTDECREMENT_EXPR,
10625 				       expr.value, false);
10626 	  set_c_expr_source_range (&expr, start, finish);
10627 	  expr.original_code = ERROR_MARK;
10628 	  expr.original_type = NULL;
10629 	  break;
10630 	default:
10631 	  return expr;
10632 	}
10633     }
10634 }
10635 
10636 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
10637 
10638    expression:
10639      assignment-expression
10640      expression , assignment-expression
10641 */
10642 
10643 static struct c_expr
c_parser_expression(c_parser * parser)10644 c_parser_expression (c_parser *parser)
10645 {
10646   location_t tloc = c_parser_peek_token (parser)->location;
10647   struct c_expr expr;
10648   expr = c_parser_expr_no_commas (parser, NULL);
10649   if (c_parser_next_token_is (parser, CPP_COMMA))
10650     expr = convert_lvalue_to_rvalue (tloc, expr, true, false);
10651   while (c_parser_next_token_is (parser, CPP_COMMA))
10652     {
10653       struct c_expr next;
10654       tree lhsval;
10655       location_t loc = c_parser_peek_token (parser)->location;
10656       location_t expr_loc;
10657       c_parser_consume_token (parser);
10658       expr_loc = c_parser_peek_token (parser)->location;
10659       lhsval = expr.value;
10660       while (TREE_CODE (lhsval) == COMPOUND_EXPR)
10661 	lhsval = TREE_OPERAND (lhsval, 1);
10662       if (DECL_P (lhsval) || handled_component_p (lhsval))
10663 	mark_exp_read (lhsval);
10664       next = c_parser_expr_no_commas (parser, NULL);
10665       next = convert_lvalue_to_rvalue (expr_loc, next, true, false);
10666       expr.value = build_compound_expr (loc, expr.value, next.value);
10667       expr.original_code = COMPOUND_EXPR;
10668       expr.original_type = next.original_type;
10669     }
10670   return expr;
10671 }
10672 
10673 /* Parse an expression and convert functions or arrays to pointers and
10674    lvalues to rvalues.  */
10675 
10676 static struct c_expr
c_parser_expression_conv(c_parser * parser)10677 c_parser_expression_conv (c_parser *parser)
10678 {
10679   struct c_expr expr;
10680   location_t loc = c_parser_peek_token (parser)->location;
10681   expr = c_parser_expression (parser);
10682   expr = convert_lvalue_to_rvalue (loc, expr, true, false);
10683   return expr;
10684 }
10685 
10686 /* Helper function of c_parser_expr_list.  Check if IDXth (0 based)
10687    argument is a literal zero alone and if so, set it in literal_zero_mask.  */
10688 
10689 static inline void
c_parser_check_literal_zero(c_parser * parser,unsigned * literal_zero_mask,unsigned int idx)10690 c_parser_check_literal_zero (c_parser *parser, unsigned *literal_zero_mask,
10691 			     unsigned int idx)
10692 {
10693   if (idx >= HOST_BITS_PER_INT)
10694     return;
10695 
10696   c_token *tok = c_parser_peek_token (parser);
10697   switch (tok->type)
10698     {
10699     case CPP_NUMBER:
10700     case CPP_CHAR:
10701     case CPP_WCHAR:
10702     case CPP_CHAR16:
10703     case CPP_CHAR32:
10704     case CPP_UTF8CHAR:
10705       /* If a parameter is literal zero alone, remember it
10706 	 for -Wmemset-transposed-args warning.  */
10707       if (integer_zerop (tok->value)
10708 	  && !TREE_OVERFLOW (tok->value)
10709 	  && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
10710 	      || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
10711 	*literal_zero_mask |= 1U << idx;
10712     default:
10713       break;
10714     }
10715 }
10716 
10717 /* Parse a non-empty list of expressions.  If CONVERT_P, convert
10718    functions and arrays to pointers and lvalues to rvalues.  If
10719    FOLD_P, fold the expressions.  If LOCATIONS is non-NULL, save the
10720    locations of function arguments into this vector.
10721 
10722    nonempty-expr-list:
10723      assignment-expression
10724      nonempty-expr-list , assignment-expression
10725 */
10726 
10727 static vec<tree, va_gc> *
c_parser_expr_list(c_parser * parser,bool convert_p,bool fold_p,vec<tree,va_gc> ** p_orig_types,location_t * sizeof_arg_loc,tree * sizeof_arg,vec<location_t> * locations,unsigned int * literal_zero_mask)10728 c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
10729 		    vec<tree, va_gc> **p_orig_types,
10730 		    location_t *sizeof_arg_loc, tree *sizeof_arg,
10731 		    vec<location_t> *locations,
10732 		    unsigned int *literal_zero_mask)
10733 {
10734   vec<tree, va_gc> *ret;
10735   vec<tree, va_gc> *orig_types;
10736   struct c_expr expr;
10737   unsigned int idx = 0;
10738 
10739   ret = make_tree_vector ();
10740   if (p_orig_types == NULL)
10741     orig_types = NULL;
10742   else
10743     orig_types = make_tree_vector ();
10744 
10745   if (literal_zero_mask)
10746     c_parser_check_literal_zero (parser, literal_zero_mask, 0);
10747   expr = c_parser_expr_no_commas (parser, NULL);
10748   if (convert_p)
10749     expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true, true);
10750   if (fold_p)
10751     expr.value = c_fully_fold (expr.value, false, NULL);
10752   ret->quick_push (expr.value);
10753   if (orig_types)
10754     orig_types->quick_push (expr.original_type);
10755   if (locations)
10756     locations->safe_push (expr.get_location ());
10757   if (sizeof_arg != NULL
10758       && expr.original_code == SIZEOF_EXPR)
10759     {
10760       sizeof_arg[0] = c_last_sizeof_arg;
10761       sizeof_arg_loc[0] = c_last_sizeof_loc;
10762     }
10763   while (c_parser_next_token_is (parser, CPP_COMMA))
10764     {
10765       c_parser_consume_token (parser);
10766       if (literal_zero_mask)
10767 	c_parser_check_literal_zero (parser, literal_zero_mask, idx + 1);
10768       expr = c_parser_expr_no_commas (parser, NULL);
10769       if (convert_p)
10770 	expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true,
10771 					 true);
10772       if (fold_p)
10773 	expr.value = c_fully_fold (expr.value, false, NULL);
10774       vec_safe_push (ret, expr.value);
10775       if (orig_types)
10776 	vec_safe_push (orig_types, expr.original_type);
10777       if (locations)
10778 	locations->safe_push (expr.get_location ());
10779       if (++idx < 3
10780 	  && sizeof_arg != NULL
10781 	  && expr.original_code == SIZEOF_EXPR)
10782 	{
10783 	  sizeof_arg[idx] = c_last_sizeof_arg;
10784 	  sizeof_arg_loc[idx] = c_last_sizeof_loc;
10785 	}
10786     }
10787   if (orig_types)
10788     *p_orig_types = orig_types;
10789   return ret;
10790 }
10791 
10792 /* Parse Objective-C-specific constructs.  */
10793 
10794 /* Parse an objc-class-definition.
10795 
10796    objc-class-definition:
10797      @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
10798        objc-class-instance-variables[opt] objc-methodprotolist @end
10799      @implementation identifier objc-superclass[opt]
10800        objc-class-instance-variables[opt]
10801      @interface identifier ( identifier ) objc-protocol-refs[opt]
10802        objc-methodprotolist @end
10803      @interface identifier ( ) objc-protocol-refs[opt]
10804        objc-methodprotolist @end
10805      @implementation identifier ( identifier )
10806 
10807    objc-superclass:
10808      : identifier
10809 
10810    "@interface identifier (" must start "@interface identifier (
10811    identifier ) ...": objc-methodprotolist in the first production may
10812    not start with a parenthesized identifier as a declarator of a data
10813    definition with no declaration specifiers if the objc-superclass,
10814    objc-protocol-refs and objc-class-instance-variables are omitted.  */
10815 
10816 static void
c_parser_objc_class_definition(c_parser * parser,tree attributes)10817 c_parser_objc_class_definition (c_parser *parser, tree attributes)
10818 {
10819   bool iface_p;
10820   tree id1;
10821   tree superclass;
10822   if (c_parser_next_token_is_keyword (parser, RID_AT_INTERFACE))
10823     iface_p = true;
10824   else if (c_parser_next_token_is_keyword (parser, RID_AT_IMPLEMENTATION))
10825     iface_p = false;
10826   else
10827     gcc_unreachable ();
10828 
10829   c_parser_consume_token (parser);
10830   if (c_parser_next_token_is_not (parser, CPP_NAME))
10831     {
10832       c_parser_error (parser, "expected identifier");
10833       return;
10834     }
10835   id1 = c_parser_peek_token (parser)->value;
10836   c_parser_consume_token (parser);
10837   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
10838     {
10839       /* We have a category or class extension.  */
10840       tree id2;
10841       tree proto = NULL_TREE;
10842       matching_parens parens;
10843       parens.consume_open (parser);
10844       if (c_parser_next_token_is_not (parser, CPP_NAME))
10845 	{
10846 	  if (iface_p && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10847 	    {
10848 	      /* We have a class extension.  */
10849 	      id2 = NULL_TREE;
10850 	    }
10851 	  else
10852 	    {
10853 	      c_parser_error (parser, "expected identifier or %<)%>");
10854 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10855 	      return;
10856 	    }
10857 	}
10858       else
10859 	{
10860 	  id2 = c_parser_peek_token (parser)->value;
10861 	  c_parser_consume_token (parser);
10862 	}
10863       parens.skip_until_found_close (parser);
10864       if (!iface_p)
10865 	{
10866 	  objc_start_category_implementation (id1, id2);
10867 	  return;
10868 	}
10869       if (c_parser_next_token_is (parser, CPP_LESS))
10870 	proto = c_parser_objc_protocol_refs (parser);
10871       objc_start_category_interface (id1, id2, proto, attributes);
10872       c_parser_objc_methodprotolist (parser);
10873       c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
10874       objc_finish_interface ();
10875       return;
10876     }
10877   if (c_parser_next_token_is (parser, CPP_COLON))
10878     {
10879       c_parser_consume_token (parser);
10880       if (c_parser_next_token_is_not (parser, CPP_NAME))
10881 	{
10882 	  c_parser_error (parser, "expected identifier");
10883 	  return;
10884 	}
10885       superclass = c_parser_peek_token (parser)->value;
10886       c_parser_consume_token (parser);
10887     }
10888   else
10889     superclass = NULL_TREE;
10890   if (iface_p)
10891     {
10892       tree proto = NULL_TREE;
10893       if (c_parser_next_token_is (parser, CPP_LESS))
10894 	proto = c_parser_objc_protocol_refs (parser);
10895       objc_start_class_interface (id1, superclass, proto, attributes);
10896     }
10897   else
10898     objc_start_class_implementation (id1, superclass);
10899   if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
10900     c_parser_objc_class_instance_variables (parser);
10901   if (iface_p)
10902     {
10903       objc_continue_interface ();
10904       c_parser_objc_methodprotolist (parser);
10905       c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
10906       objc_finish_interface ();
10907     }
10908   else
10909     {
10910       objc_continue_implementation ();
10911       return;
10912     }
10913 }
10914 
10915 /* Parse objc-class-instance-variables.
10916 
10917    objc-class-instance-variables:
10918      { objc-instance-variable-decl-list[opt] }
10919 
10920    objc-instance-variable-decl-list:
10921      objc-visibility-spec
10922      objc-instance-variable-decl ;
10923      ;
10924      objc-instance-variable-decl-list objc-visibility-spec
10925      objc-instance-variable-decl-list objc-instance-variable-decl ;
10926      objc-instance-variable-decl-list ;
10927 
10928    objc-visibility-spec:
10929      @private
10930      @protected
10931      @public
10932 
10933    objc-instance-variable-decl:
10934      struct-declaration
10935 */
10936 
10937 static void
c_parser_objc_class_instance_variables(c_parser * parser)10938 c_parser_objc_class_instance_variables (c_parser *parser)
10939 {
10940   gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
10941   c_parser_consume_token (parser);
10942   while (c_parser_next_token_is_not (parser, CPP_EOF))
10943     {
10944       tree decls;
10945       /* Parse any stray semicolon.  */
10946       if (c_parser_next_token_is (parser, CPP_SEMICOLON))
10947 	{
10948 	  pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
10949 		   "extra semicolon");
10950 	  c_parser_consume_token (parser);
10951 	  continue;
10952 	}
10953       /* Stop if at the end of the instance variables.  */
10954       if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
10955 	{
10956 	  c_parser_consume_token (parser);
10957 	  break;
10958 	}
10959       /* Parse any objc-visibility-spec.  */
10960       if (c_parser_next_token_is_keyword (parser, RID_AT_PRIVATE))
10961 	{
10962 	  c_parser_consume_token (parser);
10963 	  objc_set_visibility (OBJC_IVAR_VIS_PRIVATE);
10964 	  continue;
10965 	}
10966       else if (c_parser_next_token_is_keyword (parser, RID_AT_PROTECTED))
10967 	{
10968 	  c_parser_consume_token (parser);
10969 	  objc_set_visibility (OBJC_IVAR_VIS_PROTECTED);
10970 	  continue;
10971 	}
10972       else if (c_parser_next_token_is_keyword (parser, RID_AT_PUBLIC))
10973 	{
10974 	  c_parser_consume_token (parser);
10975 	  objc_set_visibility (OBJC_IVAR_VIS_PUBLIC);
10976 	  continue;
10977 	}
10978       else if (c_parser_next_token_is_keyword (parser, RID_AT_PACKAGE))
10979 	{
10980 	  c_parser_consume_token (parser);
10981 	  objc_set_visibility (OBJC_IVAR_VIS_PACKAGE);
10982 	  continue;
10983 	}
10984       else if (c_parser_next_token_is (parser, CPP_PRAGMA))
10985 	{
10986 	  c_parser_pragma (parser, pragma_external, NULL);
10987 	  continue;
10988 	}
10989 
10990       /* Parse some comma-separated declarations.  */
10991       decls = c_parser_struct_declaration (parser);
10992       if (decls == NULL)
10993 	{
10994 	  /* There is a syntax error.  We want to skip the offending
10995 	     tokens up to the next ';' (included) or '}'
10996 	     (excluded).  */
10997 
10998 	  /* First, skip manually a ')' or ']'.  This is because they
10999 	     reduce the nesting level, so c_parser_skip_until_found()
11000 	     wouldn't be able to skip past them.  */
11001 	  c_token *token = c_parser_peek_token (parser);
11002 	  if (token->type == CPP_CLOSE_PAREN || token->type == CPP_CLOSE_SQUARE)
11003 	    c_parser_consume_token (parser);
11004 
11005 	  /* Then, do the standard skipping.  */
11006 	  c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11007 
11008 	  /* We hopefully recovered.  Start normal parsing again.  */
11009 	  parser->error = false;
11010 	  continue;
11011 	}
11012       else
11013 	{
11014 	  /* Comma-separated instance variables are chained together
11015 	     in reverse order; add them one by one.  */
11016 	  tree ivar = nreverse (decls);
11017 	  for (; ivar; ivar = DECL_CHAIN (ivar))
11018 	    objc_add_instance_variable (copy_node (ivar));
11019 	}
11020       c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11021     }
11022 }
11023 
11024 /* Parse an objc-class-declaration.
11025 
11026    objc-class-declaration:
11027      @class identifier-list ;
11028 */
11029 
11030 static void
c_parser_objc_class_declaration(c_parser * parser)11031 c_parser_objc_class_declaration (c_parser *parser)
11032 {
11033   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_CLASS));
11034   c_parser_consume_token (parser);
11035   /* Any identifiers, including those declared as type names, are OK
11036      here.  */
11037   while (true)
11038     {
11039       tree id;
11040       if (c_parser_next_token_is_not (parser, CPP_NAME))
11041 	{
11042 	  c_parser_error (parser, "expected identifier");
11043 	  c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11044 	  parser->error = false;
11045 	  return;
11046 	}
11047       id = c_parser_peek_token (parser)->value;
11048       objc_declare_class (id);
11049       c_parser_consume_token (parser);
11050       if (c_parser_next_token_is (parser, CPP_COMMA))
11051 	c_parser_consume_token (parser);
11052       else
11053 	break;
11054     }
11055   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11056 }
11057 
11058 /* Parse an objc-alias-declaration.
11059 
11060    objc-alias-declaration:
11061      @compatibility_alias identifier identifier ;
11062 */
11063 
11064 static void
c_parser_objc_alias_declaration(c_parser * parser)11065 c_parser_objc_alias_declaration (c_parser *parser)
11066 {
11067   tree id1, id2;
11068   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_ALIAS));
11069   c_parser_consume_token (parser);
11070   if (c_parser_next_token_is_not (parser, CPP_NAME))
11071     {
11072       c_parser_error (parser, "expected identifier");
11073       c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11074       return;
11075     }
11076   id1 = c_parser_peek_token (parser)->value;
11077   c_parser_consume_token (parser);
11078   if (c_parser_next_token_is_not (parser, CPP_NAME))
11079     {
11080       c_parser_error (parser, "expected identifier");
11081       c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11082       return;
11083     }
11084   id2 = c_parser_peek_token (parser)->value;
11085   c_parser_consume_token (parser);
11086   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11087   objc_declare_alias (id1, id2);
11088 }
11089 
11090 /* Parse an objc-protocol-definition.
11091 
11092    objc-protocol-definition:
11093      @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
11094      @protocol identifier-list ;
11095 
11096    "@protocol identifier ;" should be resolved as "@protocol
11097    identifier-list ;": objc-methodprotolist may not start with a
11098    semicolon in the first alternative if objc-protocol-refs are
11099    omitted.  */
11100 
11101 static void
c_parser_objc_protocol_definition(c_parser * parser,tree attributes)11102 c_parser_objc_protocol_definition (c_parser *parser, tree attributes)
11103 {
11104   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROTOCOL));
11105 
11106   c_parser_consume_token (parser);
11107   if (c_parser_next_token_is_not (parser, CPP_NAME))
11108     {
11109       c_parser_error (parser, "expected identifier");
11110       return;
11111     }
11112   if (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
11113       || c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON)
11114     {
11115       /* Any identifiers, including those declared as type names, are
11116 	 OK here.  */
11117       while (true)
11118 	{
11119 	  tree id;
11120 	  if (c_parser_next_token_is_not (parser, CPP_NAME))
11121 	    {
11122 	      c_parser_error (parser, "expected identifier");
11123 	      break;
11124 	    }
11125 	  id = c_parser_peek_token (parser)->value;
11126 	  objc_declare_protocol (id, attributes);
11127 	  c_parser_consume_token (parser);
11128 	  if (c_parser_next_token_is (parser, CPP_COMMA))
11129 	    c_parser_consume_token (parser);
11130 	  else
11131 	    break;
11132 	}
11133       c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11134     }
11135   else
11136     {
11137       tree id = c_parser_peek_token (parser)->value;
11138       tree proto = NULL_TREE;
11139       c_parser_consume_token (parser);
11140       if (c_parser_next_token_is (parser, CPP_LESS))
11141 	proto = c_parser_objc_protocol_refs (parser);
11142       parser->objc_pq_context = true;
11143       objc_start_protocol (id, proto, attributes);
11144       c_parser_objc_methodprotolist (parser);
11145       c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
11146       parser->objc_pq_context = false;
11147       objc_finish_interface ();
11148     }
11149 }
11150 
11151 /* Parse an objc-method-type.
11152 
11153    objc-method-type:
11154      +
11155      -
11156 
11157    Return true if it is a class method (+) and false if it is
11158    an instance method (-).
11159 */
11160 static inline bool
c_parser_objc_method_type(c_parser * parser)11161 c_parser_objc_method_type (c_parser *parser)
11162 {
11163   switch (c_parser_peek_token (parser)->type)
11164     {
11165     case CPP_PLUS:
11166       c_parser_consume_token (parser);
11167       return true;
11168     case CPP_MINUS:
11169       c_parser_consume_token (parser);
11170       return false;
11171     default:
11172       gcc_unreachable ();
11173     }
11174 }
11175 
11176 /* Parse an objc-method-definition.
11177 
11178    objc-method-definition:
11179      objc-method-type objc-method-decl ;[opt] compound-statement
11180 */
11181 
11182 static void
c_parser_objc_method_definition(c_parser * parser)11183 c_parser_objc_method_definition (c_parser *parser)
11184 {
11185   bool is_class_method = c_parser_objc_method_type (parser);
11186   tree decl, attributes = NULL_TREE, expr = NULL_TREE;
11187   parser->objc_pq_context = true;
11188   decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
11189 				    &expr);
11190   if (decl == error_mark_node)
11191     return;  /* Bail here. */
11192 
11193   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
11194     {
11195       c_parser_consume_token (parser);
11196       pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11197 	       "extra semicolon in method definition specified");
11198     }
11199 
11200   if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11201     {
11202       c_parser_error (parser, "expected %<{%>");
11203       return;
11204     }
11205 
11206   parser->objc_pq_context = false;
11207   if (objc_start_method_definition (is_class_method, decl, attributes, expr))
11208     {
11209       add_stmt (c_parser_compound_statement (parser));
11210       objc_finish_method_definition (current_function_decl);
11211     }
11212   else
11213     {
11214       /* This code is executed when we find a method definition
11215 	 outside of an @implementation context (or invalid for other
11216 	 reasons).  Parse the method (to keep going) but do not emit
11217 	 any code.
11218       */
11219       c_parser_compound_statement (parser);
11220     }
11221 }
11222 
11223 /* Parse an objc-methodprotolist.
11224 
11225    objc-methodprotolist:
11226      empty
11227      objc-methodprotolist objc-methodproto
11228      objc-methodprotolist declaration
11229      objc-methodprotolist ;
11230      @optional
11231      @required
11232 
11233    The declaration is a data definition, which may be missing
11234    declaration specifiers under the same rules and diagnostics as
11235    other data definitions outside functions, and the stray semicolon
11236    is diagnosed the same way as a stray semicolon outside a
11237    function.  */
11238 
11239 static void
c_parser_objc_methodprotolist(c_parser * parser)11240 c_parser_objc_methodprotolist (c_parser *parser)
11241 {
11242   while (true)
11243     {
11244       /* The list is terminated by @end.  */
11245       switch (c_parser_peek_token (parser)->type)
11246 	{
11247 	case CPP_SEMICOLON:
11248 	  pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11249 		   "ISO C does not allow extra %<;%> outside of a function");
11250 	  c_parser_consume_token (parser);
11251 	  break;
11252 	case CPP_PLUS:
11253 	case CPP_MINUS:
11254 	  c_parser_objc_methodproto (parser);
11255 	  break;
11256 	case CPP_PRAGMA:
11257 	  c_parser_pragma (parser, pragma_external, NULL);
11258 	  break;
11259 	case CPP_EOF:
11260 	  return;
11261 	default:
11262 	  if (c_parser_next_token_is_keyword (parser, RID_AT_END))
11263 	    return;
11264 	  else if (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY))
11265 	    c_parser_objc_at_property_declaration (parser);
11266 	  else if (c_parser_next_token_is_keyword (parser, RID_AT_OPTIONAL))
11267 	    {
11268 	      objc_set_method_opt (true);
11269 	      c_parser_consume_token (parser);
11270 	    }
11271 	  else if (c_parser_next_token_is_keyword (parser, RID_AT_REQUIRED))
11272 	    {
11273 	      objc_set_method_opt (false);
11274 	      c_parser_consume_token (parser);
11275 	    }
11276 	  else
11277 	    c_parser_declaration_or_fndef (parser, false, false, true,
11278 					   false, true, NULL, vNULL);
11279 	  break;
11280 	}
11281     }
11282 }
11283 
11284 /* Parse an objc-methodproto.
11285 
11286    objc-methodproto:
11287      objc-method-type objc-method-decl ;
11288 */
11289 
11290 static void
c_parser_objc_methodproto(c_parser * parser)11291 c_parser_objc_methodproto (c_parser *parser)
11292 {
11293   bool is_class_method = c_parser_objc_method_type (parser);
11294   tree decl, attributes = NULL_TREE;
11295 
11296   /* Remember protocol qualifiers in prototypes.  */
11297   parser->objc_pq_context = true;
11298   decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
11299 				    NULL);
11300   /* Forget protocol qualifiers now.  */
11301   parser->objc_pq_context = false;
11302 
11303   /* Do not allow the presence of attributes to hide an erroneous
11304      method implementation in the interface section.  */
11305   if (!c_parser_next_token_is (parser, CPP_SEMICOLON))
11306     {
11307       c_parser_error (parser, "expected %<;%>");
11308       return;
11309     }
11310 
11311   if (decl != error_mark_node)
11312     objc_add_method_declaration (is_class_method, decl, attributes);
11313 
11314   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11315 }
11316 
11317 /* If we are at a position that method attributes may be present, check that
11318    there are not any parsed already (a syntax error) and then collect any
11319    specified at the current location.  Finally, if new attributes were present,
11320    check that the next token is legal ( ';' for decls and '{' for defs).  */
11321 
11322 static bool
c_parser_objc_maybe_method_attributes(c_parser * parser,tree * attributes)11323 c_parser_objc_maybe_method_attributes (c_parser* parser, tree* attributes)
11324 {
11325   bool bad = false;
11326   if (*attributes)
11327     {
11328       c_parser_error (parser,
11329 		    "method attributes must be specified at the end only");
11330       *attributes = NULL_TREE;
11331       bad = true;
11332     }
11333 
11334   if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
11335     *attributes = c_parser_gnu_attributes (parser);
11336 
11337   /* If there were no attributes here, just report any earlier error.  */
11338   if (*attributes == NULL_TREE || bad)
11339     return bad;
11340 
11341   /* If the attributes are followed by a ; or {, then just report any earlier
11342      error.  */
11343   if (c_parser_next_token_is (parser, CPP_SEMICOLON)
11344       || c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11345     return bad;
11346 
11347   /* We've got attributes, but not at the end.  */
11348   c_parser_error (parser,
11349 		  "expected %<;%> or %<{%> after method attribute definition");
11350   return true;
11351 }
11352 
11353 /* Parse an objc-method-decl.
11354 
11355    objc-method-decl:
11356      ( objc-type-name ) objc-selector
11357      objc-selector
11358      ( objc-type-name ) objc-keyword-selector objc-optparmlist
11359      objc-keyword-selector objc-optparmlist
11360      gnu-attributes
11361 
11362    objc-keyword-selector:
11363      objc-keyword-decl
11364      objc-keyword-selector objc-keyword-decl
11365 
11366    objc-keyword-decl:
11367      objc-selector : ( objc-type-name ) identifier
11368      objc-selector : identifier
11369      : ( objc-type-name ) identifier
11370      : identifier
11371 
11372    objc-optparmlist:
11373      objc-optparms objc-optellipsis
11374 
11375    objc-optparms:
11376      empty
11377      objc-opt-parms , parameter-declaration
11378 
11379    objc-optellipsis:
11380      empty
11381      , ...
11382 */
11383 
11384 static tree
c_parser_objc_method_decl(c_parser * parser,bool is_class_method,tree * attributes,tree * expr)11385 c_parser_objc_method_decl (c_parser *parser, bool is_class_method,
11386 			   tree *attributes, tree *expr)
11387 {
11388   tree type = NULL_TREE;
11389   tree sel;
11390   tree parms = NULL_TREE;
11391   bool ellipsis = false;
11392   bool attr_err = false;
11393 
11394   *attributes = NULL_TREE;
11395   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11396     {
11397       matching_parens parens;
11398       parens.consume_open (parser);
11399       type = c_parser_objc_type_name (parser);
11400       parens.skip_until_found_close (parser);
11401     }
11402   sel = c_parser_objc_selector (parser);
11403   /* If there is no selector, or a colon follows, we have an
11404      objc-keyword-selector.  If there is a selector, and a colon does
11405      not follow, that selector ends the objc-method-decl.  */
11406   if (!sel || c_parser_next_token_is (parser, CPP_COLON))
11407     {
11408       tree tsel = sel;
11409       tree list = NULL_TREE;
11410       while (true)
11411 	{
11412 	  tree atype = NULL_TREE, id, keyworddecl;
11413 	  tree param_attr = NULL_TREE;
11414 	  if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11415 	    break;
11416 	  if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11417 	    {
11418 	      c_parser_consume_token (parser);
11419 	      atype = c_parser_objc_type_name (parser);
11420 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
11421 					 "expected %<)%>");
11422 	    }
11423 	  /* New ObjC allows attributes on method parameters.  */
11424 	  if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
11425 	    param_attr = c_parser_gnu_attributes (parser);
11426 	  if (c_parser_next_token_is_not (parser, CPP_NAME))
11427 	    {
11428 	      c_parser_error (parser, "expected identifier");
11429 	      return error_mark_node;
11430 	    }
11431 	  id = c_parser_peek_token (parser)->value;
11432 	  c_parser_consume_token (parser);
11433 	  keyworddecl = objc_build_keyword_decl (tsel, atype, id, param_attr);
11434 	  list = chainon (list, keyworddecl);
11435 	  tsel = c_parser_objc_selector (parser);
11436 	  if (!tsel && c_parser_next_token_is_not (parser, CPP_COLON))
11437 	    break;
11438 	}
11439 
11440       attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
11441 
11442       /* Parse the optional parameter list.  Optional Objective-C
11443 	 method parameters follow the C syntax, and may include '...'
11444 	 to denote a variable number of arguments.  */
11445       parms = make_node (TREE_LIST);
11446       while (c_parser_next_token_is (parser, CPP_COMMA))
11447 	{
11448 	  struct c_parm *parm;
11449 	  c_parser_consume_token (parser);
11450 	  if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
11451 	    {
11452 	      ellipsis = true;
11453 	      c_parser_consume_token (parser);
11454 	      attr_err |= c_parser_objc_maybe_method_attributes
11455 						(parser, attributes) ;
11456 	      break;
11457 	    }
11458 	  parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
11459 	  if (parm == NULL)
11460 	    break;
11461 	  parms = chainon (parms,
11462 			   build_tree_list (NULL_TREE, grokparm (parm, expr)));
11463 	}
11464       sel = list;
11465     }
11466   else
11467     attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
11468 
11469   if (sel == NULL)
11470     {
11471       c_parser_error (parser, "objective-c method declaration is expected");
11472       return error_mark_node;
11473     }
11474 
11475   if (attr_err)
11476     return error_mark_node;
11477 
11478   return objc_build_method_signature (is_class_method, type, sel, parms, ellipsis);
11479 }
11480 
11481 /* Parse an objc-type-name.
11482 
11483    objc-type-name:
11484      objc-type-qualifiers[opt] type-name
11485      objc-type-qualifiers[opt]
11486 
11487    objc-type-qualifiers:
11488      objc-type-qualifier
11489      objc-type-qualifiers objc-type-qualifier
11490 
11491    objc-type-qualifier: one of
11492      in out inout bycopy byref oneway
11493 */
11494 
11495 static tree
c_parser_objc_type_name(c_parser * parser)11496 c_parser_objc_type_name (c_parser *parser)
11497 {
11498   tree quals = NULL_TREE;
11499   struct c_type_name *type_name = NULL;
11500   tree type = NULL_TREE;
11501   while (true)
11502     {
11503       c_token *token = c_parser_peek_token (parser);
11504       if (token->type == CPP_KEYWORD
11505 	  && (token->keyword == RID_IN
11506 	      || token->keyword == RID_OUT
11507 	      || token->keyword == RID_INOUT
11508 	      || token->keyword == RID_BYCOPY
11509 	      || token->keyword == RID_BYREF
11510 	      || token->keyword == RID_ONEWAY))
11511 	{
11512 	  quals = chainon (build_tree_list (NULL_TREE, token->value), quals);
11513 	  c_parser_consume_token (parser);
11514 	}
11515       else
11516 	break;
11517     }
11518   if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
11519     type_name = c_parser_type_name (parser);
11520   if (type_name)
11521     type = groktypename (type_name, NULL, NULL);
11522 
11523   /* If the type is unknown, and error has already been produced and
11524      we need to recover from the error.  In that case, use NULL_TREE
11525      for the type, as if no type had been specified; this will use the
11526      default type ('id') which is good for error recovery.  */
11527   if (type == error_mark_node)
11528     type = NULL_TREE;
11529 
11530   return build_tree_list (quals, type);
11531 }
11532 
11533 /* Parse objc-protocol-refs.
11534 
11535    objc-protocol-refs:
11536      < identifier-list >
11537 */
11538 
11539 static tree
c_parser_objc_protocol_refs(c_parser * parser)11540 c_parser_objc_protocol_refs (c_parser *parser)
11541 {
11542   tree list = NULL_TREE;
11543   gcc_assert (c_parser_next_token_is (parser, CPP_LESS));
11544   c_parser_consume_token (parser);
11545   /* Any identifiers, including those declared as type names, are OK
11546      here.  */
11547   while (true)
11548     {
11549       tree id;
11550       if (c_parser_next_token_is_not (parser, CPP_NAME))
11551 	{
11552 	  c_parser_error (parser, "expected identifier");
11553 	  break;
11554 	}
11555       id = c_parser_peek_token (parser)->value;
11556       list = chainon (list, build_tree_list (NULL_TREE, id));
11557       c_parser_consume_token (parser);
11558       if (c_parser_next_token_is (parser, CPP_COMMA))
11559 	c_parser_consume_token (parser);
11560       else
11561 	break;
11562     }
11563   c_parser_require (parser, CPP_GREATER, "expected %<>%>");
11564   return list;
11565 }
11566 
11567 /* Parse an objc-try-catch-finally-statement.
11568 
11569    objc-try-catch-finally-statement:
11570      @try compound-statement objc-catch-list[opt]
11571      @try compound-statement objc-catch-list[opt] @finally compound-statement
11572 
11573    objc-catch-list:
11574      @catch ( objc-catch-parameter-declaration ) compound-statement
11575      objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
11576 
11577    objc-catch-parameter-declaration:
11578      parameter-declaration
11579      '...'
11580 
11581    where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
11582 
11583    PS: This function is identical to cp_parser_objc_try_catch_finally_statement
11584    for C++.  Keep them in sync.  */
11585 
11586 static void
c_parser_objc_try_catch_finally_statement(c_parser * parser)11587 c_parser_objc_try_catch_finally_statement (c_parser *parser)
11588 {
11589   location_t location;
11590   tree stmt;
11591 
11592   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_TRY));
11593   c_parser_consume_token (parser);
11594   location = c_parser_peek_token (parser)->location;
11595   objc_maybe_warn_exceptions (location);
11596   stmt = c_parser_compound_statement (parser);
11597   objc_begin_try_stmt (location, stmt);
11598 
11599   while (c_parser_next_token_is_keyword (parser, RID_AT_CATCH))
11600     {
11601       struct c_parm *parm;
11602       tree parameter_declaration = error_mark_node;
11603       bool seen_open_paren = false;
11604 
11605       c_parser_consume_token (parser);
11606       matching_parens parens;
11607       if (!parens.require_open (parser))
11608 	seen_open_paren = true;
11609       if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
11610 	{
11611 	  /* We have "@catch (...)" (where the '...' are literally
11612 	     what is in the code).  Skip the '...'.
11613 	     parameter_declaration is set to NULL_TREE, and
11614 	     objc_being_catch_clauses() knows that that means
11615 	     '...'.  */
11616 	  c_parser_consume_token (parser);
11617 	  parameter_declaration = NULL_TREE;
11618 	}
11619       else
11620 	{
11621 	  /* We have "@catch (NSException *exception)" or something
11622 	     like that.  Parse the parameter declaration.  */
11623 	  parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
11624 	  if (parm == NULL)
11625 	    parameter_declaration = error_mark_node;
11626 	  else
11627 	    parameter_declaration = grokparm (parm, NULL);
11628 	}
11629       if (seen_open_paren)
11630 	parens.require_close (parser);
11631       else
11632 	{
11633 	  /* If there was no open parenthesis, we are recovering from
11634 	     an error, and we are trying to figure out what mistake
11635 	     the user has made.  */
11636 
11637 	  /* If there is an immediate closing parenthesis, the user
11638 	     probably forgot the opening one (ie, they typed "@catch
11639 	     NSException *e)".  Parse the closing parenthesis and keep
11640 	     going.  */
11641 	  if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
11642 	    c_parser_consume_token (parser);
11643 
11644 	  /* If these is no immediate closing parenthesis, the user
11645 	     probably doesn't know that parenthesis are required at
11646 	     all (ie, they typed "@catch NSException *e").  So, just
11647 	     forget about the closing parenthesis and keep going.  */
11648 	}
11649       objc_begin_catch_clause (parameter_declaration);
11650       if (c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
11651 	c_parser_compound_statement_nostart (parser);
11652       objc_finish_catch_clause ();
11653     }
11654   if (c_parser_next_token_is_keyword (parser, RID_AT_FINALLY))
11655     {
11656       c_parser_consume_token (parser);
11657       location = c_parser_peek_token (parser)->location;
11658       stmt = c_parser_compound_statement (parser);
11659       objc_build_finally_clause (location, stmt);
11660     }
11661   objc_finish_try_stmt ();
11662 }
11663 
11664 /* Parse an objc-synchronized-statement.
11665 
11666    objc-synchronized-statement:
11667      @synchronized ( expression ) compound-statement
11668 */
11669 
11670 static void
c_parser_objc_synchronized_statement(c_parser * parser)11671 c_parser_objc_synchronized_statement (c_parser *parser)
11672 {
11673   location_t loc;
11674   tree expr, stmt;
11675   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNCHRONIZED));
11676   c_parser_consume_token (parser);
11677   loc = c_parser_peek_token (parser)->location;
11678   objc_maybe_warn_exceptions (loc);
11679   matching_parens parens;
11680   if (parens.require_open (parser))
11681     {
11682       struct c_expr ce = c_parser_expression (parser);
11683       ce = convert_lvalue_to_rvalue (loc, ce, false, false);
11684       expr = ce.value;
11685       expr = c_fully_fold (expr, false, NULL);
11686       parens.skip_until_found_close (parser);
11687     }
11688   else
11689     expr = error_mark_node;
11690   stmt = c_parser_compound_statement (parser);
11691   objc_build_synchronized (loc, expr, stmt);
11692 }
11693 
11694 /* Parse an objc-selector; return NULL_TREE without an error if the
11695    next token is not an objc-selector.
11696 
11697    objc-selector:
11698      identifier
11699      one of
11700        enum struct union if else while do for switch case default
11701        break continue return goto asm sizeof typeof __alignof
11702        unsigned long const short volatile signed restrict _Complex
11703        in out inout bycopy byref oneway int char float double void _Bool
11704        _Atomic
11705 
11706    ??? Why this selection of keywords but not, for example, storage
11707    class specifiers?  */
11708 
11709 static tree
c_parser_objc_selector(c_parser * parser)11710 c_parser_objc_selector (c_parser *parser)
11711 {
11712   c_token *token = c_parser_peek_token (parser);
11713   tree value = token->value;
11714   if (token->type == CPP_NAME)
11715     {
11716       c_parser_consume_token (parser);
11717       return value;
11718     }
11719   if (token->type != CPP_KEYWORD)
11720     return NULL_TREE;
11721   switch (token->keyword)
11722     {
11723     case RID_ENUM:
11724     case RID_STRUCT:
11725     case RID_UNION:
11726     case RID_IF:
11727     case RID_ELSE:
11728     case RID_WHILE:
11729     case RID_DO:
11730     case RID_FOR:
11731     case RID_SWITCH:
11732     case RID_CASE:
11733     case RID_DEFAULT:
11734     case RID_BREAK:
11735     case RID_CONTINUE:
11736     case RID_RETURN:
11737     case RID_GOTO:
11738     case RID_ASM:
11739     case RID_SIZEOF:
11740     case RID_TYPEOF:
11741     case RID_ALIGNOF:
11742     case RID_UNSIGNED:
11743     case RID_LONG:
11744     case RID_CONST:
11745     case RID_SHORT:
11746     case RID_VOLATILE:
11747     case RID_SIGNED:
11748     case RID_RESTRICT:
11749     case RID_COMPLEX:
11750     case RID_IN:
11751     case RID_OUT:
11752     case RID_INOUT:
11753     case RID_BYCOPY:
11754     case RID_BYREF:
11755     case RID_ONEWAY:
11756     case RID_INT:
11757     case RID_CHAR:
11758     case RID_FLOAT:
11759     case RID_DOUBLE:
11760     CASE_RID_FLOATN_NX:
11761     case RID_VOID:
11762     case RID_BOOL:
11763     case RID_ATOMIC:
11764     case RID_AUTO_TYPE:
11765     case RID_INT_N_0:
11766     case RID_INT_N_1:
11767     case RID_INT_N_2:
11768     case RID_INT_N_3:
11769       c_parser_consume_token (parser);
11770       return value;
11771     default:
11772       return NULL_TREE;
11773     }
11774 }
11775 
11776 /* Parse an objc-selector-arg.
11777 
11778    objc-selector-arg:
11779      objc-selector
11780      objc-keywordname-list
11781 
11782    objc-keywordname-list:
11783      objc-keywordname
11784      objc-keywordname-list objc-keywordname
11785 
11786    objc-keywordname:
11787      objc-selector :
11788      :
11789 */
11790 
11791 static tree
c_parser_objc_selector_arg(c_parser * parser)11792 c_parser_objc_selector_arg (c_parser *parser)
11793 {
11794   tree sel = c_parser_objc_selector (parser);
11795   tree list = NULL_TREE;
11796   if (sel
11797       && c_parser_next_token_is_not (parser, CPP_COLON)
11798       && c_parser_next_token_is_not (parser, CPP_SCOPE))
11799     return sel;
11800   while (true)
11801     {
11802       if (c_parser_next_token_is (parser, CPP_SCOPE))
11803 	{
11804 	  c_parser_consume_token (parser);
11805 	  list = chainon (list, build_tree_list (sel, NULL_TREE));
11806 	  list = chainon (list, build_tree_list (NULL_TREE, NULL_TREE));
11807 	}
11808       else
11809 	{
11810 	  if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11811 	    return list;
11812 	  list = chainon (list, build_tree_list (sel, NULL_TREE));
11813 	}
11814       sel = c_parser_objc_selector (parser);
11815       if (!sel
11816 	  && c_parser_next_token_is_not (parser, CPP_COLON)
11817 	  && c_parser_next_token_is_not (parser, CPP_SCOPE))
11818 	break;
11819     }
11820   return list;
11821 }
11822 
11823 /* Parse an objc-receiver.
11824 
11825    objc-receiver:
11826      expression
11827      class-name
11828      type-name
11829 */
11830 
11831 static tree
c_parser_objc_receiver(c_parser * parser)11832 c_parser_objc_receiver (c_parser *parser)
11833 {
11834   location_t loc = c_parser_peek_token (parser)->location;
11835 
11836   if (c_parser_peek_token (parser)->type == CPP_NAME
11837       && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
11838 	  || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
11839     {
11840       tree id = c_parser_peek_token (parser)->value;
11841       c_parser_consume_token (parser);
11842       return objc_get_class_reference (id);
11843     }
11844   struct c_expr ce = c_parser_expression (parser);
11845   ce = convert_lvalue_to_rvalue (loc, ce, false, false);
11846   return c_fully_fold (ce.value, false, NULL);
11847 }
11848 
11849 /* Parse objc-message-args.
11850 
11851    objc-message-args:
11852      objc-selector
11853      objc-keywordarg-list
11854 
11855    objc-keywordarg-list:
11856      objc-keywordarg
11857      objc-keywordarg-list objc-keywordarg
11858 
11859    objc-keywordarg:
11860      objc-selector : objc-keywordexpr
11861      : objc-keywordexpr
11862 */
11863 
11864 static tree
c_parser_objc_message_args(c_parser * parser)11865 c_parser_objc_message_args (c_parser *parser)
11866 {
11867   tree sel = c_parser_objc_selector (parser);
11868   tree list = NULL_TREE;
11869   if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
11870     return sel;
11871   while (true)
11872     {
11873       tree keywordexpr;
11874       if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11875 	return error_mark_node;
11876       keywordexpr = c_parser_objc_keywordexpr (parser);
11877       list = chainon (list, build_tree_list (sel, keywordexpr));
11878       sel = c_parser_objc_selector (parser);
11879       if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
11880 	break;
11881     }
11882   return list;
11883 }
11884 
11885 /* Parse an objc-keywordexpr.
11886 
11887    objc-keywordexpr:
11888      nonempty-expr-list
11889 */
11890 
11891 static tree
c_parser_objc_keywordexpr(c_parser * parser)11892 c_parser_objc_keywordexpr (c_parser *parser)
11893 {
11894   tree ret;
11895   vec<tree, va_gc> *expr_list = c_parser_expr_list (parser, true, true,
11896 						NULL, NULL, NULL, NULL);
11897   if (vec_safe_length (expr_list) == 1)
11898     {
11899       /* Just return the expression, remove a level of
11900 	 indirection.  */
11901       ret = (*expr_list)[0];
11902     }
11903   else
11904     {
11905       /* We have a comma expression, we will collapse later.  */
11906       ret = build_tree_list_vec (expr_list);
11907     }
11908   release_tree_vector (expr_list);
11909   return ret;
11910 }
11911 
11912 /* A check, needed in several places, that ObjC interface, implementation or
11913    method definitions are not prefixed by incorrect items.  */
11914 static bool
c_parser_objc_diagnose_bad_element_prefix(c_parser * parser,struct c_declspecs * specs)11915 c_parser_objc_diagnose_bad_element_prefix (c_parser *parser,
11916 					   struct c_declspecs *specs)
11917 {
11918   if (!specs->declspecs_seen_p || specs->non_sc_seen_p
11919       || specs->typespec_kind != ctsk_none)
11920     {
11921       c_parser_error (parser,
11922       		      "no type or storage class may be specified here,");
11923       c_parser_skip_to_end_of_block_or_statement (parser);
11924       return true;
11925     }
11926   return false;
11927 }
11928 
11929 /* Parse an Objective-C @property declaration.  The syntax is:
11930 
11931    objc-property-declaration:
11932      '@property' objc-property-attributes[opt] struct-declaration ;
11933 
11934    objc-property-attributes:
11935     '(' objc-property-attribute-list ')'
11936 
11937    objc-property-attribute-list:
11938      objc-property-attribute
11939      objc-property-attribute-list, objc-property-attribute
11940 
11941    objc-property-attribute
11942      'getter' = identifier
11943      'setter' = identifier
11944      'readonly'
11945      'readwrite'
11946      'assign'
11947      'retain'
11948      'copy'
11949      'nonatomic'
11950 
11951   For example:
11952     @property NSString *name;
11953     @property (readonly) id object;
11954     @property (retain, nonatomic, getter=getTheName) id name;
11955     @property int a, b, c;
11956 
11957   PS: This function is identical to cp_parser_objc_at_propery_declaration
11958   for C++.  Keep them in sync.  */
11959 static void
c_parser_objc_at_property_declaration(c_parser * parser)11960 c_parser_objc_at_property_declaration (c_parser *parser)
11961 {
11962   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY));
11963   location_t loc = c_parser_peek_token (parser)->location;
11964   c_parser_consume_token (parser);  /* Eat '@property'.  */
11965 
11966   /* Parse the optional attribute list.
11967 
11968      A list of parsed, but not verified, attributes.  */
11969   vec<property_attribute_info *> prop_attr_list = vNULL;
11970 
11971   bool syntax_error = false;
11972   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11973     {
11974       matching_parens parens;
11975 
11976       location_t attr_start = c_parser_peek_token (parser)->location;
11977       /* Eat the '(' */
11978       parens.consume_open (parser);
11979 
11980       /* Property attribute keywords are valid now.  */
11981       parser->objc_property_attr_context = true;
11982 
11983       /* Allow @property (), with a warning.  */
11984       location_t attr_end = c_parser_peek_token (parser)->location;
11985 
11986       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
11987 	{
11988 	  location_t attr_comb = make_location (attr_end, attr_start, attr_end);
11989 	  warning_at (attr_comb, OPT_Wattributes,
11990 		      "empty property attribute list");
11991 	}
11992       else
11993 	while (true)
11994 	  {
11995 	    c_token *token = c_parser_peek_token (parser);
11996 	    attr_start = token->location;
11997 	    attr_end = get_finish (token->location);
11998 	    location_t attr_comb = make_location (attr_start, attr_start,
11999 						  attr_end);
12000 
12001 	    if (token->type == CPP_CLOSE_PAREN || token->type == CPP_COMMA)
12002 	      {
12003 		warning_at (attr_comb, OPT_Wattributes,
12004 			    "missing property attribute");
12005 		if (token->type == CPP_CLOSE_PAREN)
12006 		  break;
12007 		c_parser_consume_token (parser);
12008 		continue;
12009 	      }
12010 
12011 	    tree attr_name = NULL_TREE;
12012 	    enum rid keyword = RID_MAX; /* Not a valid property attribute.  */
12013 	    bool add_at = false;
12014 	    if (token->type == CPP_KEYWORD)
12015 	      {
12016 		keyword = token->keyword;
12017 		if (OBJC_IS_AT_KEYWORD (keyword))
12018 		  {
12019 		    /* For '@' keywords the token value has the keyword,
12020 		       prepend the '@' for diagnostics.  */
12021 		    attr_name = token->value;
12022 		    add_at = true;
12023 		  }
12024 		else
12025 		  attr_name = ridpointers[(int)keyword];
12026 	      }
12027 	    else if (token->type == CPP_NAME)
12028 	      attr_name = token->value;
12029 	    c_parser_consume_token (parser);
12030 
12031 	    enum objc_property_attribute_kind prop_kind
12032 	      = objc_prop_attr_kind_for_rid (keyword);
12033 	    property_attribute_info *prop
12034 	      = new property_attribute_info (attr_name, attr_comb, prop_kind);
12035 	    prop_attr_list.safe_push (prop);
12036 
12037 	    tree meth_name;
12038 	    switch (prop->prop_kind)
12039 	      {
12040 	      default: break;
12041 	      case OBJC_PROPERTY_ATTR_UNKNOWN:
12042 		if (attr_name)
12043 		  error_at (attr_comb, "unknown property attribute %<%s%s%>",
12044 			    add_at ? "@" : "", IDENTIFIER_POINTER (attr_name));
12045 		else
12046 		  error_at (attr_comb, "unknown property attribute");
12047 		prop->parse_error = syntax_error = true;
12048 		break;
12049 
12050 	      case OBJC_PROPERTY_ATTR_GETTER:
12051 	      case OBJC_PROPERTY_ATTR_SETTER:
12052 		if (c_parser_next_token_is_not (parser, CPP_EQ))
12053 		  {
12054 		    attr_comb = make_location (attr_end, attr_start, attr_end);
12055 		    error_at (attr_comb, "expected %<=%> after Objective-C %qE",
12056 			      attr_name);
12057 		    prop->parse_error = syntax_error = true;
12058 		    break;
12059 		  }
12060 		token = c_parser_peek_token (parser);
12061 		attr_end = token->location;
12062 		c_parser_consume_token (parser); /* eat the = */
12063 		if (c_parser_next_token_is_not (parser, CPP_NAME))
12064 		  {
12065 		    attr_comb = make_location (attr_end, attr_start, attr_end);
12066 		    error_at (attr_comb, "expected %qE selector name",
12067 			      attr_name);
12068 		    prop->parse_error = syntax_error = true;
12069 		    break;
12070 		  }
12071 		/* Get the end of the method name, and consume the name.  */
12072 		token = c_parser_peek_token (parser);
12073 		attr_end = get_finish (token->location);
12074 		meth_name = token->value;
12075 		c_parser_consume_token (parser);
12076 		if (prop->prop_kind == OBJC_PROPERTY_ATTR_SETTER)
12077 		  {
12078 		    if (c_parser_next_token_is_not (parser, CPP_COLON))
12079 		      {
12080 			attr_comb = make_location (attr_end, attr_start,
12081 						   attr_end);
12082 			error_at (attr_comb, "setter method names must"
12083 				  " terminate with %<:%>");
12084 			prop->parse_error = syntax_error = true;
12085 		      }
12086 		    else
12087 		      {
12088 			attr_end = get_finish (c_parser_peek_token
12089 					       (parser)->location);
12090 			c_parser_consume_token (parser);
12091 		      }
12092 		    attr_comb = make_location (attr_start, attr_start,
12093 					       attr_end);
12094 		  }
12095 		else
12096 		  attr_comb = make_location (attr_start, attr_start,
12097 					       attr_end);
12098 		prop->ident = meth_name;
12099 		/* Updated location including all that was successfully
12100 		   parsed.  */
12101 		prop->prop_loc = attr_comb;
12102 		break;
12103 	    }
12104 
12105 	  /* If we see a comma here, then keep going - even if we already
12106 	     saw a syntax error.  For simple mistakes e.g. (asign, getter=x)
12107 	     this makes a more useful output and avoid spurious warnings about
12108 	     missing attributes that are, in fact, specified after the one with
12109 	     the syntax error.  */
12110 	  if (c_parser_next_token_is (parser, CPP_COMMA))
12111 	    c_parser_consume_token (parser);
12112 	  else
12113 	    break;
12114 	}
12115       parser->objc_property_attr_context = false;
12116 
12117       if (syntax_error && c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
12118 	/* We don't really want to chew the whole of the file looking for a
12119 	   matching closing parenthesis, so we will try to read the decl and
12120 	   let the error handling for that close out the statement.  */
12121 	;
12122       else
12123 	syntax_error = false, parens.skip_until_found_close (parser);
12124     }
12125 
12126   /* 'properties' is the list of properties that we read.  Usually a
12127      single one, but maybe more (eg, in "@property int a, b, c;" there
12128      are three).  */
12129   tree properties = c_parser_struct_declaration (parser);
12130 
12131   if (properties == error_mark_node)
12132     c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12133   else
12134     {
12135       if (properties == NULL_TREE)
12136 	c_parser_error (parser, "expected identifier");
12137       else
12138 	{
12139 	  /* Comma-separated properties are chained together in reverse order;
12140 	     add them one by one.  */
12141 	  properties = nreverse (properties);
12142 	  for (; properties; properties = TREE_CHAIN (properties))
12143 	    objc_add_property_declaration (loc, copy_node (properties),
12144 					    prop_attr_list);
12145 	}
12146       c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12147     }
12148 
12149   while (!prop_attr_list.is_empty())
12150     delete prop_attr_list.pop ();
12151   prop_attr_list.release ();
12152   parser->error = false;
12153 }
12154 
12155 /* Parse an Objective-C @synthesize declaration.  The syntax is:
12156 
12157    objc-synthesize-declaration:
12158      @synthesize objc-synthesize-identifier-list ;
12159 
12160    objc-synthesize-identifier-list:
12161      objc-synthesize-identifier
12162      objc-synthesize-identifier-list, objc-synthesize-identifier
12163 
12164    objc-synthesize-identifier
12165      identifier
12166      identifier = identifier
12167 
12168   For example:
12169     @synthesize MyProperty;
12170     @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
12171 
12172   PS: This function is identical to cp_parser_objc_at_synthesize_declaration
12173   for C++.  Keep them in sync.
12174 */
12175 static void
c_parser_objc_at_synthesize_declaration(c_parser * parser)12176 c_parser_objc_at_synthesize_declaration (c_parser *parser)
12177 {
12178   tree list = NULL_TREE;
12179   location_t loc;
12180   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNTHESIZE));
12181   loc = c_parser_peek_token (parser)->location;
12182 
12183   c_parser_consume_token (parser);
12184   while (true)
12185     {
12186       tree property, ivar;
12187       if (c_parser_next_token_is_not (parser, CPP_NAME))
12188 	{
12189 	  c_parser_error (parser, "expected identifier");
12190 	  c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12191 	  /* Once we find the semicolon, we can resume normal parsing.
12192 	     We have to reset parser->error manually because
12193 	     c_parser_skip_until_found() won't reset it for us if the
12194 	     next token is precisely a semicolon.  */
12195 	  parser->error = false;
12196 	  return;
12197 	}
12198       property = c_parser_peek_token (parser)->value;
12199       c_parser_consume_token (parser);
12200       if (c_parser_next_token_is (parser, CPP_EQ))
12201 	{
12202 	  c_parser_consume_token (parser);
12203 	  if (c_parser_next_token_is_not (parser, CPP_NAME))
12204 	    {
12205 	      c_parser_error (parser, "expected identifier");
12206 	      c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12207 	      parser->error = false;
12208 	      return;
12209 	    }
12210 	  ivar = c_parser_peek_token (parser)->value;
12211 	  c_parser_consume_token (parser);
12212 	}
12213       else
12214 	ivar = NULL_TREE;
12215       list = chainon (list, build_tree_list (ivar, property));
12216       if (c_parser_next_token_is (parser, CPP_COMMA))
12217 	c_parser_consume_token (parser);
12218       else
12219 	break;
12220     }
12221   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12222   objc_add_synthesize_declaration (loc, list);
12223 }
12224 
12225 /* Parse an Objective-C @dynamic declaration.  The syntax is:
12226 
12227    objc-dynamic-declaration:
12228      @dynamic identifier-list ;
12229 
12230    For example:
12231      @dynamic MyProperty;
12232      @dynamic MyProperty, AnotherProperty;
12233 
12234   PS: This function is identical to cp_parser_objc_at_dynamic_declaration
12235   for C++.  Keep them in sync.
12236 */
12237 static void
c_parser_objc_at_dynamic_declaration(c_parser * parser)12238 c_parser_objc_at_dynamic_declaration (c_parser *parser)
12239 {
12240   tree list = NULL_TREE;
12241   location_t loc;
12242   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_DYNAMIC));
12243   loc = c_parser_peek_token (parser)->location;
12244 
12245   c_parser_consume_token (parser);
12246   while (true)
12247     {
12248       tree property;
12249       if (c_parser_next_token_is_not (parser, CPP_NAME))
12250 	{
12251 	  c_parser_error (parser, "expected identifier");
12252 	  c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12253 	  parser->error = false;
12254 	  return;
12255 	}
12256       property = c_parser_peek_token (parser)->value;
12257       list = chainon (list, build_tree_list (NULL_TREE, property));
12258       c_parser_consume_token (parser);
12259       if (c_parser_next_token_is (parser, CPP_COMMA))
12260 	c_parser_consume_token (parser);
12261       else
12262 	break;
12263     }
12264   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12265   objc_add_dynamic_declaration (loc, list);
12266 }
12267 
12268 
12269 /* Parse a pragma GCC ivdep.  */
12270 
12271 static bool
c_parse_pragma_ivdep(c_parser * parser)12272 c_parse_pragma_ivdep (c_parser *parser)
12273 {
12274   c_parser_consume_pragma (parser);
12275   c_parser_skip_to_pragma_eol (parser);
12276   return true;
12277 }
12278 
12279 /* Parse a pragma GCC unroll.  */
12280 
12281 static unsigned short
c_parser_pragma_unroll(c_parser * parser)12282 c_parser_pragma_unroll (c_parser *parser)
12283 {
12284   unsigned short unroll;
12285   c_parser_consume_pragma (parser);
12286   location_t location = c_parser_peek_token (parser)->location;
12287   tree expr = c_parser_expr_no_commas (parser, NULL).value;
12288   mark_exp_read (expr);
12289   expr = c_fully_fold (expr, false, NULL);
12290   HOST_WIDE_INT lunroll = 0;
12291   if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
12292       || TREE_CODE (expr) != INTEGER_CST
12293       || (lunroll = tree_to_shwi (expr)) < 0
12294       || lunroll >= USHRT_MAX)
12295     {
12296       error_at (location, "%<#pragma GCC unroll%> requires an"
12297 		" assignment-expression that evaluates to a non-negative"
12298 		" integral constant less than %u", USHRT_MAX);
12299       unroll = 0;
12300     }
12301   else
12302     {
12303       unroll = (unsigned short)lunroll;
12304       if (unroll == 0)
12305 	unroll = 1;
12306     }
12307 
12308   c_parser_skip_to_pragma_eol (parser);
12309   return unroll;
12310 }
12311 
12312 /* Handle pragmas.  Some OpenMP pragmas are associated with, and therefore
12313    should be considered, statements.  ALLOW_STMT is true if we're within
12314    the context of a function and such pragmas are to be allowed.  Returns
12315    true if we actually parsed such a pragma.  */
12316 
12317 static bool
c_parser_pragma(c_parser * parser,enum pragma_context context,bool * if_p)12318 c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p)
12319 {
12320   unsigned int id;
12321   const char *construct = NULL;
12322 
12323   id = c_parser_peek_token (parser)->pragma_kind;
12324   gcc_assert (id != PRAGMA_NONE);
12325 
12326   switch (id)
12327     {
12328     case PRAGMA_OACC_DECLARE:
12329       c_parser_oacc_declare (parser);
12330       return false;
12331 
12332     case PRAGMA_OACC_ENTER_DATA:
12333       if (context != pragma_compound)
12334 	{
12335 	  construct = "acc enter data";
12336 	in_compound:
12337 	  if (context == pragma_stmt)
12338 	    {
12339 	      error_at (c_parser_peek_token (parser)->location,
12340 			"%<#pragma %s%> may only be used in compound "
12341 			"statements", construct);
12342 	      c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12343 	      return false;
12344 	    }
12345 	  goto bad_stmt;
12346 	}
12347       c_parser_oacc_enter_exit_data (parser, true);
12348       return false;
12349 
12350     case PRAGMA_OACC_EXIT_DATA:
12351       if (context != pragma_compound)
12352 	{
12353 	  construct = "acc exit data";
12354 	  goto in_compound;
12355 	}
12356       c_parser_oacc_enter_exit_data (parser, false);
12357       return false;
12358 
12359     case PRAGMA_OACC_ROUTINE:
12360       if (context != pragma_external)
12361 	{
12362 	  error_at (c_parser_peek_token (parser)->location,
12363 		    "%<#pragma acc routine%> must be at file scope");
12364 	  c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12365 	  return false;
12366 	}
12367       c_parser_oacc_routine (parser, context);
12368       return false;
12369 
12370     case PRAGMA_OACC_UPDATE:
12371       if (context != pragma_compound)
12372 	{
12373 	  construct = "acc update";
12374 	  goto in_compound;
12375 	}
12376       c_parser_oacc_update (parser);
12377       return false;
12378 
12379     case PRAGMA_OMP_BARRIER:
12380       if (context != pragma_compound)
12381 	{
12382 	  construct = "omp barrier";
12383 	  goto in_compound;
12384 	}
12385       c_parser_omp_barrier (parser);
12386       return false;
12387 
12388     case PRAGMA_OMP_DEPOBJ:
12389       if (context != pragma_compound)
12390 	{
12391 	  construct = "omp depobj";
12392 	  goto in_compound;
12393 	}
12394       c_parser_omp_depobj (parser);
12395       return false;
12396 
12397     case PRAGMA_OMP_FLUSH:
12398       if (context != pragma_compound)
12399 	{
12400 	  construct = "omp flush";
12401 	  goto in_compound;
12402 	}
12403       c_parser_omp_flush (parser);
12404       return false;
12405 
12406     case PRAGMA_OMP_TASKWAIT:
12407       if (context != pragma_compound)
12408 	{
12409 	  construct = "omp taskwait";
12410 	  goto in_compound;
12411 	}
12412       c_parser_omp_taskwait (parser);
12413       return false;
12414 
12415     case PRAGMA_OMP_TASKYIELD:
12416       if (context != pragma_compound)
12417 	{
12418 	  construct = "omp taskyield";
12419 	  goto in_compound;
12420 	}
12421       c_parser_omp_taskyield (parser);
12422       return false;
12423 
12424     case PRAGMA_OMP_CANCEL:
12425       if (context != pragma_compound)
12426 	{
12427 	  construct = "omp cancel";
12428 	  goto in_compound;
12429 	}
12430       c_parser_omp_cancel (parser);
12431       return false;
12432 
12433     case PRAGMA_OMP_CANCELLATION_POINT:
12434       c_parser_omp_cancellation_point (parser, context);
12435       return false;
12436 
12437     case PRAGMA_OMP_THREADPRIVATE:
12438       c_parser_omp_threadprivate (parser);
12439       return false;
12440 
12441     case PRAGMA_OMP_TARGET:
12442       return c_parser_omp_target (parser, context, if_p);
12443 
12444     case PRAGMA_OMP_END_DECLARE_TARGET:
12445       c_parser_omp_end_declare_target (parser);
12446       return false;
12447 
12448     case PRAGMA_OMP_SCAN:
12449       error_at (c_parser_peek_token (parser)->location,
12450 		"%<#pragma omp scan%> may only be used in "
12451 		"a loop construct with %<inscan%> %<reduction%> clause");
12452       c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12453       return false;
12454 
12455     case PRAGMA_OMP_SECTION:
12456       error_at (c_parser_peek_token (parser)->location,
12457 		"%<#pragma omp section%> may only be used in "
12458 		"%<#pragma omp sections%> construct");
12459       c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12460       return false;
12461 
12462     case PRAGMA_OMP_DECLARE:
12463       c_parser_omp_declare (parser, context);
12464       return false;
12465 
12466     case PRAGMA_OMP_REQUIRES:
12467       if (context != pragma_external)
12468 	{
12469 	  error_at (c_parser_peek_token (parser)->location,
12470 		    "%<#pragma omp requires%> may only be used at file scope");
12471 	  c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12472 	  return false;
12473 	}
12474       c_parser_omp_requires (parser);
12475       return false;
12476 
12477     case PRAGMA_OMP_ORDERED:
12478       return c_parser_omp_ordered (parser, context, if_p);
12479 
12480     case PRAGMA_IVDEP:
12481       {
12482 	const bool ivdep = c_parse_pragma_ivdep (parser);
12483 	unsigned short unroll;
12484 	if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_UNROLL)
12485 	  unroll = c_parser_pragma_unroll (parser);
12486 	else
12487 	  unroll = 0;
12488 	if (!c_parser_next_token_is_keyword (parser, RID_FOR)
12489 	    && !c_parser_next_token_is_keyword (parser, RID_WHILE)
12490 	    && !c_parser_next_token_is_keyword (parser, RID_DO))
12491 	  {
12492 	    c_parser_error (parser, "for, while or do statement expected");
12493 	    return false;
12494 	  }
12495 	if (c_parser_next_token_is_keyword (parser, RID_FOR))
12496 	  c_parser_for_statement (parser, ivdep, unroll, if_p);
12497 	else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
12498 	  c_parser_while_statement (parser, ivdep, unroll, if_p);
12499 	else
12500 	  c_parser_do_statement (parser, ivdep, unroll);
12501       }
12502       return false;
12503 
12504     case PRAGMA_UNROLL:
12505       {
12506 	unsigned short unroll = c_parser_pragma_unroll (parser);
12507 	bool ivdep;
12508 	if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_IVDEP)
12509 	  ivdep = c_parse_pragma_ivdep (parser);
12510 	else
12511 	  ivdep = false;
12512 	if (!c_parser_next_token_is_keyword (parser, RID_FOR)
12513 	    && !c_parser_next_token_is_keyword (parser, RID_WHILE)
12514 	    && !c_parser_next_token_is_keyword (parser, RID_DO))
12515 	  {
12516 	    c_parser_error (parser, "for, while or do statement expected");
12517 	    return false;
12518 	  }
12519 	if (c_parser_next_token_is_keyword (parser, RID_FOR))
12520 	  c_parser_for_statement (parser, ivdep, unroll, if_p);
12521 	else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
12522 	  c_parser_while_statement (parser, ivdep, unroll, if_p);
12523 	else
12524 	  c_parser_do_statement (parser, ivdep, unroll);
12525       }
12526       return false;
12527 
12528     case PRAGMA_GCC_PCH_PREPROCESS:
12529       c_parser_error (parser, "%<#pragma GCC pch_preprocess%> must be first");
12530       c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12531       return false;
12532 
12533     case PRAGMA_OACC_WAIT:
12534       if (context != pragma_compound)
12535 	{
12536 	  construct = "acc wait";
12537 	  goto in_compound;
12538 	}
12539 	/* FALL THROUGH.  */
12540 
12541     default:
12542       if (id < PRAGMA_FIRST_EXTERNAL)
12543 	{
12544 	  if (context != pragma_stmt && context != pragma_compound)
12545 	    {
12546 	    bad_stmt:
12547 	      c_parser_error (parser, "expected declaration specifiers");
12548 	      c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12549 	      return false;
12550 	    }
12551 	  c_parser_omp_construct (parser, if_p);
12552 	  return true;
12553 	}
12554       break;
12555     }
12556 
12557   c_parser_consume_pragma (parser);
12558   c_invoke_pragma_handler (id);
12559 
12560   /* Skip to EOL, but suppress any error message.  Those will have been
12561      generated by the handler routine through calling error, as opposed
12562      to calling c_parser_error.  */
12563   parser->error = true;
12564   c_parser_skip_to_pragma_eol (parser);
12565 
12566   return false;
12567 }
12568 
12569 /* The interface the pragma parsers have to the lexer.  */
12570 
12571 enum cpp_ttype
pragma_lex(tree * value,location_t * loc)12572 pragma_lex (tree *value, location_t *loc)
12573 {
12574   c_token *tok = c_parser_peek_token (the_parser);
12575   enum cpp_ttype ret = tok->type;
12576 
12577   *value = tok->value;
12578   if (loc)
12579     *loc = tok->location;
12580 
12581   if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF)
12582     ret = CPP_EOF;
12583   else if (ret == CPP_STRING)
12584     *value = c_parser_string_literal (the_parser, false, false).value;
12585   else
12586     {
12587       if (ret == CPP_KEYWORD)
12588 	ret = CPP_NAME;
12589       c_parser_consume_token (the_parser);
12590     }
12591 
12592   return ret;
12593 }
12594 
12595 static void
c_parser_pragma_pch_preprocess(c_parser * parser)12596 c_parser_pragma_pch_preprocess (c_parser *parser)
12597 {
12598   tree name = NULL;
12599 
12600   parser->lex_joined_string = true;
12601   c_parser_consume_pragma (parser);
12602   if (c_parser_next_token_is (parser, CPP_STRING))
12603     {
12604       name = c_parser_peek_token (parser)->value;
12605       c_parser_consume_token (parser);
12606     }
12607   else
12608     c_parser_error (parser, "expected string literal");
12609   c_parser_skip_to_pragma_eol (parser);
12610   parser->lex_joined_string = false;
12611 
12612   if (name)
12613     c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name));
12614 }
12615 
12616 /* OpenACC and OpenMP parsing routines.  */
12617 
12618 /* Returns name of the next clause.
12619    If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
12620    the token is not consumed.  Otherwise appropriate pragma_omp_clause is
12621    returned and the token is consumed.  */
12622 
12623 static pragma_omp_clause
c_parser_omp_clause_name(c_parser * parser)12624 c_parser_omp_clause_name (c_parser *parser)
12625 {
12626   pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;
12627 
12628   if (c_parser_next_token_is_keyword (parser, RID_AUTO))
12629     result = PRAGMA_OACC_CLAUSE_AUTO;
12630   else if (c_parser_next_token_is_keyword (parser, RID_IF))
12631     result = PRAGMA_OMP_CLAUSE_IF;
12632   else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
12633     result = PRAGMA_OMP_CLAUSE_DEFAULT;
12634   else if (c_parser_next_token_is_keyword (parser, RID_FOR))
12635     result = PRAGMA_OMP_CLAUSE_FOR;
12636   else if (c_parser_next_token_is (parser, CPP_NAME))
12637     {
12638       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
12639 
12640       switch (p[0])
12641 	{
12642 	case 'a':
12643 	  if (!strcmp ("aligned", p))
12644 	    result = PRAGMA_OMP_CLAUSE_ALIGNED;
12645 	  else if (!strcmp ("async", p))
12646 	    result = PRAGMA_OACC_CLAUSE_ASYNC;
12647 	  else if (!strcmp ("attach", p))
12648 	    result = PRAGMA_OACC_CLAUSE_ATTACH;
12649 	  break;
12650 	case 'b':
12651 	  if (!strcmp ("bind", p))
12652 	    result = PRAGMA_OMP_CLAUSE_BIND;
12653 	  break;
12654 	case 'c':
12655 	  if (!strcmp ("collapse", p))
12656 	    result = PRAGMA_OMP_CLAUSE_COLLAPSE;
12657 	  else if (!strcmp ("copy", p))
12658 	    result = PRAGMA_OACC_CLAUSE_COPY;
12659 	  else if (!strcmp ("copyin", p))
12660 	    result = PRAGMA_OMP_CLAUSE_COPYIN;
12661 	  else if (!strcmp ("copyout", p))
12662 	    result = PRAGMA_OACC_CLAUSE_COPYOUT;
12663           else if (!strcmp ("copyprivate", p))
12664 	    result = PRAGMA_OMP_CLAUSE_COPYPRIVATE;
12665 	  else if (!strcmp ("create", p))
12666 	    result = PRAGMA_OACC_CLAUSE_CREATE;
12667 	  break;
12668 	case 'd':
12669 	  if (!strcmp ("defaultmap", p))
12670 	    result = PRAGMA_OMP_CLAUSE_DEFAULTMAP;
12671 	  else if (!strcmp ("delete", p))
12672 	    result = PRAGMA_OACC_CLAUSE_DELETE;
12673 	  else if (!strcmp ("depend", p))
12674 	    result = PRAGMA_OMP_CLAUSE_DEPEND;
12675 	  else if (!strcmp ("detach", p))
12676 	    result = PRAGMA_OACC_CLAUSE_DETACH;
12677 	  else if (!strcmp ("device", p))
12678 	    result = PRAGMA_OMP_CLAUSE_DEVICE;
12679 	  else if (!strcmp ("deviceptr", p))
12680 	    result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
12681 	  else if (!strcmp ("device_resident", p))
12682 	    result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
12683 	  else if (!strcmp ("device_type", p))
12684 	    result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
12685 	  else if (!strcmp ("dist_schedule", p))
12686 	    result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
12687 	  break;
12688 	case 'f':
12689 	  if (!strcmp ("final", p))
12690 	    result = PRAGMA_OMP_CLAUSE_FINAL;
12691 	  else if (!strcmp ("finalize", p))
12692 	    result = PRAGMA_OACC_CLAUSE_FINALIZE;
12693 	  else if (!strcmp ("firstprivate", p))
12694 	    result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
12695 	  else if (!strcmp ("from", p))
12696 	    result = PRAGMA_OMP_CLAUSE_FROM;
12697 	  break;
12698 	case 'g':
12699 	  if (!strcmp ("gang", p))
12700 	    result = PRAGMA_OACC_CLAUSE_GANG;
12701 	  else if (!strcmp ("grainsize", p))
12702 	    result = PRAGMA_OMP_CLAUSE_GRAINSIZE;
12703 	  break;
12704 	case 'h':
12705 	  if (!strcmp ("hint", p))
12706 	    result = PRAGMA_OMP_CLAUSE_HINT;
12707 	  else if (!strcmp ("host", p))
12708 	    result = PRAGMA_OACC_CLAUSE_HOST;
12709 	  break;
12710 	case 'i':
12711 	  if (!strcmp ("if_present", p))
12712 	    result = PRAGMA_OACC_CLAUSE_IF_PRESENT;
12713 	  else if (!strcmp ("in_reduction", p))
12714 	    result = PRAGMA_OMP_CLAUSE_IN_REDUCTION;
12715 	  else if (!strcmp ("inbranch", p))
12716 	    result = PRAGMA_OMP_CLAUSE_INBRANCH;
12717 	  else if (!strcmp ("independent", p))
12718 	    result = PRAGMA_OACC_CLAUSE_INDEPENDENT;
12719 	  else if (!strcmp ("is_device_ptr", p))
12720 	    result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR;
12721 	  break;
12722 	case 'l':
12723 	  if (!strcmp ("lastprivate", p))
12724 	    result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
12725 	  else if (!strcmp ("linear", p))
12726 	    result = PRAGMA_OMP_CLAUSE_LINEAR;
12727 	  else if (!strcmp ("link", p))
12728 	    result = PRAGMA_OMP_CLAUSE_LINK;
12729 	  break;
12730 	case 'm':
12731 	  if (!strcmp ("map", p))
12732 	    result = PRAGMA_OMP_CLAUSE_MAP;
12733 	  else if (!strcmp ("mergeable", p))
12734 	    result = PRAGMA_OMP_CLAUSE_MERGEABLE;
12735 	  break;
12736 	case 'n':
12737 	  if (!strcmp ("no_create", p))
12738 	    result = PRAGMA_OACC_CLAUSE_NO_CREATE;
12739 	  else if (!strcmp ("nogroup", p))
12740 	    result = PRAGMA_OMP_CLAUSE_NOGROUP;
12741 	  else if (!strcmp ("nontemporal", p))
12742 	    result = PRAGMA_OMP_CLAUSE_NONTEMPORAL;
12743 	  else if (!strcmp ("notinbranch", p))
12744 	    result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
12745 	  else if (!strcmp ("nowait", p))
12746 	    result = PRAGMA_OMP_CLAUSE_NOWAIT;
12747 	  else if (!strcmp ("num_gangs", p))
12748 	    result = PRAGMA_OACC_CLAUSE_NUM_GANGS;
12749 	  else if (!strcmp ("num_tasks", p))
12750 	    result = PRAGMA_OMP_CLAUSE_NUM_TASKS;
12751 	  else if (!strcmp ("num_teams", p))
12752 	    result = PRAGMA_OMP_CLAUSE_NUM_TEAMS;
12753 	  else if (!strcmp ("num_threads", p))
12754 	    result = PRAGMA_OMP_CLAUSE_NUM_THREADS;
12755 	  else if (!strcmp ("num_workers", p))
12756 	    result = PRAGMA_OACC_CLAUSE_NUM_WORKERS;
12757 	  break;
12758 	case 'o':
12759 	  if (!strcmp ("ordered", p))
12760 	    result = PRAGMA_OMP_CLAUSE_ORDERED;
12761 	  else if (!strcmp ("order", p))
12762 	    result = PRAGMA_OMP_CLAUSE_ORDER;
12763 	  break;
12764 	case 'p':
12765 	  if (!strcmp ("parallel", p))
12766 	    result = PRAGMA_OMP_CLAUSE_PARALLEL;
12767 	  else if (!strcmp ("present", p))
12768 	    result = PRAGMA_OACC_CLAUSE_PRESENT;
12769 	  /* As of OpenACC 2.5, these are now aliases of the non-present_or
12770 	     clauses.  */
12771 	  else if (!strcmp ("present_or_copy", p)
12772 		   || !strcmp ("pcopy", p))
12773 	    result = PRAGMA_OACC_CLAUSE_COPY;
12774 	  else if (!strcmp ("present_or_copyin", p)
12775 		   || !strcmp ("pcopyin", p))
12776 	    result = PRAGMA_OACC_CLAUSE_COPYIN;
12777 	  else if (!strcmp ("present_or_copyout", p)
12778 		   || !strcmp ("pcopyout", p))
12779 	    result = PRAGMA_OACC_CLAUSE_COPYOUT;
12780 	  else if (!strcmp ("present_or_create", p)
12781 		   || !strcmp ("pcreate", p))
12782 	    result = PRAGMA_OACC_CLAUSE_CREATE;
12783 	  else if (!strcmp ("priority", p))
12784 	    result = PRAGMA_OMP_CLAUSE_PRIORITY;
12785 	  else if (!strcmp ("private", p))
12786 	    result = PRAGMA_OMP_CLAUSE_PRIVATE;
12787 	  else if (!strcmp ("proc_bind", p))
12788 	    result = PRAGMA_OMP_CLAUSE_PROC_BIND;
12789 	  break;
12790 	case 'r':
12791 	  if (!strcmp ("reduction", p))
12792 	    result = PRAGMA_OMP_CLAUSE_REDUCTION;
12793 	  break;
12794 	case 's':
12795 	  if (!strcmp ("safelen", p))
12796 	    result = PRAGMA_OMP_CLAUSE_SAFELEN;
12797 	  else if (!strcmp ("schedule", p))
12798 	    result = PRAGMA_OMP_CLAUSE_SCHEDULE;
12799 	  else if (!strcmp ("sections", p))
12800 	    result = PRAGMA_OMP_CLAUSE_SECTIONS;
12801 	  else if (!strcmp ("self", p)) /* "self" is a synonym for "host".  */
12802 	    result = PRAGMA_OACC_CLAUSE_HOST;
12803 	  else if (!strcmp ("seq", p))
12804 	    result = PRAGMA_OACC_CLAUSE_SEQ;
12805 	  else if (!strcmp ("shared", p))
12806 	    result = PRAGMA_OMP_CLAUSE_SHARED;
12807 	  else if (!strcmp ("simd", p))
12808 	    result = PRAGMA_OMP_CLAUSE_SIMD;
12809 	  else if (!strcmp ("simdlen", p))
12810 	    result = PRAGMA_OMP_CLAUSE_SIMDLEN;
12811 	  break;
12812 	case 't':
12813 	  if (!strcmp ("task_reduction", p))
12814 	    result = PRAGMA_OMP_CLAUSE_TASK_REDUCTION;
12815 	  else if (!strcmp ("taskgroup", p))
12816 	    result = PRAGMA_OMP_CLAUSE_TASKGROUP;
12817 	  else if (!strcmp ("thread_limit", p))
12818 	    result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT;
12819 	  else if (!strcmp ("threads", p))
12820 	    result = PRAGMA_OMP_CLAUSE_THREADS;
12821 	  else if (!strcmp ("tile", p))
12822 	    result = PRAGMA_OACC_CLAUSE_TILE;
12823 	  else if (!strcmp ("to", p))
12824 	    result = PRAGMA_OMP_CLAUSE_TO;
12825 	  break;
12826 	case 'u':
12827 	  if (!strcmp ("uniform", p))
12828 	    result = PRAGMA_OMP_CLAUSE_UNIFORM;
12829 	  else if (!strcmp ("untied", p))
12830 	    result = PRAGMA_OMP_CLAUSE_UNTIED;
12831 	  else if (!strcmp ("use_device", p))
12832 	    result = PRAGMA_OACC_CLAUSE_USE_DEVICE;
12833 	  else if (!strcmp ("use_device_addr", p))
12834 	    result = PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR;
12835 	  else if (!strcmp ("use_device_ptr", p))
12836 	    result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR;
12837 	  break;
12838 	case 'v':
12839 	  if (!strcmp ("vector", p))
12840 	    result = PRAGMA_OACC_CLAUSE_VECTOR;
12841 	  else if (!strcmp ("vector_length", p))
12842 	    result = PRAGMA_OACC_CLAUSE_VECTOR_LENGTH;
12843 	  break;
12844 	case 'w':
12845 	  if (!strcmp ("wait", p))
12846 	    result = PRAGMA_OACC_CLAUSE_WAIT;
12847 	  else if (!strcmp ("worker", p))
12848 	    result = PRAGMA_OACC_CLAUSE_WORKER;
12849 	  break;
12850 	}
12851     }
12852 
12853   if (result != PRAGMA_OMP_CLAUSE_NONE)
12854     c_parser_consume_token (parser);
12855 
12856   return result;
12857 }
12858 
12859 /* Validate that a clause of the given type does not already exist.  */
12860 
12861 static void
check_no_duplicate_clause(tree clauses,enum omp_clause_code code,const char * name)12862 check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
12863 			   const char *name)
12864 {
12865   if (tree c = omp_find_clause (clauses, code))
12866     error_at (OMP_CLAUSE_LOCATION (c), "too many %qs clauses", name);
12867 }
12868 
12869 /* OpenACC 2.0
12870    Parse wait clause or wait directive parameters.  */
12871 
12872 static tree
c_parser_oacc_wait_list(c_parser * parser,location_t clause_loc,tree list)12873 c_parser_oacc_wait_list (c_parser *parser, location_t clause_loc, tree list)
12874 {
12875   vec<tree, va_gc> *args;
12876   tree t, args_tree;
12877 
12878   matching_parens parens;
12879   if (!parens.require_open (parser))
12880     return list;
12881 
12882   args = c_parser_expr_list (parser, false, true, NULL, NULL, NULL, NULL);
12883   args_tree = build_tree_list_vec (args);
12884 
12885   for (t = args_tree; t; t = TREE_CHAIN (t))
12886     {
12887       tree targ = TREE_VALUE (t);
12888 
12889       if (targ != error_mark_node)
12890 	{
12891 	  if (!INTEGRAL_TYPE_P (TREE_TYPE (targ)))
12892 	    {
12893 	      c_parser_error (parser, "expression must be integral");
12894 	      targ = error_mark_node;
12895 	    }
12896 	  else
12897 	    {
12898 	      tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
12899 
12900 	      OMP_CLAUSE_DECL (c) = targ;
12901 	      OMP_CLAUSE_CHAIN (c) = list;
12902 	      list = c;
12903 	    }
12904 	}
12905     }
12906 
12907   release_tree_vector (args);
12908   parens.require_close (parser);
12909   return list;
12910 }
12911 
12912 /* OpenACC 2.0, OpenMP 2.5:
12913    variable-list:
12914      identifier
12915      variable-list , identifier
12916 
12917    If KIND is nonzero, create the appropriate node and install the
12918    decl in OMP_CLAUSE_DECL and add the node to the head of the list.
12919    If KIND is nonzero, CLAUSE_LOC is the location of the clause.
12920 
12921    If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
12922    return the list created.
12923 
12924    The optional ALLOW_DEREF argument is true if list items can use the deref
12925    (->) operator.  */
12926 
12927 static tree
12928 c_parser_omp_variable_list (c_parser *parser,
12929 			    location_t clause_loc,
12930 			    enum omp_clause_code kind, tree list,
12931 			    bool allow_deref = false)
12932 {
12933   auto_vec<c_token> tokens;
12934   unsigned int tokens_avail = 0;
12935   bool first = true;
12936 
12937   while (1)
12938     {
12939       bool array_section_p = false;
12940       if (kind == OMP_CLAUSE_DEPEND)
12941 	{
12942 	  if (c_parser_next_token_is_not (parser, CPP_NAME)
12943 	      || c_parser_peek_token (parser)->id_kind != C_ID_ID)
12944 	    {
12945 	      struct c_expr expr = c_parser_expr_no_commas (parser, NULL);
12946 	      if (expr.value != error_mark_node)
12947 		{
12948 		  tree u = build_omp_clause (clause_loc, kind);
12949 		  OMP_CLAUSE_DECL (u) = expr.value;
12950 		  OMP_CLAUSE_CHAIN (u) = list;
12951 		  list = u;
12952 		}
12953 
12954 	      if (c_parser_next_token_is_not (parser, CPP_COMMA))
12955 		break;
12956 
12957 	      c_parser_consume_token (parser);
12958 	      first = false;
12959 	      continue;
12960 	    }
12961 
12962 	  tokens.truncate (0);
12963 	  unsigned int nesting_depth = 0;
12964 	  while (1)
12965 	    {
12966 	      c_token *token = c_parser_peek_token (parser);
12967 	      switch (token->type)
12968 		{
12969 		case CPP_EOF:
12970 		case CPP_PRAGMA_EOL:
12971 		  break;
12972 		case CPP_OPEN_BRACE:
12973 		case CPP_OPEN_PAREN:
12974 		case CPP_OPEN_SQUARE:
12975 		  ++nesting_depth;
12976 		  goto add;
12977 		case CPP_CLOSE_BRACE:
12978 		case CPP_CLOSE_PAREN:
12979 		case CPP_CLOSE_SQUARE:
12980 		  if (nesting_depth-- == 0)
12981 		    break;
12982 		  goto add;
12983 		case CPP_COMMA:
12984 		  if (nesting_depth == 0)
12985 		    break;
12986 		  goto add;
12987 		default:
12988 		add:
12989 		  tokens.safe_push (*token);
12990 		  c_parser_consume_token (parser);
12991 		  continue;
12992 		}
12993 	      break;
12994 	    }
12995 
12996 	  /* Make sure nothing tries to read past the end of the tokens.  */
12997 	  c_token eof_token;
12998 	  memset (&eof_token, 0, sizeof (eof_token));
12999 	  eof_token.type = CPP_EOF;
13000 	  tokens.safe_push (eof_token);
13001 	  tokens.safe_push (eof_token);
13002 
13003 	  tokens_avail = parser->tokens_avail;
13004 	  gcc_assert (parser->tokens == &parser->tokens_buf[0]);
13005 	  parser->tokens = tokens.address ();
13006 	  parser->tokens_avail = tokens.length ();
13007 	}
13008 
13009       tree t = NULL_TREE;
13010 
13011       if (c_parser_next_token_is (parser, CPP_NAME)
13012 	  && c_parser_peek_token (parser)->id_kind == C_ID_ID)
13013 	{
13014 	  t = lookup_name (c_parser_peek_token (parser)->value);
13015 
13016 	  if (t == NULL_TREE)
13017 	    {
13018 	      undeclared_variable (c_parser_peek_token (parser)->location,
13019 	      c_parser_peek_token (parser)->value);
13020 	      t = error_mark_node;
13021 	    }
13022 
13023 	  c_parser_consume_token (parser);
13024 	}
13025       else if (c_parser_next_token_is (parser, CPP_KEYWORD)
13026 	       && (c_parser_peek_token (parser)->keyword == RID_FUNCTION_NAME
13027 		   || (c_parser_peek_token (parser)->keyword
13028 		       == RID_PRETTY_FUNCTION_NAME)
13029 		   || (c_parser_peek_token (parser)->keyword
13030 		       == RID_C99_FUNCTION_NAME)))
13031 	t = c_parser_predefined_identifier (parser).value;
13032       else
13033 	{
13034 	  if (first)
13035 	    c_parser_error (parser, "expected identifier");
13036 	  break;
13037 	}
13038 
13039       if (t == error_mark_node)
13040 	;
13041       else if (kind != 0)
13042 	{
13043 	  switch (kind)
13044 	    {
13045 	    case OMP_CLAUSE__CACHE_:
13046 	      /* The OpenACC cache directive explicitly only allows "array
13047 		 elements or subarrays".  */
13048 	      if (c_parser_peek_token (parser)->type != CPP_OPEN_SQUARE)
13049 		{
13050 		  c_parser_error (parser, "expected %<[%>");
13051 		  t = error_mark_node;
13052 		  break;
13053 		}
13054 	      /* FALLTHROUGH  */
13055 	    case OMP_CLAUSE_MAP:
13056 	    case OMP_CLAUSE_FROM:
13057 	    case OMP_CLAUSE_TO:
13058 	      while (c_parser_next_token_is (parser, CPP_DOT)
13059 		     || (allow_deref
13060 			 && c_parser_next_token_is (parser, CPP_DEREF)))
13061 		{
13062 		  location_t op_loc = c_parser_peek_token (parser)->location;
13063 		  if (c_parser_next_token_is (parser, CPP_DEREF))
13064 		    t = build_simple_mem_ref (t);
13065 		  c_parser_consume_token (parser);
13066 		  if (!c_parser_next_token_is (parser, CPP_NAME))
13067 		    {
13068 		      c_parser_error (parser, "expected identifier");
13069 		      t = error_mark_node;
13070 		      break;
13071 		    }
13072 
13073 		  c_token *comp_tok = c_parser_peek_token (parser);
13074 		  tree ident = comp_tok->value;
13075 		  location_t comp_loc = comp_tok->location;
13076 		  c_parser_consume_token (parser);
13077 		  t = build_component_ref (op_loc, t, ident, comp_loc);
13078 		}
13079 	      /* FALLTHROUGH  */
13080 	    case OMP_CLAUSE_DEPEND:
13081 	    case OMP_CLAUSE_REDUCTION:
13082 	    case OMP_CLAUSE_IN_REDUCTION:
13083 	    case OMP_CLAUSE_TASK_REDUCTION:
13084 	      while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
13085 		{
13086 		  tree low_bound = NULL_TREE, length = NULL_TREE;
13087 
13088 		  c_parser_consume_token (parser);
13089 		  if (!c_parser_next_token_is (parser, CPP_COLON))
13090 		    {
13091 		      location_t expr_loc
13092 			= c_parser_peek_token (parser)->location;
13093 		      c_expr expr = c_parser_expression (parser);
13094 		      expr = convert_lvalue_to_rvalue (expr_loc, expr,
13095 						       false, true);
13096 		      low_bound = expr.value;
13097 		    }
13098 		  if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
13099 		    length = integer_one_node;
13100 		  else
13101 		    {
13102 		      /* Look for `:'.  */
13103 		      if (!c_parser_require (parser, CPP_COLON,
13104 					     "expected %<:%>"))
13105 			{
13106 			  t = error_mark_node;
13107 			  break;
13108 			}
13109 		      array_section_p = true;
13110 		      if (!c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
13111 			{
13112 			  location_t expr_loc
13113 			    = c_parser_peek_token (parser)->location;
13114 			  c_expr expr = c_parser_expression (parser);
13115 			  expr = convert_lvalue_to_rvalue (expr_loc, expr,
13116 							   false, true);
13117 			  length = expr.value;
13118 			}
13119 		    }
13120 		  /* Look for the closing `]'.  */
13121 		  if (!c_parser_require (parser, CPP_CLOSE_SQUARE,
13122 					 "expected %<]%>"))
13123 		    {
13124 		      t = error_mark_node;
13125 		      break;
13126 		    }
13127 
13128 		  t = tree_cons (low_bound, length, t);
13129 		}
13130 	      if (kind == OMP_CLAUSE_DEPEND
13131 		  && t != error_mark_node
13132 		  && parser->tokens_avail != 2)
13133 		{
13134 		  if (array_section_p)
13135 		    {
13136 		      error_at (c_parser_peek_token (parser)->location,
13137 				"expected %<)%> or %<,%>");
13138 		      t = error_mark_node;
13139 		    }
13140 		  else
13141 		    {
13142 		      parser->tokens = tokens.address ();
13143 		      parser->tokens_avail = tokens.length ();
13144 
13145 		      t = c_parser_expr_no_commas (parser, NULL).value;
13146 		      if (t != error_mark_node && parser->tokens_avail != 2)
13147 			{
13148 			  error_at (c_parser_peek_token (parser)->location,
13149 				    "expected %<)%> or %<,%>");
13150 			  t = error_mark_node;
13151 			}
13152 		    }
13153 		}
13154 	      break;
13155 	    default:
13156 	      break;
13157 	    }
13158 
13159 	  if (t != error_mark_node)
13160 	    {
13161 	      tree u = build_omp_clause (clause_loc, kind);
13162 	      OMP_CLAUSE_DECL (u) = t;
13163 	      OMP_CLAUSE_CHAIN (u) = list;
13164 	      list = u;
13165 	    }
13166 	}
13167       else
13168 	list = tree_cons (t, NULL_TREE, list);
13169 
13170       if (kind == OMP_CLAUSE_DEPEND)
13171 	{
13172 	  parser->tokens = &parser->tokens_buf[0];
13173 	  parser->tokens_avail = tokens_avail;
13174 	}
13175       if (c_parser_next_token_is_not (parser, CPP_COMMA))
13176 	break;
13177 
13178       c_parser_consume_token (parser);
13179       first = false;
13180     }
13181 
13182   return list;
13183 }
13184 
13185 /* Similarly, but expect leading and trailing parenthesis.  This is a very
13186    common case for OpenACC and OpenMP clauses.  The optional ALLOW_DEREF
13187    argument is true if list items can use the deref (->) operator.  */
13188 
13189 static tree
13190 c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind,
13191 			      tree list, bool allow_deref = false)
13192 {
13193   /* The clauses location.  */
13194   location_t loc = c_parser_peek_token (parser)->location;
13195 
13196   matching_parens parens;
13197   if (parens.require_open (parser))
13198     {
13199       list = c_parser_omp_variable_list (parser, loc, kind, list, allow_deref);
13200       parens.skip_until_found_close (parser);
13201     }
13202   return list;
13203 }
13204 
13205 /* OpenACC 2.0:
13206    copy ( variable-list )
13207    copyin ( variable-list )
13208    copyout ( variable-list )
13209    create ( variable-list )
13210    delete ( variable-list )
13211    present ( variable-list )
13212 
13213    OpenACC 2.6:
13214    no_create ( variable-list )
13215    attach ( variable-list )
13216    detach ( variable-list ) */
13217 
13218 static tree
c_parser_oacc_data_clause(c_parser * parser,pragma_omp_clause c_kind,tree list)13219 c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind,
13220 			   tree list)
13221 {
13222   enum gomp_map_kind kind;
13223   switch (c_kind)
13224     {
13225     case PRAGMA_OACC_CLAUSE_ATTACH:
13226       kind = GOMP_MAP_ATTACH;
13227       break;
13228     case PRAGMA_OACC_CLAUSE_COPY:
13229       kind = GOMP_MAP_TOFROM;
13230       break;
13231     case PRAGMA_OACC_CLAUSE_COPYIN:
13232       kind = GOMP_MAP_TO;
13233       break;
13234     case PRAGMA_OACC_CLAUSE_COPYOUT:
13235       kind = GOMP_MAP_FROM;
13236       break;
13237     case PRAGMA_OACC_CLAUSE_CREATE:
13238       kind = GOMP_MAP_ALLOC;
13239       break;
13240     case PRAGMA_OACC_CLAUSE_DELETE:
13241       kind = GOMP_MAP_RELEASE;
13242       break;
13243     case PRAGMA_OACC_CLAUSE_DETACH:
13244       kind = GOMP_MAP_DETACH;
13245       break;
13246     case PRAGMA_OACC_CLAUSE_DEVICE:
13247       kind = GOMP_MAP_FORCE_TO;
13248       break;
13249     case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
13250       kind = GOMP_MAP_DEVICE_RESIDENT;
13251       break;
13252     case PRAGMA_OACC_CLAUSE_HOST:
13253       kind = GOMP_MAP_FORCE_FROM;
13254       break;
13255     case PRAGMA_OACC_CLAUSE_LINK:
13256       kind = GOMP_MAP_LINK;
13257       break;
13258     case PRAGMA_OACC_CLAUSE_NO_CREATE:
13259       kind = GOMP_MAP_IF_PRESENT;
13260       break;
13261     case PRAGMA_OACC_CLAUSE_PRESENT:
13262       kind = GOMP_MAP_FORCE_PRESENT;
13263       break;
13264     default:
13265       gcc_unreachable ();
13266     }
13267   tree nl, c;
13268   nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_MAP, list, true);
13269 
13270   for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
13271     OMP_CLAUSE_SET_MAP_KIND (c, kind);
13272 
13273   return nl;
13274 }
13275 
13276 /* OpenACC 2.0:
13277    deviceptr ( variable-list ) */
13278 
13279 static tree
c_parser_oacc_data_clause_deviceptr(c_parser * parser,tree list)13280 c_parser_oacc_data_clause_deviceptr (c_parser *parser, tree list)
13281 {
13282   location_t loc = c_parser_peek_token (parser)->location;
13283   tree vars, t;
13284 
13285   /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
13286      c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
13287      variable-list must only allow for pointer variables.  */
13288   vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
13289   for (t = vars; t && t; t = TREE_CHAIN (t))
13290     {
13291       tree v = TREE_PURPOSE (t);
13292 
13293       /* FIXME diagnostics: Ideally we should keep individual
13294 	 locations for all the variables in the var list to make the
13295 	 following errors more precise.  Perhaps
13296 	 c_parser_omp_var_list_parens() should construct a list of
13297 	 locations to go along with the var list.  */
13298 
13299       if (!VAR_P (v) && TREE_CODE (v) != PARM_DECL)
13300 	error_at (loc, "%qD is not a variable", v);
13301       else if (TREE_TYPE (v) == error_mark_node)
13302 	;
13303       else if (!POINTER_TYPE_P (TREE_TYPE (v)))
13304 	error_at (loc, "%qD is not a pointer variable", v);
13305 
13306       tree u = build_omp_clause (loc, OMP_CLAUSE_MAP);
13307       OMP_CLAUSE_SET_MAP_KIND (u, GOMP_MAP_FORCE_DEVICEPTR);
13308       OMP_CLAUSE_DECL (u) = v;
13309       OMP_CLAUSE_CHAIN (u) = list;
13310       list = u;
13311     }
13312 
13313   return list;
13314 }
13315 
13316 /* OpenACC 2.0, OpenMP 3.0:
13317    collapse ( constant-expression ) */
13318 
13319 static tree
c_parser_omp_clause_collapse(c_parser * parser,tree list)13320 c_parser_omp_clause_collapse (c_parser *parser, tree list)
13321 {
13322   tree c, num = error_mark_node;
13323   HOST_WIDE_INT n;
13324   location_t loc;
13325 
13326   check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
13327   check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
13328 
13329   loc = c_parser_peek_token (parser)->location;
13330   matching_parens parens;
13331   if (parens.require_open (parser))
13332     {
13333       num = c_parser_expr_no_commas (parser, NULL).value;
13334       parens.skip_until_found_close (parser);
13335     }
13336   if (num == error_mark_node)
13337     return list;
13338   mark_exp_read (num);
13339   num = c_fully_fold (num, false, NULL);
13340   if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
13341       || !tree_fits_shwi_p (num)
13342       || (n = tree_to_shwi (num)) <= 0
13343       || (int) n != n)
13344     {
13345       error_at (loc,
13346 		"collapse argument needs positive constant integer expression");
13347       return list;
13348     }
13349   c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE);
13350   OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
13351   OMP_CLAUSE_CHAIN (c) = list;
13352   return c;
13353 }
13354 
13355 /* OpenMP 2.5:
13356    copyin ( variable-list ) */
13357 
13358 static tree
c_parser_omp_clause_copyin(c_parser * parser,tree list)13359 c_parser_omp_clause_copyin (c_parser *parser, tree list)
13360 {
13361   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYIN, list);
13362 }
13363 
13364 /* OpenMP 2.5:
13365    copyprivate ( variable-list ) */
13366 
13367 static tree
c_parser_omp_clause_copyprivate(c_parser * parser,tree list)13368 c_parser_omp_clause_copyprivate (c_parser *parser, tree list)
13369 {
13370   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYPRIVATE, list);
13371 }
13372 
13373 /* OpenMP 2.5:
13374    default ( none | shared )
13375 
13376    OpenACC:
13377    default ( none | present ) */
13378 
13379 static tree
c_parser_omp_clause_default(c_parser * parser,tree list,bool is_oacc)13380 c_parser_omp_clause_default (c_parser *parser, tree list, bool is_oacc)
13381 {
13382   enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
13383   location_t loc = c_parser_peek_token (parser)->location;
13384   tree c;
13385 
13386   matching_parens parens;
13387   if (!parens.require_open (parser))
13388     return list;
13389   if (c_parser_next_token_is (parser, CPP_NAME))
13390     {
13391       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13392 
13393       switch (p[0])
13394 	{
13395 	case 'n':
13396 	  if (strcmp ("none", p) != 0)
13397 	    goto invalid_kind;
13398 	  kind = OMP_CLAUSE_DEFAULT_NONE;
13399 	  break;
13400 
13401 	case 'p':
13402 	  if (strcmp ("present", p) != 0 || !is_oacc)
13403 	    goto invalid_kind;
13404 	  kind = OMP_CLAUSE_DEFAULT_PRESENT;
13405 	  break;
13406 
13407 	case 's':
13408 	  if (strcmp ("shared", p) != 0 || is_oacc)
13409 	    goto invalid_kind;
13410 	  kind = OMP_CLAUSE_DEFAULT_SHARED;
13411 	  break;
13412 
13413 	default:
13414 	  goto invalid_kind;
13415 	}
13416 
13417       c_parser_consume_token (parser);
13418     }
13419   else
13420     {
13421     invalid_kind:
13422       if (is_oacc)
13423 	c_parser_error (parser, "expected %<none%> or %<present%>");
13424       else
13425 	c_parser_error (parser, "expected %<none%> or %<shared%>");
13426     }
13427   parens.skip_until_found_close (parser);
13428 
13429   if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED)
13430     return list;
13431 
13432   check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default");
13433   c = build_omp_clause (loc, OMP_CLAUSE_DEFAULT);
13434   OMP_CLAUSE_CHAIN (c) = list;
13435   OMP_CLAUSE_DEFAULT_KIND (c) = kind;
13436 
13437   return c;
13438 }
13439 
13440 /* OpenMP 2.5:
13441    firstprivate ( variable-list ) */
13442 
13443 static tree
c_parser_omp_clause_firstprivate(c_parser * parser,tree list)13444 c_parser_omp_clause_firstprivate (c_parser *parser, tree list)
13445 {
13446   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FIRSTPRIVATE, list);
13447 }
13448 
13449 /* OpenMP 3.1:
13450    final ( expression ) */
13451 
13452 static tree
c_parser_omp_clause_final(c_parser * parser,tree list)13453 c_parser_omp_clause_final (c_parser *parser, tree list)
13454 {
13455   location_t loc = c_parser_peek_token (parser)->location;
13456   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
13457     {
13458       matching_parens parens;
13459       tree t, c;
13460       if (!parens.require_open (parser))
13461 	t = error_mark_node;
13462       else
13463 	{
13464 	  location_t eloc = c_parser_peek_token (parser)->location;
13465 	  c_expr expr = c_parser_expr_no_commas (parser, NULL);
13466 	  t = convert_lvalue_to_rvalue (eloc, expr, true, true).value;
13467 	  t = c_objc_common_truthvalue_conversion (eloc, t);
13468 	  t = c_fully_fold (t, false, NULL);
13469 	  parens.skip_until_found_close (parser);
13470 	}
13471 
13472       check_no_duplicate_clause (list, OMP_CLAUSE_FINAL, "final");
13473 
13474       c = build_omp_clause (loc, OMP_CLAUSE_FINAL);
13475       OMP_CLAUSE_FINAL_EXPR (c) = t;
13476       OMP_CLAUSE_CHAIN (c) = list;
13477       list = c;
13478     }
13479   else
13480     c_parser_error (parser, "expected %<(%>");
13481 
13482   return list;
13483 }
13484 
13485 /* OpenACC, OpenMP 2.5:
13486    if ( expression )
13487 
13488    OpenMP 4.5:
13489    if ( directive-name-modifier : expression )
13490 
13491    directive-name-modifier:
13492      parallel | task | taskloop | target data | target | target update
13493      | target enter data | target exit data
13494 
13495    OpenMP 5.0:
13496    directive-name-modifier:
13497      ... | simd | cancel  */
13498 
13499 static tree
c_parser_omp_clause_if(c_parser * parser,tree list,bool is_omp)13500 c_parser_omp_clause_if (c_parser *parser, tree list, bool is_omp)
13501 {
13502   location_t location = c_parser_peek_token (parser)->location;
13503   enum tree_code if_modifier = ERROR_MARK;
13504 
13505   matching_parens parens;
13506   if (!parens.require_open (parser))
13507     return list;
13508 
13509   if (is_omp && c_parser_next_token_is (parser, CPP_NAME))
13510     {
13511       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13512       int n = 2;
13513       if (strcmp (p, "cancel") == 0)
13514 	if_modifier = VOID_CST;
13515       else if (strcmp (p, "parallel") == 0)
13516 	if_modifier = OMP_PARALLEL;
13517       else if (strcmp (p, "simd") == 0)
13518 	if_modifier = OMP_SIMD;
13519       else if (strcmp (p, "task") == 0)
13520 	if_modifier = OMP_TASK;
13521       else if (strcmp (p, "taskloop") == 0)
13522 	if_modifier = OMP_TASKLOOP;
13523       else if (strcmp (p, "target") == 0)
13524 	{
13525 	  if_modifier = OMP_TARGET;
13526 	  if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
13527 	    {
13528 	      p = IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser)->value);
13529 	      if (strcmp ("data", p) == 0)
13530 		if_modifier = OMP_TARGET_DATA;
13531 	      else if (strcmp ("update", p) == 0)
13532 		if_modifier = OMP_TARGET_UPDATE;
13533 	      else if (strcmp ("enter", p) == 0)
13534 		if_modifier = OMP_TARGET_ENTER_DATA;
13535 	      else if (strcmp ("exit", p) == 0)
13536 		if_modifier = OMP_TARGET_EXIT_DATA;
13537 	      if (if_modifier != OMP_TARGET)
13538 		{
13539 		  n = 3;
13540 		  c_parser_consume_token (parser);
13541 		}
13542 	      else
13543 		{
13544 		  location_t loc = c_parser_peek_2nd_token (parser)->location;
13545 		  error_at (loc, "expected %<data%>, %<update%>, %<enter%> "
13546 				 "or %<exit%>");
13547 		  if_modifier = ERROR_MARK;
13548 		}
13549 	      if (if_modifier == OMP_TARGET_ENTER_DATA
13550 		  || if_modifier == OMP_TARGET_EXIT_DATA)
13551 		{
13552 		  if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
13553 		    {
13554 		      p = IDENTIFIER_POINTER
13555 				(c_parser_peek_2nd_token (parser)->value);
13556 		      if (strcmp ("data", p) == 0)
13557 			n = 4;
13558 		    }
13559 		  if (n == 4)
13560 		    c_parser_consume_token (parser);
13561 		  else
13562 		    {
13563 		      location_t loc
13564 			= c_parser_peek_2nd_token (parser)->location;
13565 		      error_at (loc, "expected %<data%>");
13566 		      if_modifier = ERROR_MARK;
13567 		    }
13568 		}
13569 	    }
13570 	}
13571       if (if_modifier != ERROR_MARK)
13572 	{
13573 	  if (c_parser_peek_2nd_token (parser)->type == CPP_COLON)
13574 	    {
13575 	      c_parser_consume_token (parser);
13576 	      c_parser_consume_token (parser);
13577 	    }
13578 	  else
13579 	    {
13580 	      if (n > 2)
13581 		{
13582 		  location_t loc = c_parser_peek_2nd_token (parser)->location;
13583 		  error_at (loc, "expected %<:%>");
13584 		}
13585 	      if_modifier = ERROR_MARK;
13586 	    }
13587 	}
13588     }
13589 
13590   location_t loc = c_parser_peek_token (parser)->location;
13591   c_expr expr = c_parser_expr_no_commas (parser, NULL);
13592   expr = convert_lvalue_to_rvalue (loc, expr, true, true);
13593   tree t = c_objc_common_truthvalue_conversion (loc, expr.value), c;
13594   t = c_fully_fold (t, false, NULL);
13595   parens.skip_until_found_close (parser);
13596 
13597   for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
13598     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF)
13599       {
13600 	if (if_modifier != ERROR_MARK
13601 	    && OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
13602 	  {
13603 	    const char *p = NULL;
13604 	    switch (if_modifier)
13605 	      {
13606 	      case VOID_CST: p = "cancel"; break;
13607 	      case OMP_PARALLEL: p = "parallel"; break;
13608 	      case OMP_SIMD: p = "simd"; break;
13609 	      case OMP_TASK: p = "task"; break;
13610 	      case OMP_TASKLOOP: p = "taskloop"; break;
13611 	      case OMP_TARGET_DATA: p = "target data"; break;
13612 	      case OMP_TARGET: p = "target"; break;
13613 	      case OMP_TARGET_UPDATE: p = "target update"; break;
13614 	      case OMP_TARGET_ENTER_DATA: p = "target enter data"; break;
13615 	      case OMP_TARGET_EXIT_DATA: p = "target exit data"; break;
13616 	      default: gcc_unreachable ();
13617 	      }
13618 	    error_at (location, "too many %<if%> clauses with %qs modifier",
13619 		      p);
13620 	    return list;
13621 	  }
13622 	else if (OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
13623 	  {
13624 	    if (!is_omp)
13625 	      error_at (location, "too many %<if%> clauses");
13626 	    else
13627 	      error_at (location, "too many %<if%> clauses without modifier");
13628 	    return list;
13629 	  }
13630 	else if (if_modifier == ERROR_MARK
13631 		 || OMP_CLAUSE_IF_MODIFIER (c) == ERROR_MARK)
13632 	  {
13633 	    error_at (location, "if any %<if%> clause has modifier, then all "
13634 				"%<if%> clauses have to use modifier");
13635 	    return list;
13636 	  }
13637       }
13638 
13639   c = build_omp_clause (location, OMP_CLAUSE_IF);
13640   OMP_CLAUSE_IF_MODIFIER (c) = if_modifier;
13641   OMP_CLAUSE_IF_EXPR (c) = t;
13642   OMP_CLAUSE_CHAIN (c) = list;
13643   return c;
13644 }
13645 
13646 /* OpenMP 2.5:
13647    lastprivate ( variable-list )
13648 
13649    OpenMP 5.0:
13650    lastprivate ( [ lastprivate-modifier : ] variable-list ) */
13651 
13652 static tree
c_parser_omp_clause_lastprivate(c_parser * parser,tree list)13653 c_parser_omp_clause_lastprivate (c_parser *parser, tree list)
13654 {
13655   /* The clauses location.  */
13656   location_t loc = c_parser_peek_token (parser)->location;
13657 
13658   if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
13659     {
13660       bool conditional = false;
13661       if (c_parser_next_token_is (parser, CPP_NAME)
13662 	  && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
13663 	{
13664 	  const char *p
13665 	    = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13666 	  if (strcmp (p, "conditional") == 0)
13667 	    {
13668 	      conditional = true;
13669 	      c_parser_consume_token (parser);
13670 	      c_parser_consume_token (parser);
13671 	    }
13672 	}
13673       tree nlist = c_parser_omp_variable_list (parser, loc,
13674 					       OMP_CLAUSE_LASTPRIVATE, list);
13675       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
13676       if (conditional)
13677 	for (tree c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
13678 	  OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 1;
13679       return nlist;
13680     }
13681   return list;
13682 }
13683 
13684 /* OpenMP 3.1:
13685    mergeable */
13686 
13687 static tree
c_parser_omp_clause_mergeable(c_parser * parser ATTRIBUTE_UNUSED,tree list)13688 c_parser_omp_clause_mergeable (c_parser *parser ATTRIBUTE_UNUSED, tree list)
13689 {
13690   tree c;
13691 
13692   /* FIXME: Should we allow duplicates?  */
13693   check_no_duplicate_clause (list, OMP_CLAUSE_MERGEABLE, "mergeable");
13694 
13695   c = build_omp_clause (c_parser_peek_token (parser)->location,
13696 			OMP_CLAUSE_MERGEABLE);
13697   OMP_CLAUSE_CHAIN (c) = list;
13698 
13699   return c;
13700 }
13701 
13702 /* OpenMP 2.5:
13703    nowait */
13704 
13705 static tree
c_parser_omp_clause_nowait(c_parser * parser ATTRIBUTE_UNUSED,tree list)13706 c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list)
13707 {
13708   tree c;
13709   location_t loc = c_parser_peek_token (parser)->location;
13710 
13711   check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait");
13712 
13713   c = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
13714   OMP_CLAUSE_CHAIN (c) = list;
13715   return c;
13716 }
13717 
13718 /* OpenMP 2.5:
13719    num_threads ( expression ) */
13720 
13721 static tree
c_parser_omp_clause_num_threads(c_parser * parser,tree list)13722 c_parser_omp_clause_num_threads (c_parser *parser, tree list)
13723 {
13724   location_t num_threads_loc = c_parser_peek_token (parser)->location;
13725   matching_parens parens;
13726   if (parens.require_open (parser))
13727     {
13728       location_t expr_loc = c_parser_peek_token (parser)->location;
13729       c_expr expr = c_parser_expr_no_commas (parser, NULL);
13730       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13731       tree c, t = expr.value;
13732       t = c_fully_fold (t, false, NULL);
13733 
13734       parens.skip_until_found_close (parser);
13735 
13736       if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13737 	{
13738 	  c_parser_error (parser, "expected integer expression");
13739 	  return list;
13740 	}
13741 
13742       /* Attempt to statically determine when the number isn't positive.  */
13743       c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13744 		       build_int_cst (TREE_TYPE (t), 0));
13745       protected_set_expr_location (c, expr_loc);
13746       if (c == boolean_true_node)
13747 	{
13748 	  warning_at (expr_loc, 0,
13749 		      "%<num_threads%> value must be positive");
13750 	  t = integer_one_node;
13751 	}
13752 
13753       check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads");
13754 
13755       c = build_omp_clause (num_threads_loc, OMP_CLAUSE_NUM_THREADS);
13756       OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
13757       OMP_CLAUSE_CHAIN (c) = list;
13758       list = c;
13759     }
13760 
13761   return list;
13762 }
13763 
13764 /* OpenMP 4.5:
13765    num_tasks ( expression ) */
13766 
13767 static tree
c_parser_omp_clause_num_tasks(c_parser * parser,tree list)13768 c_parser_omp_clause_num_tasks (c_parser *parser, tree list)
13769 {
13770   location_t num_tasks_loc = c_parser_peek_token (parser)->location;
13771   matching_parens parens;
13772   if (parens.require_open (parser))
13773     {
13774       location_t expr_loc = c_parser_peek_token (parser)->location;
13775       c_expr expr = c_parser_expr_no_commas (parser, NULL);
13776       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13777       tree c, t = expr.value;
13778       t = c_fully_fold (t, false, NULL);
13779 
13780       parens.skip_until_found_close (parser);
13781 
13782       if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13783 	{
13784 	  c_parser_error (parser, "expected integer expression");
13785 	  return list;
13786 	}
13787 
13788       /* Attempt to statically determine when the number isn't positive.  */
13789       c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13790 			   build_int_cst (TREE_TYPE (t), 0));
13791       if (CAN_HAVE_LOCATION_P (c))
13792 	SET_EXPR_LOCATION (c, expr_loc);
13793       if (c == boolean_true_node)
13794 	{
13795 	  warning_at (expr_loc, 0, "%<num_tasks%> value must be positive");
13796 	  t = integer_one_node;
13797 	}
13798 
13799       check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TASKS, "num_tasks");
13800 
13801       c = build_omp_clause (num_tasks_loc, OMP_CLAUSE_NUM_TASKS);
13802       OMP_CLAUSE_NUM_TASKS_EXPR (c) = t;
13803       OMP_CLAUSE_CHAIN (c) = list;
13804       list = c;
13805     }
13806 
13807   return list;
13808 }
13809 
13810 /* OpenMP 4.5:
13811    grainsize ( expression ) */
13812 
13813 static tree
c_parser_omp_clause_grainsize(c_parser * parser,tree list)13814 c_parser_omp_clause_grainsize (c_parser *parser, tree list)
13815 {
13816   location_t grainsize_loc = c_parser_peek_token (parser)->location;
13817   matching_parens parens;
13818   if (parens.require_open (parser))
13819     {
13820       location_t expr_loc = c_parser_peek_token (parser)->location;
13821       c_expr expr = c_parser_expr_no_commas (parser, NULL);
13822       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13823       tree c, t = expr.value;
13824       t = c_fully_fold (t, false, NULL);
13825 
13826       parens.skip_until_found_close (parser);
13827 
13828       if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13829 	{
13830 	  c_parser_error (parser, "expected integer expression");
13831 	  return list;
13832 	}
13833 
13834       /* Attempt to statically determine when the number isn't positive.  */
13835       c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13836 			   build_int_cst (TREE_TYPE (t), 0));
13837       if (CAN_HAVE_LOCATION_P (c))
13838 	SET_EXPR_LOCATION (c, expr_loc);
13839       if (c == boolean_true_node)
13840 	{
13841 	  warning_at (expr_loc, 0, "%<grainsize%> value must be positive");
13842 	  t = integer_one_node;
13843 	}
13844 
13845       check_no_duplicate_clause (list, OMP_CLAUSE_GRAINSIZE, "grainsize");
13846 
13847       c = build_omp_clause (grainsize_loc, OMP_CLAUSE_GRAINSIZE);
13848       OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
13849       OMP_CLAUSE_CHAIN (c) = list;
13850       list = c;
13851     }
13852 
13853   return list;
13854 }
13855 
13856 /* OpenMP 4.5:
13857    priority ( expression ) */
13858 
13859 static tree
c_parser_omp_clause_priority(c_parser * parser,tree list)13860 c_parser_omp_clause_priority (c_parser *parser, tree list)
13861 {
13862   location_t priority_loc = c_parser_peek_token (parser)->location;
13863   matching_parens parens;
13864   if (parens.require_open (parser))
13865     {
13866       location_t expr_loc = c_parser_peek_token (parser)->location;
13867       c_expr expr = c_parser_expr_no_commas (parser, NULL);
13868       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13869       tree c, t = expr.value;
13870       t = c_fully_fold (t, false, NULL);
13871 
13872       parens.skip_until_found_close (parser);
13873 
13874       if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13875 	{
13876 	  c_parser_error (parser, "expected integer expression");
13877 	  return list;
13878 	}
13879 
13880       /* Attempt to statically determine when the number isn't
13881 	 non-negative.  */
13882       c = fold_build2_loc (expr_loc, LT_EXPR, boolean_type_node, t,
13883 			   build_int_cst (TREE_TYPE (t), 0));
13884       if (CAN_HAVE_LOCATION_P (c))
13885 	SET_EXPR_LOCATION (c, expr_loc);
13886       if (c == boolean_true_node)
13887 	{
13888 	  warning_at (expr_loc, 0, "%<priority%> value must be non-negative");
13889 	  t = integer_one_node;
13890 	}
13891 
13892       check_no_duplicate_clause (list, OMP_CLAUSE_PRIORITY, "priority");
13893 
13894       c = build_omp_clause (priority_loc, OMP_CLAUSE_PRIORITY);
13895       OMP_CLAUSE_PRIORITY_EXPR (c) = t;
13896       OMP_CLAUSE_CHAIN (c) = list;
13897       list = c;
13898     }
13899 
13900   return list;
13901 }
13902 
13903 /* OpenMP 4.5:
13904    hint ( expression ) */
13905 
13906 static tree
c_parser_omp_clause_hint(c_parser * parser,tree list)13907 c_parser_omp_clause_hint (c_parser *parser, tree list)
13908 {
13909   location_t hint_loc = c_parser_peek_token (parser)->location;
13910   matching_parens parens;
13911   if (parens.require_open (parser))
13912     {
13913       location_t expr_loc = c_parser_peek_token (parser)->location;
13914       c_expr expr = c_parser_expr_no_commas (parser, NULL);
13915       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13916       tree c, t = expr.value;
13917       t = c_fully_fold (t, false, NULL);
13918 
13919       parens.skip_until_found_close (parser);
13920 
13921       if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
13922 	  || TREE_CODE (t) != INTEGER_CST)
13923 	{
13924 	  c_parser_error (parser, "expected constant integer expression");
13925 	  return list;
13926 	}
13927 
13928       check_no_duplicate_clause (list, OMP_CLAUSE_HINT, "hint");
13929 
13930       c = build_omp_clause (hint_loc, OMP_CLAUSE_HINT);
13931       OMP_CLAUSE_HINT_EXPR (c) = t;
13932       OMP_CLAUSE_CHAIN (c) = list;
13933       list = c;
13934     }
13935 
13936   return list;
13937 }
13938 
13939 /* OpenMP 4.5:
13940    defaultmap ( tofrom : scalar )
13941 
13942    OpenMP 5.0:
13943    defaultmap ( implicit-behavior [ : variable-category ] ) */
13944 
13945 static tree
c_parser_omp_clause_defaultmap(c_parser * parser,tree list)13946 c_parser_omp_clause_defaultmap (c_parser *parser, tree list)
13947 {
13948   location_t loc = c_parser_peek_token (parser)->location;
13949   tree c;
13950   const char *p;
13951   enum omp_clause_defaultmap_kind behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
13952   enum omp_clause_defaultmap_kind category
13953     = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
13954 
13955   matching_parens parens;
13956   if (!parens.require_open (parser))
13957     return list;
13958   if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
13959     p = "default";
13960   else if (!c_parser_next_token_is (parser, CPP_NAME))
13961     {
13962     invalid_behavior:
13963       c_parser_error (parser, "expected %<alloc%>, %<to%>, %<from%>, "
13964 			      "%<tofrom%>, %<firstprivate%>, %<none%> "
13965 			      "or %<default%>");
13966       goto out_err;
13967     }
13968   else
13969     p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13970 
13971   switch (p[0])
13972     {
13973     case 'a':
13974       if (strcmp ("alloc", p) == 0)
13975 	behavior = OMP_CLAUSE_DEFAULTMAP_ALLOC;
13976       else
13977 	goto invalid_behavior;
13978       break;
13979 
13980     case 'd':
13981       if (strcmp ("default", p) == 0)
13982 	behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
13983       else
13984 	goto invalid_behavior;
13985       break;
13986 
13987     case 'f':
13988       if (strcmp ("firstprivate", p) == 0)
13989 	behavior = OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
13990       else if (strcmp ("from", p) == 0)
13991 	behavior = OMP_CLAUSE_DEFAULTMAP_FROM;
13992       else
13993 	goto invalid_behavior;
13994       break;
13995 
13996     case 'n':
13997       if (strcmp ("none", p) == 0)
13998 	behavior = OMP_CLAUSE_DEFAULTMAP_NONE;
13999       else
14000 	goto invalid_behavior;
14001       break;
14002 
14003     case 't':
14004       if (strcmp ("tofrom", p) == 0)
14005 	behavior = OMP_CLAUSE_DEFAULTMAP_TOFROM;
14006       else if (strcmp ("to", p) == 0)
14007 	behavior = OMP_CLAUSE_DEFAULTMAP_TO;
14008       else
14009 	goto invalid_behavior;
14010       break;
14011 
14012     default:
14013       goto invalid_behavior;
14014     }
14015   c_parser_consume_token (parser);
14016 
14017   if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
14018     {
14019       if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14020 	goto out_err;
14021       if (!c_parser_next_token_is (parser, CPP_NAME))
14022 	{
14023 	invalid_category:
14024 	  c_parser_error (parser, "expected %<scalar%>, %<aggregate%> or "
14025 				  "%<pointer%>");
14026 	  goto out_err;
14027 	}
14028       p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14029       switch (p[0])
14030 	{
14031 	case 'a':
14032 	  if (strcmp ("aggregate", p) == 0)
14033 	    category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE;
14034 	  else
14035 	    goto invalid_category;
14036 	  break;
14037 
14038 	case 'p':
14039 	  if (strcmp ("pointer", p) == 0)
14040 	    category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER;
14041 	  else
14042 	    goto invalid_category;
14043 	  break;
14044 
14045 	case 's':
14046 	  if (strcmp ("scalar", p) == 0)
14047 	    category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR;
14048 	  else
14049 	    goto invalid_category;
14050 	  break;
14051 
14052 	default:
14053 	  goto invalid_category;
14054 	}
14055 
14056       c_parser_consume_token (parser);
14057     }
14058   parens.skip_until_found_close (parser);
14059 
14060   for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
14061     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEFAULTMAP
14062 	&& (category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
14063 	    || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c) == category
14064 	    || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
14065 		== OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)))
14066       {
14067 	enum omp_clause_defaultmap_kind cat = category;
14068 	location_t loc = OMP_CLAUSE_LOCATION (c);
14069 	if (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
14070 	  cat = OMP_CLAUSE_DEFAULTMAP_CATEGORY (c);
14071 	p = NULL;
14072 	switch (cat)
14073 	  {
14074 	  case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
14075 	    p = NULL;
14076 	    break;
14077 	  case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
14078 	    p = "aggregate";
14079 	    break;
14080 	  case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
14081 	    p = "pointer";
14082 	    break;
14083 	  case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
14084 	    p = "scalar";
14085 	    break;
14086 	  default:
14087 	    gcc_unreachable ();
14088 	  }
14089 	if (p)
14090 	  error_at (loc, "too many %<defaultmap%> clauses with %qs category",
14091 		    p);
14092 	else
14093 	  error_at (loc, "too many %<defaultmap%> clauses with unspecified "
14094 			 "category");
14095 	break;
14096       }
14097 
14098   c = build_omp_clause (loc, OMP_CLAUSE_DEFAULTMAP);
14099   OMP_CLAUSE_DEFAULTMAP_SET_KIND (c, behavior, category);
14100   OMP_CLAUSE_CHAIN (c) = list;
14101   return c;
14102 
14103  out_err:
14104   parens.skip_until_found_close (parser);
14105   return list;
14106 }
14107 
14108 /* OpenACC 2.0:
14109    use_device ( variable-list )
14110 
14111    OpenMP 4.5:
14112    use_device_ptr ( variable-list ) */
14113 
14114 static tree
c_parser_omp_clause_use_device_ptr(c_parser * parser,tree list)14115 c_parser_omp_clause_use_device_ptr (c_parser *parser, tree list)
14116 {
14117   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_PTR,
14118 				       list);
14119 }
14120 
14121 /* OpenMP 5.0:
14122    use_device_addr ( variable-list ) */
14123 
14124 static tree
c_parser_omp_clause_use_device_addr(c_parser * parser,tree list)14125 c_parser_omp_clause_use_device_addr (c_parser *parser, tree list)
14126 {
14127   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_ADDR,
14128 				       list);
14129 }
14130 
14131 /* OpenMP 4.5:
14132    is_device_ptr ( variable-list ) */
14133 
14134 static tree
c_parser_omp_clause_is_device_ptr(c_parser * parser,tree list)14135 c_parser_omp_clause_is_device_ptr (c_parser *parser, tree list)
14136 {
14137   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_IS_DEVICE_PTR, list);
14138 }
14139 
14140 /* OpenACC:
14141    num_gangs ( expression )
14142    num_workers ( expression )
14143    vector_length ( expression )  */
14144 
14145 static tree
c_parser_oacc_single_int_clause(c_parser * parser,omp_clause_code code,tree list)14146 c_parser_oacc_single_int_clause (c_parser *parser, omp_clause_code code,
14147 				 tree list)
14148 {
14149   location_t loc = c_parser_peek_token (parser)->location;
14150 
14151   matching_parens parens;
14152   if (!parens.require_open (parser))
14153     return list;
14154 
14155   location_t expr_loc = c_parser_peek_token (parser)->location;
14156   c_expr expr = c_parser_expression (parser);
14157   expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14158   tree c, t = expr.value;
14159   t = c_fully_fold (t, false, NULL);
14160 
14161   parens.skip_until_found_close (parser);
14162 
14163   if (t == error_mark_node)
14164     return list;
14165   else if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14166     {
14167       error_at (expr_loc, "%qs expression must be integral",
14168 		omp_clause_code_name[code]);
14169       return list;
14170     }
14171 
14172   /* Attempt to statically determine when the number isn't positive.  */
14173   c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14174 		       build_int_cst (TREE_TYPE (t), 0));
14175   protected_set_expr_location (c, expr_loc);
14176   if (c == boolean_true_node)
14177     {
14178       warning_at (expr_loc, 0,
14179 		  "%qs value must be positive",
14180 		  omp_clause_code_name[code]);
14181       t = integer_one_node;
14182     }
14183 
14184   check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14185 
14186   c = build_omp_clause (loc, code);
14187   OMP_CLAUSE_OPERAND (c, 0) = t;
14188   OMP_CLAUSE_CHAIN (c) = list;
14189   return c;
14190 }
14191 
14192 /* OpenACC:
14193 
14194     gang [( gang-arg-list )]
14195     worker [( [num:] int-expr )]
14196     vector [( [length:] int-expr )]
14197 
14198   where gang-arg is one of:
14199 
14200     [num:] int-expr
14201     static: size-expr
14202 
14203   and size-expr may be:
14204 
14205     *
14206     int-expr
14207 */
14208 
14209 static tree
c_parser_oacc_shape_clause(c_parser * parser,location_t loc,omp_clause_code kind,const char * str,tree list)14210 c_parser_oacc_shape_clause (c_parser *parser, location_t loc,
14211 			    omp_clause_code kind,
14212 			    const char *str, tree list)
14213 {
14214   const char *id = "num";
14215   tree ops[2] = { NULL_TREE, NULL_TREE }, c;
14216 
14217   if (kind == OMP_CLAUSE_VECTOR)
14218     id = "length";
14219 
14220   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14221     {
14222       c_parser_consume_token (parser);
14223 
14224       do
14225 	{
14226 	  c_token *next = c_parser_peek_token (parser);
14227 	  int idx = 0;
14228 
14229 	  /* Gang static argument.  */
14230 	  if (kind == OMP_CLAUSE_GANG
14231 	      && c_parser_next_token_is_keyword (parser, RID_STATIC))
14232 	    {
14233 	      c_parser_consume_token (parser);
14234 
14235 	      if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14236 		goto cleanup_error;
14237 
14238 	      idx = 1;
14239 	      if (ops[idx] != NULL_TREE)
14240 		{
14241 		  c_parser_error (parser, "too many %<static%> arguments");
14242 		  goto cleanup_error;
14243 		}
14244 
14245 	      /* Check for the '*' argument.  */
14246 	      if (c_parser_next_token_is (parser, CPP_MULT)
14247 		  && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
14248 		      || c_parser_peek_2nd_token (parser)->type
14249 		         == CPP_CLOSE_PAREN))
14250 		{
14251 		  c_parser_consume_token (parser);
14252 		  ops[idx] = integer_minus_one_node;
14253 
14254 		  if (c_parser_next_token_is (parser, CPP_COMMA))
14255 		    {
14256 		      c_parser_consume_token (parser);
14257 		      continue;
14258 		    }
14259 		  else
14260 		    break;
14261 		}
14262 	    }
14263 	  /* Worker num: argument and vector length: arguments.  */
14264 	  else if (c_parser_next_token_is (parser, CPP_NAME)
14265 		   && strcmp (id, IDENTIFIER_POINTER (next->value)) == 0
14266 		   && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
14267 	    {
14268 	      c_parser_consume_token (parser);  /* id  */
14269 	      c_parser_consume_token (parser);  /* ':'  */
14270 	    }
14271 
14272 	  /* Now collect the actual argument.  */
14273 	  if (ops[idx] != NULL_TREE)
14274 	    {
14275 	      c_parser_error (parser, "unexpected argument");
14276 	      goto cleanup_error;
14277 	    }
14278 
14279 	  location_t expr_loc = c_parser_peek_token (parser)->location;
14280 	  c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
14281 	  cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
14282 	  tree expr = cexpr.value;
14283 	  if (expr == error_mark_node)
14284 	    goto cleanup_error;
14285 
14286 	  expr = c_fully_fold (expr, false, NULL);
14287 
14288 	  /* Attempt to statically determine when the number isn't a
14289 	     positive integer.  */
14290 
14291 	  if (!INTEGRAL_TYPE_P (TREE_TYPE (expr)))
14292 	    {
14293 	      c_parser_error (parser, "expected integer expression");
14294 	      return list;
14295 	    }
14296 
14297 	  tree c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, expr,
14298 				    build_int_cst (TREE_TYPE (expr), 0));
14299 	  if (c == boolean_true_node)
14300 	    {
14301 	      warning_at (loc, 0,
14302 			  "%qs value must be positive", str);
14303 	      expr = integer_one_node;
14304 	    }
14305 
14306 	  ops[idx] = expr;
14307 
14308 	  if (kind == OMP_CLAUSE_GANG
14309 	      && c_parser_next_token_is (parser, CPP_COMMA))
14310 	    {
14311 	      c_parser_consume_token (parser);
14312 	      continue;
14313 	    }
14314 	  break;
14315 	}
14316       while (1);
14317 
14318       if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
14319 	goto cleanup_error;
14320     }
14321 
14322   check_no_duplicate_clause (list, kind, str);
14323 
14324   c = build_omp_clause (loc, kind);
14325 
14326   if (ops[1])
14327     OMP_CLAUSE_OPERAND (c, 1) = ops[1];
14328 
14329   OMP_CLAUSE_OPERAND (c, 0) = ops[0];
14330   OMP_CLAUSE_CHAIN (c) = list;
14331 
14332   return c;
14333 
14334  cleanup_error:
14335   c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
14336   return list;
14337 }
14338 
14339 /* OpenACC 2.5:
14340    auto
14341    finalize
14342    independent
14343    nohost
14344    seq */
14345 
14346 static tree
c_parser_oacc_simple_clause(location_t loc,enum omp_clause_code code,tree list)14347 c_parser_oacc_simple_clause (location_t loc, enum omp_clause_code code,
14348 			     tree list)
14349 {
14350   check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14351 
14352   tree c = build_omp_clause (loc, code);
14353   OMP_CLAUSE_CHAIN (c) = list;
14354 
14355   return c;
14356 }
14357 
14358 /* OpenACC:
14359    async [( int-expr )] */
14360 
14361 static tree
c_parser_oacc_clause_async(c_parser * parser,tree list)14362 c_parser_oacc_clause_async (c_parser *parser, tree list)
14363 {
14364   tree c, t;
14365   location_t loc = c_parser_peek_token (parser)->location;
14366 
14367   t = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
14368 
14369   if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
14370     {
14371       c_parser_consume_token (parser);
14372 
14373       t = c_parser_expr_no_commas (parser, NULL).value;
14374       if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14375 	c_parser_error (parser, "expected integer expression");
14376       else if (t == error_mark_node
14377 	  || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
14378 	return list;
14379     }
14380   else
14381     t = c_fully_fold (t, false, NULL);
14382 
14383   check_no_duplicate_clause (list, OMP_CLAUSE_ASYNC, "async");
14384 
14385   c = build_omp_clause (loc, OMP_CLAUSE_ASYNC);
14386   OMP_CLAUSE_ASYNC_EXPR (c) = t;
14387   OMP_CLAUSE_CHAIN (c) = list;
14388   list = c;
14389 
14390   return list;
14391 }
14392 
14393 /* OpenACC 2.0:
14394    tile ( size-expr-list ) */
14395 
14396 static tree
c_parser_oacc_clause_tile(c_parser * parser,tree list)14397 c_parser_oacc_clause_tile (c_parser *parser, tree list)
14398 {
14399   tree c, expr = error_mark_node;
14400   location_t loc;
14401   tree tile = NULL_TREE;
14402 
14403   check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
14404   check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
14405 
14406   loc = c_parser_peek_token (parser)->location;
14407   if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
14408     return list;
14409 
14410   do
14411     {
14412       if (tile && !c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
14413 	return list;
14414 
14415       if (c_parser_next_token_is (parser, CPP_MULT)
14416 	  && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
14417 	      || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
14418 	{
14419 	  c_parser_consume_token (parser);
14420 	  expr = integer_zero_node;
14421 	}
14422       else
14423 	{
14424 	  location_t expr_loc = c_parser_peek_token (parser)->location;
14425 	  c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
14426 	  cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
14427 	  expr = cexpr.value;
14428 
14429 	  if (expr == error_mark_node)
14430 	    {
14431 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
14432 					 "expected %<)%>");
14433 	      return list;
14434 	    }
14435 
14436 	  expr = c_fully_fold (expr, false, NULL);
14437 
14438 	  if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
14439 	      || !tree_fits_shwi_p (expr)
14440 	      || tree_to_shwi (expr) <= 0)
14441 	    {
14442 	      error_at (expr_loc, "%<tile%> argument needs positive"
14443 			" integral constant");
14444 	      expr = integer_zero_node;
14445 	    }
14446 	}
14447 
14448       tile = tree_cons (NULL_TREE, expr, tile);
14449     }
14450   while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN));
14451 
14452   /* Consume the trailing ')'.  */
14453   c_parser_consume_token (parser);
14454 
14455   c = build_omp_clause (loc, OMP_CLAUSE_TILE);
14456   tile = nreverse (tile);
14457   OMP_CLAUSE_TILE_LIST (c) = tile;
14458   OMP_CLAUSE_CHAIN (c) = list;
14459   return c;
14460 }
14461 
14462 /* OpenACC:
14463    wait [( int-expr-list )] */
14464 
14465 static tree
c_parser_oacc_clause_wait(c_parser * parser,tree list)14466 c_parser_oacc_clause_wait (c_parser *parser, tree list)
14467 {
14468   location_t clause_loc = c_parser_peek_token (parser)->location;
14469 
14470   if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
14471     list = c_parser_oacc_wait_list (parser, clause_loc, list);
14472   else
14473     {
14474       tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
14475 
14476       OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
14477       OMP_CLAUSE_CHAIN (c) = list;
14478       list = c;
14479     }
14480 
14481   return list;
14482 }
14483 
14484 
14485 /* OpenMP 5.0:
14486    order ( concurrent ) */
14487 
14488 static tree
c_parser_omp_clause_order(c_parser * parser,tree list)14489 c_parser_omp_clause_order (c_parser *parser, tree list)
14490 {
14491   location_t loc = c_parser_peek_token (parser)->location;
14492   tree c;
14493   const char *p;
14494 
14495   matching_parens parens;
14496   if (!parens.require_open (parser))
14497     return list;
14498   if (!c_parser_next_token_is (parser, CPP_NAME))
14499     {
14500       c_parser_error (parser, "expected %<concurrent%>");
14501       goto out_err;
14502     }
14503   p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14504   if (strcmp (p, "concurrent") != 0)
14505     {
14506       c_parser_error (parser, "expected %<concurrent%>");
14507       goto out_err;
14508     }
14509   c_parser_consume_token (parser);
14510   parens.skip_until_found_close (parser);
14511   /* check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order"); */
14512   c = build_omp_clause (loc, OMP_CLAUSE_ORDER);
14513   OMP_CLAUSE_CHAIN (c) = list;
14514   return c;
14515 
14516  out_err:
14517   parens.skip_until_found_close (parser);
14518   return list;
14519 }
14520 
14521 
14522 /* OpenMP 5.0:
14523    bind ( teams | parallel | thread ) */
14524 
14525 static tree
c_parser_omp_clause_bind(c_parser * parser,tree list)14526 c_parser_omp_clause_bind (c_parser *parser, tree list)
14527 {
14528   location_t loc = c_parser_peek_token (parser)->location;
14529   tree c;
14530   const char *p;
14531   enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
14532 
14533   matching_parens parens;
14534   if (!parens.require_open (parser))
14535     return list;
14536   if (!c_parser_next_token_is (parser, CPP_NAME))
14537     {
14538      invalid:
14539       c_parser_error (parser,
14540 		      "expected %<teams%>, %<parallel%> or %<thread%>");
14541       parens.skip_until_found_close (parser);
14542       return list;
14543     }
14544   p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14545   if (strcmp (p, "teams") == 0)
14546     kind = OMP_CLAUSE_BIND_TEAMS;
14547   else if (strcmp (p, "parallel") == 0)
14548     kind = OMP_CLAUSE_BIND_PARALLEL;
14549   else if (strcmp (p, "thread") != 0)
14550     goto invalid;
14551   c_parser_consume_token (parser);
14552   parens.skip_until_found_close (parser);
14553   /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
14554   c = build_omp_clause (loc, OMP_CLAUSE_BIND);
14555   OMP_CLAUSE_BIND_KIND (c) = kind;
14556   OMP_CLAUSE_CHAIN (c) = list;
14557   return c;
14558 }
14559 
14560 
14561 /* OpenMP 2.5:
14562    ordered
14563 
14564    OpenMP 4.5:
14565    ordered ( constant-expression ) */
14566 
14567 static tree
c_parser_omp_clause_ordered(c_parser * parser,tree list)14568 c_parser_omp_clause_ordered (c_parser *parser, tree list)
14569 {
14570   check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered");
14571 
14572   tree c, num = NULL_TREE;
14573   HOST_WIDE_INT n;
14574   location_t loc = c_parser_peek_token (parser)->location;
14575   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14576     {
14577       matching_parens parens;
14578       parens.consume_open (parser);
14579       num = c_parser_expr_no_commas (parser, NULL).value;
14580       parens.skip_until_found_close (parser);
14581     }
14582   if (num == error_mark_node)
14583     return list;
14584   if (num)
14585     {
14586       mark_exp_read (num);
14587       num = c_fully_fold (num, false, NULL);
14588       if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
14589 	  || !tree_fits_shwi_p (num)
14590 	  || (n = tree_to_shwi (num)) <= 0
14591 	  || (int) n != n)
14592 	{
14593 	  error_at (loc, "ordered argument needs positive "
14594 			 "constant integer expression");
14595 	  return list;
14596 	}
14597     }
14598   c = build_omp_clause (loc, OMP_CLAUSE_ORDERED);
14599   OMP_CLAUSE_ORDERED_EXPR (c) = num;
14600   OMP_CLAUSE_CHAIN (c) = list;
14601   return c;
14602 }
14603 
14604 /* OpenMP 2.5:
14605    private ( variable-list ) */
14606 
14607 static tree
c_parser_omp_clause_private(c_parser * parser,tree list)14608 c_parser_omp_clause_private (c_parser *parser, tree list)
14609 {
14610   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_PRIVATE, list);
14611 }
14612 
14613 /* OpenMP 2.5:
14614    reduction ( reduction-operator : variable-list )
14615 
14616    reduction-operator:
14617      One of: + * - & ^ | && ||
14618 
14619    OpenMP 3.1:
14620 
14621    reduction-operator:
14622      One of: + * - & ^ | && || max min
14623 
14624    OpenMP 4.0:
14625 
14626    reduction-operator:
14627      One of: + * - & ^ | && ||
14628      identifier
14629 
14630    OpenMP 5.0:
14631    reduction ( reduction-modifier, reduction-operator : variable-list )
14632    in_reduction ( reduction-operator : variable-list )
14633    task_reduction ( reduction-operator : variable-list )  */
14634 
14635 static tree
c_parser_omp_clause_reduction(c_parser * parser,enum omp_clause_code kind,bool is_omp,tree list)14636 c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind,
14637 			       bool is_omp, tree list)
14638 {
14639   location_t clause_loc = c_parser_peek_token (parser)->location;
14640   matching_parens parens;
14641   if (parens.require_open (parser))
14642     {
14643       bool task = false;
14644       bool inscan = false;
14645       enum tree_code code = ERROR_MARK;
14646       tree reduc_id = NULL_TREE;
14647 
14648       if (kind == OMP_CLAUSE_REDUCTION && is_omp)
14649 	{
14650 	  if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)
14651 	      && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
14652 	    {
14653 	      c_parser_consume_token (parser);
14654 	      c_parser_consume_token (parser);
14655 	    }
14656 	  else if (c_parser_next_token_is (parser, CPP_NAME)
14657 		   && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
14658 	    {
14659 	      const char *p
14660 		= IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14661 	      if (strcmp (p, "task") == 0)
14662 		task = true;
14663 	      else if (strcmp (p, "inscan") == 0)
14664 		inscan = true;
14665 	      if (task || inscan)
14666 		{
14667 		  c_parser_consume_token (parser);
14668 		  c_parser_consume_token (parser);
14669 		}
14670 	    }
14671 	}
14672 
14673       switch (c_parser_peek_token (parser)->type)
14674 	{
14675 	case CPP_PLUS:
14676 	  code = PLUS_EXPR;
14677 	  break;
14678 	case CPP_MULT:
14679 	  code = MULT_EXPR;
14680 	  break;
14681 	case CPP_MINUS:
14682 	  code = MINUS_EXPR;
14683 	  break;
14684 	case CPP_AND:
14685 	  code = BIT_AND_EXPR;
14686 	  break;
14687 	case CPP_XOR:
14688 	  code = BIT_XOR_EXPR;
14689 	  break;
14690 	case CPP_OR:
14691 	  code = BIT_IOR_EXPR;
14692 	  break;
14693 	case CPP_AND_AND:
14694 	  code = TRUTH_ANDIF_EXPR;
14695 	  break;
14696 	case CPP_OR_OR:
14697 	  code = TRUTH_ORIF_EXPR;
14698 	  break;
14699         case CPP_NAME:
14700 	  {
14701 	    const char *p
14702 	      = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14703 	    if (strcmp (p, "min") == 0)
14704 	      {
14705 		code = MIN_EXPR;
14706 		break;
14707 	      }
14708 	    if (strcmp (p, "max") == 0)
14709 	      {
14710 		code = MAX_EXPR;
14711 		break;
14712 	      }
14713 	    reduc_id = c_parser_peek_token (parser)->value;
14714 	    break;
14715 	  }
14716 	default:
14717 	  c_parser_error (parser,
14718 			  "expected %<+%>, %<*%>, %<-%>, %<&%>, "
14719 			  "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
14720 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
14721 	  return list;
14722 	}
14723       c_parser_consume_token (parser);
14724       reduc_id = c_omp_reduction_id (code, reduc_id);
14725       if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14726 	{
14727 	  tree nl, c;
14728 
14729 	  nl = c_parser_omp_variable_list (parser, clause_loc, kind, list);
14730 	  for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
14731 	    {
14732 	      tree d = OMP_CLAUSE_DECL (c), type;
14733 	      if (TREE_CODE (d) != TREE_LIST)
14734 		type = TREE_TYPE (d);
14735 	      else
14736 		{
14737 		  int cnt = 0;
14738 		  tree t;
14739 		  for (t = d; TREE_CODE (t) == TREE_LIST; t = TREE_CHAIN (t))
14740 		    cnt++;
14741 		  type = TREE_TYPE (t);
14742 		  while (cnt > 0)
14743 		    {
14744 		      if (TREE_CODE (type) != POINTER_TYPE
14745 			  && TREE_CODE (type) != ARRAY_TYPE)
14746 			break;
14747 		      type = TREE_TYPE (type);
14748 		      cnt--;
14749 		    }
14750 		}
14751 	      while (TREE_CODE (type) == ARRAY_TYPE)
14752 		type = TREE_TYPE (type);
14753 	      OMP_CLAUSE_REDUCTION_CODE (c) = code;
14754 	      if (task)
14755 		OMP_CLAUSE_REDUCTION_TASK (c) = 1;
14756 	      else if (inscan)
14757 		OMP_CLAUSE_REDUCTION_INSCAN (c) = 1;
14758 	      if (code == ERROR_MARK
14759 		  || !(INTEGRAL_TYPE_P (type)
14760 		       || TREE_CODE (type) == REAL_TYPE
14761 		       || TREE_CODE (type) == COMPLEX_TYPE))
14762 		OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
14763 		  = c_omp_reduction_lookup (reduc_id,
14764 					    TYPE_MAIN_VARIANT (type));
14765 	    }
14766 
14767 	  list = nl;
14768 	}
14769       parens.skip_until_found_close (parser);
14770     }
14771   return list;
14772 }
14773 
14774 /* OpenMP 2.5:
14775    schedule ( schedule-kind )
14776    schedule ( schedule-kind , expression )
14777 
14778    schedule-kind:
14779      static | dynamic | guided | runtime | auto
14780 
14781    OpenMP 4.5:
14782    schedule ( schedule-modifier : schedule-kind )
14783    schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
14784 
14785    schedule-modifier:
14786      simd
14787      monotonic
14788      nonmonotonic  */
14789 
14790 static tree
c_parser_omp_clause_schedule(c_parser * parser,tree list)14791 c_parser_omp_clause_schedule (c_parser *parser, tree list)
14792 {
14793   tree c, t;
14794   location_t loc = c_parser_peek_token (parser)->location;
14795   int modifiers = 0, nmodifiers = 0;
14796 
14797   matching_parens parens;
14798   if (!parens.require_open (parser))
14799     return list;
14800 
14801   c = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE);
14802 
14803   while (c_parser_next_token_is (parser, CPP_NAME))
14804     {
14805       tree kind = c_parser_peek_token (parser)->value;
14806       const char *p = IDENTIFIER_POINTER (kind);
14807       if (strcmp ("simd", p) == 0)
14808 	OMP_CLAUSE_SCHEDULE_SIMD (c) = 1;
14809       else if (strcmp ("monotonic", p) == 0)
14810 	modifiers |= OMP_CLAUSE_SCHEDULE_MONOTONIC;
14811       else if (strcmp ("nonmonotonic", p) == 0)
14812 	modifiers |= OMP_CLAUSE_SCHEDULE_NONMONOTONIC;
14813       else
14814 	break;
14815       c_parser_consume_token (parser);
14816       if (nmodifiers++ == 0
14817 	  && c_parser_next_token_is (parser, CPP_COMMA))
14818 	c_parser_consume_token (parser);
14819       else
14820 	{
14821 	  c_parser_require (parser, CPP_COLON, "expected %<:%>");
14822 	  break;
14823 	}
14824     }
14825 
14826   if ((modifiers & (OMP_CLAUSE_SCHEDULE_MONOTONIC
14827 		    | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
14828       == (OMP_CLAUSE_SCHEDULE_MONOTONIC
14829 	  | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
14830     {
14831       error_at (loc, "both %<monotonic%> and %<nonmonotonic%> modifiers "
14832 		     "specified");
14833       modifiers = 0;
14834     }
14835 
14836   if (c_parser_next_token_is (parser, CPP_NAME))
14837     {
14838       tree kind = c_parser_peek_token (parser)->value;
14839       const char *p = IDENTIFIER_POINTER (kind);
14840 
14841       switch (p[0])
14842 	{
14843 	case 'd':
14844 	  if (strcmp ("dynamic", p) != 0)
14845 	    goto invalid_kind;
14846 	  OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
14847 	  break;
14848 
14849         case 'g':
14850 	  if (strcmp ("guided", p) != 0)
14851 	    goto invalid_kind;
14852 	  OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
14853 	  break;
14854 
14855 	case 'r':
14856 	  if (strcmp ("runtime", p) != 0)
14857 	    goto invalid_kind;
14858 	  OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
14859 	  break;
14860 
14861 	default:
14862 	  goto invalid_kind;
14863 	}
14864     }
14865   else if (c_parser_next_token_is_keyword (parser, RID_STATIC))
14866     OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
14867   else if (c_parser_next_token_is_keyword (parser, RID_AUTO))
14868     OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
14869   else
14870     goto invalid_kind;
14871 
14872   c_parser_consume_token (parser);
14873   if (c_parser_next_token_is (parser, CPP_COMMA))
14874     {
14875       location_t here;
14876       c_parser_consume_token (parser);
14877 
14878       here = c_parser_peek_token (parser)->location;
14879       c_expr expr = c_parser_expr_no_commas (parser, NULL);
14880       expr = convert_lvalue_to_rvalue (here, expr, false, true);
14881       t = expr.value;
14882       t = c_fully_fold (t, false, NULL);
14883 
14884       if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
14885 	error_at (here, "schedule %<runtime%> does not take "
14886 		  "a %<chunk_size%> parameter");
14887       else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO)
14888 	error_at (here,
14889 		  "schedule %<auto%> does not take "
14890 		  "a %<chunk_size%> parameter");
14891       else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE)
14892 	{
14893 	  /* Attempt to statically determine when the number isn't
14894 	     positive.  */
14895 	  tree s = fold_build2_loc (loc, LE_EXPR, boolean_type_node, t,
14896 				    build_int_cst (TREE_TYPE (t), 0));
14897 	  protected_set_expr_location (s, loc);
14898 	  if (s == boolean_true_node)
14899 	    {
14900 	      warning_at (loc, 0,
14901 			  "chunk size value must be positive");
14902 	      t = integer_one_node;
14903 	    }
14904 	  OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
14905 	}
14906       else
14907 	c_parser_error (parser, "expected integer expression");
14908 
14909       parens.skip_until_found_close (parser);
14910     }
14911   else
14912     c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
14913 			       "expected %<,%> or %<)%>");
14914 
14915   OMP_CLAUSE_SCHEDULE_KIND (c)
14916     = (enum omp_clause_schedule_kind)
14917       (OMP_CLAUSE_SCHEDULE_KIND (c) | modifiers);
14918 
14919   check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule");
14920   OMP_CLAUSE_CHAIN (c) = list;
14921   return c;
14922 
14923  invalid_kind:
14924   c_parser_error (parser, "invalid schedule kind");
14925   c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
14926   return list;
14927 }
14928 
14929 /* OpenMP 2.5:
14930    shared ( variable-list ) */
14931 
14932 static tree
c_parser_omp_clause_shared(c_parser * parser,tree list)14933 c_parser_omp_clause_shared (c_parser *parser, tree list)
14934 {
14935   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_SHARED, list);
14936 }
14937 
14938 /* OpenMP 3.0:
14939    untied */
14940 
14941 static tree
c_parser_omp_clause_untied(c_parser * parser ATTRIBUTE_UNUSED,tree list)14942 c_parser_omp_clause_untied (c_parser *parser ATTRIBUTE_UNUSED, tree list)
14943 {
14944   tree c;
14945 
14946   /* FIXME: Should we allow duplicates?  */
14947   check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied");
14948 
14949   c = build_omp_clause (c_parser_peek_token (parser)->location,
14950 			OMP_CLAUSE_UNTIED);
14951   OMP_CLAUSE_CHAIN (c) = list;
14952 
14953   return c;
14954 }
14955 
14956 /* OpenMP 4.0:
14957    inbranch
14958    notinbranch */
14959 
14960 static tree
c_parser_omp_clause_branch(c_parser * parser ATTRIBUTE_UNUSED,enum omp_clause_code code,tree list)14961 c_parser_omp_clause_branch (c_parser *parser ATTRIBUTE_UNUSED,
14962 			    enum omp_clause_code code, tree list)
14963 {
14964   check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14965 
14966   tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
14967   OMP_CLAUSE_CHAIN (c) = list;
14968 
14969   return c;
14970 }
14971 
14972 /* OpenMP 4.0:
14973    parallel
14974    for
14975    sections
14976    taskgroup */
14977 
14978 static tree
c_parser_omp_clause_cancelkind(c_parser * parser ATTRIBUTE_UNUSED,enum omp_clause_code code,tree list)14979 c_parser_omp_clause_cancelkind (c_parser *parser ATTRIBUTE_UNUSED,
14980 				enum omp_clause_code code, tree list)
14981 {
14982   tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
14983   OMP_CLAUSE_CHAIN (c) = list;
14984 
14985   return c;
14986 }
14987 
14988 /* OpenMP 4.5:
14989    nogroup */
14990 
14991 static tree
c_parser_omp_clause_nogroup(c_parser * parser ATTRIBUTE_UNUSED,tree list)14992 c_parser_omp_clause_nogroup (c_parser *parser ATTRIBUTE_UNUSED, tree list)
14993 {
14994   check_no_duplicate_clause (list, OMP_CLAUSE_NOGROUP, "nogroup");
14995   tree c = build_omp_clause (c_parser_peek_token (parser)->location,
14996 			     OMP_CLAUSE_NOGROUP);
14997   OMP_CLAUSE_CHAIN (c) = list;
14998   return c;
14999 }
15000 
15001 /* OpenMP 4.5:
15002    simd
15003    threads */
15004 
15005 static tree
c_parser_omp_clause_orderedkind(c_parser * parser ATTRIBUTE_UNUSED,enum omp_clause_code code,tree list)15006 c_parser_omp_clause_orderedkind (c_parser *parser ATTRIBUTE_UNUSED,
15007 				 enum omp_clause_code code, tree list)
15008 {
15009   check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
15010   tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15011   OMP_CLAUSE_CHAIN (c) = list;
15012   return c;
15013 }
15014 
15015 /* OpenMP 4.0:
15016    num_teams ( expression ) */
15017 
15018 static tree
c_parser_omp_clause_num_teams(c_parser * parser,tree list)15019 c_parser_omp_clause_num_teams (c_parser *parser, tree list)
15020 {
15021   location_t num_teams_loc = c_parser_peek_token (parser)->location;
15022   matching_parens parens;
15023   if (parens.require_open (parser))
15024     {
15025       location_t expr_loc = c_parser_peek_token (parser)->location;
15026       c_expr expr = c_parser_expr_no_commas (parser, NULL);
15027       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15028       tree c, t = expr.value;
15029       t = c_fully_fold (t, false, NULL);
15030 
15031       parens.skip_until_found_close (parser);
15032 
15033       if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
15034 	{
15035 	  c_parser_error (parser, "expected integer expression");
15036 	  return list;
15037 	}
15038 
15039       /* Attempt to statically determine when the number isn't positive.  */
15040       c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
15041 			   build_int_cst (TREE_TYPE (t), 0));
15042       protected_set_expr_location (c, expr_loc);
15043       if (c == boolean_true_node)
15044 	{
15045 	  warning_at (expr_loc, 0, "%<num_teams%> value must be positive");
15046 	  t = integer_one_node;
15047 	}
15048 
15049       check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TEAMS, "num_teams");
15050 
15051       c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
15052       OMP_CLAUSE_NUM_TEAMS_EXPR (c) = t;
15053       OMP_CLAUSE_CHAIN (c) = list;
15054       list = c;
15055     }
15056 
15057   return list;
15058 }
15059 
15060 /* OpenMP 4.0:
15061    thread_limit ( expression ) */
15062 
15063 static tree
c_parser_omp_clause_thread_limit(c_parser * parser,tree list)15064 c_parser_omp_clause_thread_limit (c_parser *parser, tree list)
15065 {
15066   location_t num_thread_limit_loc = c_parser_peek_token (parser)->location;
15067   matching_parens parens;
15068   if (parens.require_open (parser))
15069     {
15070       location_t expr_loc = c_parser_peek_token (parser)->location;
15071       c_expr expr = c_parser_expr_no_commas (parser, NULL);
15072       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15073       tree c, t = expr.value;
15074       t = c_fully_fold (t, false, NULL);
15075 
15076       parens.skip_until_found_close (parser);
15077 
15078       if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
15079 	{
15080 	  c_parser_error (parser, "expected integer expression");
15081 	  return list;
15082 	}
15083 
15084       /* Attempt to statically determine when the number isn't positive.  */
15085       c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
15086 			   build_int_cst (TREE_TYPE (t), 0));
15087       protected_set_expr_location (c, expr_loc);
15088       if (c == boolean_true_node)
15089 	{
15090 	  warning_at (expr_loc, 0, "%<thread_limit%> value must be positive");
15091 	  t = integer_one_node;
15092 	}
15093 
15094       check_no_duplicate_clause (list, OMP_CLAUSE_THREAD_LIMIT,
15095 				 "thread_limit");
15096 
15097       c = build_omp_clause (num_thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
15098       OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
15099       OMP_CLAUSE_CHAIN (c) = list;
15100       list = c;
15101     }
15102 
15103   return list;
15104 }
15105 
15106 /* OpenMP 4.0:
15107    aligned ( variable-list )
15108    aligned ( variable-list : constant-expression ) */
15109 
15110 static tree
c_parser_omp_clause_aligned(c_parser * parser,tree list)15111 c_parser_omp_clause_aligned (c_parser *parser, tree list)
15112 {
15113   location_t clause_loc = c_parser_peek_token (parser)->location;
15114   tree nl, c;
15115 
15116   matching_parens parens;
15117   if (!parens.require_open (parser))
15118     return list;
15119 
15120   nl = c_parser_omp_variable_list (parser, clause_loc,
15121 				   OMP_CLAUSE_ALIGNED, list);
15122 
15123   if (c_parser_next_token_is (parser, CPP_COLON))
15124     {
15125       c_parser_consume_token (parser);
15126       location_t expr_loc = c_parser_peek_token (parser)->location;
15127       c_expr expr = c_parser_expr_no_commas (parser, NULL);
15128       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15129       tree alignment = expr.value;
15130       alignment = c_fully_fold (alignment, false, NULL);
15131       if (TREE_CODE (alignment) != INTEGER_CST
15132 	  || !INTEGRAL_TYPE_P (TREE_TYPE (alignment))
15133 	  || tree_int_cst_sgn (alignment) != 1)
15134 	{
15135 	  error_at (clause_loc, "%<aligned%> clause alignment expression must "
15136 				"be positive constant integer expression");
15137 	  alignment = NULL_TREE;
15138 	}
15139 
15140       for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15141 	OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = alignment;
15142     }
15143 
15144   parens.skip_until_found_close (parser);
15145   return nl;
15146 }
15147 
15148 /* OpenMP 4.0:
15149    linear ( variable-list )
15150    linear ( variable-list : expression )
15151 
15152    OpenMP 4.5:
15153    linear ( modifier ( variable-list ) )
15154    linear ( modifier ( variable-list ) : expression ) */
15155 
15156 static tree
c_parser_omp_clause_linear(c_parser * parser,tree list)15157 c_parser_omp_clause_linear (c_parser *parser, tree list)
15158 {
15159   location_t clause_loc = c_parser_peek_token (parser)->location;
15160   tree nl, c, step;
15161   enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
15162 
15163   matching_parens parens;
15164   if (!parens.require_open (parser))
15165     return list;
15166 
15167   if (c_parser_next_token_is (parser, CPP_NAME))
15168     {
15169       c_token *tok = c_parser_peek_token (parser);
15170       const char *p = IDENTIFIER_POINTER (tok->value);
15171       if (strcmp ("val", p) == 0)
15172 	kind = OMP_CLAUSE_LINEAR_VAL;
15173       if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN)
15174 	kind = OMP_CLAUSE_LINEAR_DEFAULT;
15175       if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
15176 	{
15177 	  c_parser_consume_token (parser);
15178 	  c_parser_consume_token (parser);
15179 	}
15180     }
15181 
15182   nl = c_parser_omp_variable_list (parser, clause_loc,
15183 				   OMP_CLAUSE_LINEAR, list);
15184 
15185   if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
15186     parens.skip_until_found_close (parser);
15187 
15188   if (c_parser_next_token_is (parser, CPP_COLON))
15189     {
15190       c_parser_consume_token (parser);
15191       location_t expr_loc = c_parser_peek_token (parser)->location;
15192       c_expr expr = c_parser_expr_no_commas (parser, NULL);
15193       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15194       step = expr.value;
15195       step = c_fully_fold (step, false, NULL);
15196       if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
15197 	{
15198 	  error_at (clause_loc, "%<linear%> clause step expression must "
15199 				"be integral");
15200 	  step = integer_one_node;
15201 	}
15202 
15203     }
15204   else
15205     step = integer_one_node;
15206 
15207   for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15208     {
15209       OMP_CLAUSE_LINEAR_STEP (c) = step;
15210       OMP_CLAUSE_LINEAR_KIND (c) = kind;
15211     }
15212 
15213   parens.skip_until_found_close (parser);
15214   return nl;
15215 }
15216 
15217 /* OpenMP 5.0:
15218    nontemporal ( variable-list ) */
15219 
15220 static tree
c_parser_omp_clause_nontemporal(c_parser * parser,tree list)15221 c_parser_omp_clause_nontemporal (c_parser *parser, tree list)
15222 {
15223   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_NONTEMPORAL, list);
15224 }
15225 
15226 /* OpenMP 4.0:
15227    safelen ( constant-expression ) */
15228 
15229 static tree
c_parser_omp_clause_safelen(c_parser * parser,tree list)15230 c_parser_omp_clause_safelen (c_parser *parser, tree list)
15231 {
15232   location_t clause_loc = c_parser_peek_token (parser)->location;
15233   tree c, t;
15234 
15235   matching_parens parens;
15236   if (!parens.require_open (parser))
15237     return list;
15238 
15239   location_t expr_loc = c_parser_peek_token (parser)->location;
15240   c_expr expr = c_parser_expr_no_commas (parser, NULL);
15241   expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15242   t = expr.value;
15243   t = c_fully_fold (t, false, NULL);
15244   if (TREE_CODE (t) != INTEGER_CST
15245       || !INTEGRAL_TYPE_P (TREE_TYPE (t))
15246       || tree_int_cst_sgn (t) != 1)
15247     {
15248       error_at (clause_loc, "%<safelen%> clause expression must "
15249 			    "be positive constant integer expression");
15250       t = NULL_TREE;
15251     }
15252 
15253   parens.skip_until_found_close (parser);
15254   if (t == NULL_TREE || t == error_mark_node)
15255     return list;
15256 
15257   check_no_duplicate_clause (list, OMP_CLAUSE_SAFELEN, "safelen");
15258 
15259   c = build_omp_clause (clause_loc, OMP_CLAUSE_SAFELEN);
15260   OMP_CLAUSE_SAFELEN_EXPR (c) = t;
15261   OMP_CLAUSE_CHAIN (c) = list;
15262   return c;
15263 }
15264 
15265 /* OpenMP 4.0:
15266    simdlen ( constant-expression ) */
15267 
15268 static tree
c_parser_omp_clause_simdlen(c_parser * parser,tree list)15269 c_parser_omp_clause_simdlen (c_parser *parser, tree list)
15270 {
15271   location_t clause_loc = c_parser_peek_token (parser)->location;
15272   tree c, t;
15273 
15274   matching_parens parens;
15275   if (!parens.require_open (parser))
15276     return list;
15277 
15278   location_t expr_loc = c_parser_peek_token (parser)->location;
15279   c_expr expr = c_parser_expr_no_commas (parser, NULL);
15280   expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15281   t = expr.value;
15282   t = c_fully_fold (t, false, NULL);
15283   if (TREE_CODE (t) != INTEGER_CST
15284       || !INTEGRAL_TYPE_P (TREE_TYPE (t))
15285       || tree_int_cst_sgn (t) != 1)
15286     {
15287       error_at (clause_loc, "%<simdlen%> clause expression must "
15288 			    "be positive constant integer expression");
15289       t = NULL_TREE;
15290     }
15291 
15292   parens.skip_until_found_close (parser);
15293   if (t == NULL_TREE || t == error_mark_node)
15294     return list;
15295 
15296   check_no_duplicate_clause (list, OMP_CLAUSE_SIMDLEN, "simdlen");
15297 
15298   c = build_omp_clause (clause_loc, OMP_CLAUSE_SIMDLEN);
15299   OMP_CLAUSE_SIMDLEN_EXPR (c) = t;
15300   OMP_CLAUSE_CHAIN (c) = list;
15301   return c;
15302 }
15303 
15304 /* OpenMP 4.5:
15305    vec:
15306      identifier [+/- integer]
15307      vec , identifier [+/- integer]
15308 */
15309 
15310 static tree
c_parser_omp_clause_depend_sink(c_parser * parser,location_t clause_loc,tree list)15311 c_parser_omp_clause_depend_sink (c_parser *parser, location_t clause_loc,
15312 				 tree list)
15313 {
15314   tree vec = NULL;
15315   if (c_parser_next_token_is_not (parser, CPP_NAME)
15316       || c_parser_peek_token (parser)->id_kind != C_ID_ID)
15317     {
15318       c_parser_error (parser, "expected identifier");
15319       return list;
15320     }
15321 
15322   while (c_parser_next_token_is (parser, CPP_NAME)
15323 	 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
15324     {
15325       tree t = lookup_name (c_parser_peek_token (parser)->value);
15326       tree addend = NULL;
15327 
15328       if (t == NULL_TREE)
15329 	{
15330 	  undeclared_variable (c_parser_peek_token (parser)->location,
15331 			       c_parser_peek_token (parser)->value);
15332 	  t = error_mark_node;
15333 	}
15334 
15335       c_parser_consume_token (parser);
15336 
15337       bool neg = false;
15338       if (c_parser_next_token_is (parser, CPP_MINUS))
15339 	neg = true;
15340       else if (!c_parser_next_token_is (parser, CPP_PLUS))
15341 	{
15342 	  addend = integer_zero_node;
15343 	  neg = false;
15344 	  goto add_to_vector;
15345 	}
15346       c_parser_consume_token (parser);
15347 
15348       if (c_parser_next_token_is_not (parser, CPP_NUMBER))
15349 	{
15350 	  c_parser_error (parser, "expected integer");
15351 	  return list;
15352 	}
15353 
15354       addend = c_parser_peek_token (parser)->value;
15355       if (TREE_CODE (addend) != INTEGER_CST)
15356 	{
15357 	  c_parser_error (parser, "expected integer");
15358 	  return list;
15359 	}
15360       c_parser_consume_token (parser);
15361 
15362     add_to_vector:
15363       if (t != error_mark_node)
15364 	{
15365 	  vec = tree_cons (addend, t, vec);
15366 	  if (neg)
15367 	    OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec) = 1;
15368 	}
15369 
15370       if (c_parser_next_token_is_not (parser, CPP_COMMA))
15371 	break;
15372 
15373       c_parser_consume_token (parser);
15374     }
15375 
15376   if (vec == NULL_TREE)
15377     return list;
15378 
15379   tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
15380   OMP_CLAUSE_DEPEND_KIND (u) = OMP_CLAUSE_DEPEND_SINK;
15381   OMP_CLAUSE_DECL (u) = nreverse (vec);
15382   OMP_CLAUSE_CHAIN (u) = list;
15383   return u;
15384 }
15385 
15386 /* OpenMP 5.0:
15387    iterators ( iterators-definition )
15388 
15389    iterators-definition:
15390      iterator-specifier
15391      iterator-specifier , iterators-definition
15392 
15393    iterator-specifier:
15394      identifier = range-specification
15395      iterator-type identifier = range-specification
15396 
15397    range-specification:
15398      begin : end
15399      begin : end : step  */
15400 
15401 static tree
c_parser_omp_iterators(c_parser * parser)15402 c_parser_omp_iterators (c_parser *parser)
15403 {
15404   tree ret = NULL_TREE, *last = &ret;
15405   c_parser_consume_token (parser);
15406 
15407   push_scope ();
15408 
15409   matching_parens parens;
15410   if (!parens.require_open (parser))
15411     return error_mark_node;
15412 
15413   do
15414     {
15415       tree iter_type = NULL_TREE, type_expr = NULL_TREE;
15416       if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
15417 	{
15418 	  struct c_type_name *type = c_parser_type_name (parser);
15419 	  if (type != NULL)
15420 	    iter_type = groktypename (type, &type_expr, NULL);
15421 	}
15422       if (iter_type == NULL_TREE)
15423 	iter_type = integer_type_node;
15424 
15425       location_t loc = c_parser_peek_token (parser)->location;
15426       if (!c_parser_next_token_is (parser, CPP_NAME))
15427 	{
15428 	  c_parser_error (parser, "expected identifier");
15429 	  break;
15430 	}
15431 
15432       tree id = c_parser_peek_token (parser)->value;
15433       c_parser_consume_token (parser);
15434 
15435       if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
15436 	break;
15437 
15438       location_t eloc = c_parser_peek_token (parser)->location;
15439       c_expr expr = c_parser_expr_no_commas (parser, NULL);
15440       expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
15441       tree begin = expr.value;
15442 
15443       if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15444 	break;
15445 
15446       eloc = c_parser_peek_token (parser)->location;
15447       expr = c_parser_expr_no_commas (parser, NULL);
15448       expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
15449       tree end = expr.value;
15450 
15451       tree step = integer_one_node;
15452       if (c_parser_next_token_is (parser, CPP_COLON))
15453 	{
15454 	  c_parser_consume_token (parser);
15455 	  eloc = c_parser_peek_token (parser)->location;
15456 	  expr = c_parser_expr_no_commas (parser, NULL);
15457 	  expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
15458 	  step = expr.value;
15459 	}
15460 
15461       tree iter_var = build_decl (loc, VAR_DECL, id, iter_type);
15462       DECL_ARTIFICIAL (iter_var) = 1;
15463       DECL_CONTEXT (iter_var) = current_function_decl;
15464       pushdecl (iter_var);
15465 
15466       *last = make_tree_vec (6);
15467       TREE_VEC_ELT (*last, 0) = iter_var;
15468       TREE_VEC_ELT (*last, 1) = begin;
15469       TREE_VEC_ELT (*last, 2) = end;
15470       TREE_VEC_ELT (*last, 3) = step;
15471       last = &TREE_CHAIN (*last);
15472 
15473       if (c_parser_next_token_is (parser, CPP_COMMA))
15474 	{
15475 	  c_parser_consume_token (parser);
15476 	  continue;
15477 	}
15478       break;
15479     }
15480   while (1);
15481 
15482   parens.skip_until_found_close (parser);
15483   return ret ? ret : error_mark_node;
15484 }
15485 
15486 /* OpenMP 4.0:
15487    depend ( depend-kind: variable-list )
15488 
15489    depend-kind:
15490      in | out | inout
15491 
15492    OpenMP 4.5:
15493    depend ( source )
15494 
15495    depend ( sink  : vec )
15496 
15497    OpenMP 5.0:
15498    depend ( depend-modifier , depend-kind: variable-list )
15499 
15500    depend-kind:
15501      in | out | inout | mutexinoutset | depobj
15502 
15503    depend-modifier:
15504      iterator ( iterators-definition )  */
15505 
15506 static tree
c_parser_omp_clause_depend(c_parser * parser,tree list)15507 c_parser_omp_clause_depend (c_parser *parser, tree list)
15508 {
15509   location_t clause_loc = c_parser_peek_token (parser)->location;
15510   enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_LAST;
15511   tree nl, c, iterators = NULL_TREE;
15512 
15513   matching_parens parens;
15514   if (!parens.require_open (parser))
15515     return list;
15516 
15517   do
15518     {
15519       if (c_parser_next_token_is_not (parser, CPP_NAME))
15520 	goto invalid_kind;
15521 
15522       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15523       if (strcmp ("iterator", p) == 0 && iterators == NULL_TREE)
15524 	{
15525 	  iterators = c_parser_omp_iterators (parser);
15526 	  c_parser_require (parser, CPP_COMMA, "expected %<,%>");
15527 	  continue;
15528 	}
15529       if (strcmp ("in", p) == 0)
15530 	kind = OMP_CLAUSE_DEPEND_IN;
15531       else if (strcmp ("inout", p) == 0)
15532 	kind = OMP_CLAUSE_DEPEND_INOUT;
15533       else if (strcmp ("mutexinoutset", p) == 0)
15534 	kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
15535       else if (strcmp ("out", p) == 0)
15536 	kind = OMP_CLAUSE_DEPEND_OUT;
15537       else if (strcmp ("depobj", p) == 0)
15538 	kind = OMP_CLAUSE_DEPEND_DEPOBJ;
15539       else if (strcmp ("sink", p) == 0)
15540 	kind = OMP_CLAUSE_DEPEND_SINK;
15541       else if (strcmp ("source", p) == 0)
15542 	kind = OMP_CLAUSE_DEPEND_SOURCE;
15543       else
15544 	goto invalid_kind;
15545       break;
15546     }
15547   while (1);
15548 
15549   c_parser_consume_token (parser);
15550 
15551   if (iterators
15552       && (kind == OMP_CLAUSE_DEPEND_SOURCE || kind == OMP_CLAUSE_DEPEND_SINK))
15553     {
15554       pop_scope ();
15555       error_at (clause_loc, "%<iterator%> modifier incompatible with %qs",
15556 		kind == OMP_CLAUSE_DEPEND_SOURCE ? "source" : "sink");
15557       iterators = NULL_TREE;
15558     }
15559 
15560   if (kind == OMP_CLAUSE_DEPEND_SOURCE)
15561     {
15562       c = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
15563       OMP_CLAUSE_DEPEND_KIND (c) = kind;
15564       OMP_CLAUSE_DECL (c) = NULL_TREE;
15565       OMP_CLAUSE_CHAIN (c) = list;
15566       parens.skip_until_found_close (parser);
15567       return c;
15568     }
15569 
15570   if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15571     goto resync_fail;
15572 
15573   if (kind == OMP_CLAUSE_DEPEND_SINK)
15574     nl = c_parser_omp_clause_depend_sink (parser, clause_loc, list);
15575   else
15576     {
15577       nl = c_parser_omp_variable_list (parser, clause_loc,
15578 				       OMP_CLAUSE_DEPEND, list);
15579 
15580       if (iterators)
15581 	{
15582 	  tree block = pop_scope ();
15583 	  if (iterators == error_mark_node)
15584 	    iterators = NULL_TREE;
15585 	  else
15586 	    TREE_VEC_ELT (iterators, 5) = block;
15587 	}
15588 
15589       for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15590 	{
15591 	  OMP_CLAUSE_DEPEND_KIND (c) = kind;
15592 	  if (iterators)
15593 	    OMP_CLAUSE_DECL (c)
15594 	      = build_tree_list (iterators, OMP_CLAUSE_DECL (c));
15595 	}
15596     }
15597 
15598   parens.skip_until_found_close (parser);
15599   return nl;
15600 
15601  invalid_kind:
15602   c_parser_error (parser, "invalid depend kind");
15603  resync_fail:
15604   parens.skip_until_found_close (parser);
15605   if (iterators)
15606     pop_scope ();
15607   return list;
15608 }
15609 
15610 /* OpenMP 4.0:
15611    map ( map-kind: variable-list )
15612    map ( variable-list )
15613 
15614    map-kind:
15615      alloc | to | from | tofrom
15616 
15617    OpenMP 4.5:
15618    map-kind:
15619      alloc | to | from | tofrom | release | delete
15620 
15621    map ( always [,] map-kind: variable-list ) */
15622 
15623 static tree
c_parser_omp_clause_map(c_parser * parser,tree list)15624 c_parser_omp_clause_map (c_parser *parser, tree list)
15625 {
15626   location_t clause_loc = c_parser_peek_token (parser)->location;
15627   enum gomp_map_kind kind = GOMP_MAP_TOFROM;
15628   int always = 0;
15629   enum c_id_kind always_id_kind = C_ID_NONE;
15630   location_t always_loc = UNKNOWN_LOCATION;
15631   tree always_id = NULL_TREE;
15632   tree nl, c;
15633 
15634   matching_parens parens;
15635   if (!parens.require_open (parser))
15636     return list;
15637 
15638   if (c_parser_next_token_is (parser, CPP_NAME))
15639     {
15640       c_token *tok = c_parser_peek_token (parser);
15641       const char *p = IDENTIFIER_POINTER (tok->value);
15642       always_id_kind = tok->id_kind;
15643       always_loc = tok->location;
15644       always_id = tok->value;
15645       if (strcmp ("always", p) == 0)
15646 	{
15647 	  c_token *sectok = c_parser_peek_2nd_token (parser);
15648 	  if (sectok->type == CPP_COMMA)
15649 	    {
15650 	      c_parser_consume_token (parser);
15651 	      c_parser_consume_token (parser);
15652 	      always = 2;
15653 	    }
15654 	  else if (sectok->type == CPP_NAME)
15655 	    {
15656 	      p = IDENTIFIER_POINTER (sectok->value);
15657 	      if (strcmp ("alloc", p) == 0
15658 		  || strcmp ("to", p) == 0
15659 		  || strcmp ("from", p) == 0
15660 		  || strcmp ("tofrom", p) == 0
15661 		  || strcmp ("release", p) == 0
15662 		  || strcmp ("delete", p) == 0)
15663 		{
15664 		  c_parser_consume_token (parser);
15665 		  always = 1;
15666 		}
15667 	    }
15668 	}
15669     }
15670 
15671   if (c_parser_next_token_is (parser, CPP_NAME)
15672       && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
15673     {
15674       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15675       if (strcmp ("alloc", p) == 0)
15676 	kind = GOMP_MAP_ALLOC;
15677       else if (strcmp ("to", p) == 0)
15678 	kind = always ? GOMP_MAP_ALWAYS_TO : GOMP_MAP_TO;
15679       else if (strcmp ("from", p) == 0)
15680 	kind = always ? GOMP_MAP_ALWAYS_FROM : GOMP_MAP_FROM;
15681       else if (strcmp ("tofrom", p) == 0)
15682 	kind = always ? GOMP_MAP_ALWAYS_TOFROM : GOMP_MAP_TOFROM;
15683       else if (strcmp ("release", p) == 0)
15684 	kind = GOMP_MAP_RELEASE;
15685       else if (strcmp ("delete", p) == 0)
15686 	kind = GOMP_MAP_DELETE;
15687       else
15688 	{
15689 	  c_parser_error (parser, "invalid map kind");
15690 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
15691 				     "expected %<)%>");
15692 	  return list;
15693 	}
15694       c_parser_consume_token (parser);
15695       c_parser_consume_token (parser);
15696     }
15697   else if (always)
15698     {
15699       if (always_id_kind != C_ID_ID)
15700 	{
15701 	  c_parser_error (parser, "expected identifier");
15702 	  parens.skip_until_found_close (parser);
15703 	  return list;
15704 	}
15705 
15706       tree t = lookup_name (always_id);
15707       if (t == NULL_TREE)
15708 	{
15709 	  undeclared_variable (always_loc, always_id);
15710 	  t = error_mark_node;
15711 	}
15712       if (t != error_mark_node)
15713 	{
15714 	  tree u = build_omp_clause (clause_loc, OMP_CLAUSE_MAP);
15715 	  OMP_CLAUSE_DECL (u) = t;
15716 	  OMP_CLAUSE_CHAIN (u) = list;
15717 	  OMP_CLAUSE_SET_MAP_KIND (u, kind);
15718 	  list = u;
15719 	}
15720       if (always == 1)
15721 	{
15722 	  parens.skip_until_found_close (parser);
15723 	  return list;
15724 	}
15725     }
15726 
15727   nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_MAP, list);
15728 
15729   for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15730     OMP_CLAUSE_SET_MAP_KIND (c, kind);
15731 
15732   parens.skip_until_found_close (parser);
15733   return nl;
15734 }
15735 
15736 /* OpenMP 4.0:
15737    device ( expression ) */
15738 
15739 static tree
c_parser_omp_clause_device(c_parser * parser,tree list)15740 c_parser_omp_clause_device (c_parser *parser, tree list)
15741 {
15742   location_t clause_loc = c_parser_peek_token (parser)->location;
15743   matching_parens parens;
15744   if (parens.require_open (parser))
15745     {
15746       location_t expr_loc = c_parser_peek_token (parser)->location;
15747       c_expr expr = c_parser_expr_no_commas (parser, NULL);
15748       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15749       tree c, t = expr.value;
15750       t = c_fully_fold (t, false, NULL);
15751 
15752       parens.skip_until_found_close (parser);
15753 
15754       if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
15755 	{
15756 	  c_parser_error (parser, "expected integer expression");
15757 	  return list;
15758 	}
15759 
15760       check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE, "device");
15761 
15762       c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE);
15763       OMP_CLAUSE_DEVICE_ID (c) = t;
15764       OMP_CLAUSE_CHAIN (c) = list;
15765       list = c;
15766     }
15767 
15768   return list;
15769 }
15770 
15771 /* OpenMP 4.0:
15772    dist_schedule ( static )
15773    dist_schedule ( static , expression ) */
15774 
15775 static tree
c_parser_omp_clause_dist_schedule(c_parser * parser,tree list)15776 c_parser_omp_clause_dist_schedule (c_parser *parser, tree list)
15777 {
15778   tree c, t = NULL_TREE;
15779   location_t loc = c_parser_peek_token (parser)->location;
15780 
15781   matching_parens parens;
15782   if (!parens.require_open (parser))
15783     return list;
15784 
15785   if (!c_parser_next_token_is_keyword (parser, RID_STATIC))
15786     {
15787       c_parser_error (parser, "invalid dist_schedule kind");
15788       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
15789 				 "expected %<)%>");
15790       return list;
15791     }
15792 
15793   c_parser_consume_token (parser);
15794   if (c_parser_next_token_is (parser, CPP_COMMA))
15795     {
15796       c_parser_consume_token (parser);
15797 
15798       location_t expr_loc = c_parser_peek_token (parser)->location;
15799       c_expr expr = c_parser_expr_no_commas (parser, NULL);
15800       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15801       t = expr.value;
15802       t = c_fully_fold (t, false, NULL);
15803       parens.skip_until_found_close (parser);
15804     }
15805   else
15806     c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
15807 			       "expected %<,%> or %<)%>");
15808 
15809   /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
15810 				"dist_schedule"); */
15811   if (omp_find_clause (list, OMP_CLAUSE_DIST_SCHEDULE))
15812     warning_at (loc, 0, "too many %qs clauses", "dist_schedule");
15813   if (t == error_mark_node)
15814     return list;
15815 
15816   c = build_omp_clause (loc, OMP_CLAUSE_DIST_SCHEDULE);
15817   OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t;
15818   OMP_CLAUSE_CHAIN (c) = list;
15819   return c;
15820 }
15821 
15822 /* OpenMP 4.0:
15823    proc_bind ( proc-bind-kind )
15824 
15825    proc-bind-kind:
15826      master | close | spread  */
15827 
15828 static tree
c_parser_omp_clause_proc_bind(c_parser * parser,tree list)15829 c_parser_omp_clause_proc_bind (c_parser *parser, tree list)
15830 {
15831   location_t clause_loc = c_parser_peek_token (parser)->location;
15832   enum omp_clause_proc_bind_kind kind;
15833   tree c;
15834 
15835   matching_parens parens;
15836   if (!parens.require_open (parser))
15837     return list;
15838 
15839   if (c_parser_next_token_is (parser, CPP_NAME))
15840     {
15841       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15842       if (strcmp ("master", p) == 0)
15843 	kind = OMP_CLAUSE_PROC_BIND_MASTER;
15844       else if (strcmp ("close", p) == 0)
15845 	kind = OMP_CLAUSE_PROC_BIND_CLOSE;
15846       else if (strcmp ("spread", p) == 0)
15847 	kind = OMP_CLAUSE_PROC_BIND_SPREAD;
15848       else
15849 	goto invalid_kind;
15850     }
15851   else
15852     goto invalid_kind;
15853 
15854   check_no_duplicate_clause (list, OMP_CLAUSE_PROC_BIND, "proc_bind");
15855   c_parser_consume_token (parser);
15856   parens.skip_until_found_close (parser);
15857   c = build_omp_clause (clause_loc, OMP_CLAUSE_PROC_BIND);
15858   OMP_CLAUSE_PROC_BIND_KIND (c) = kind;
15859   OMP_CLAUSE_CHAIN (c) = list;
15860   return c;
15861 
15862  invalid_kind:
15863   c_parser_error (parser, "invalid proc_bind kind");
15864   parens.skip_until_found_close (parser);
15865   return list;
15866 }
15867 
15868 /* OpenMP 5.0:
15869    device_type ( host | nohost | any )  */
15870 
15871 static tree
c_parser_omp_clause_device_type(c_parser * parser,tree list)15872 c_parser_omp_clause_device_type (c_parser *parser, tree list)
15873 {
15874   location_t clause_loc = c_parser_peek_token (parser)->location;
15875   enum omp_clause_device_type_kind kind;
15876   tree c;
15877 
15878   matching_parens parens;
15879   if (!parens.require_open (parser))
15880     return list;
15881 
15882   if (c_parser_next_token_is (parser, CPP_NAME))
15883     {
15884       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15885       if (strcmp ("host", p) == 0)
15886 	kind = OMP_CLAUSE_DEVICE_TYPE_HOST;
15887       else if (strcmp ("nohost", p) == 0)
15888 	kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
15889       else if (strcmp ("any", p) == 0)
15890 	kind = OMP_CLAUSE_DEVICE_TYPE_ANY;
15891       else
15892 	goto invalid_kind;
15893     }
15894   else
15895     goto invalid_kind;
15896 
15897   /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE,
15898 				"device_type");  */
15899   c_parser_consume_token (parser);
15900   parens.skip_until_found_close (parser);
15901   c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE_TYPE);
15902   OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind;
15903   OMP_CLAUSE_CHAIN (c) = list;
15904   return c;
15905 
15906  invalid_kind:
15907   c_parser_error (parser, "expected %<host%>, %<nohost%> or %<any%>");
15908   parens.skip_until_found_close (parser);
15909   return list;
15910 }
15911 
15912 /* OpenMP 4.0:
15913    to ( variable-list ) */
15914 
15915 static tree
c_parser_omp_clause_to(c_parser * parser,tree list)15916 c_parser_omp_clause_to (c_parser *parser, tree list)
15917 {
15918   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO, list);
15919 }
15920 
15921 /* OpenMP 4.0:
15922    from ( variable-list ) */
15923 
15924 static tree
c_parser_omp_clause_from(c_parser * parser,tree list)15925 c_parser_omp_clause_from (c_parser *parser, tree list)
15926 {
15927   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FROM, list);
15928 }
15929 
15930 /* OpenMP 4.0:
15931    uniform ( variable-list ) */
15932 
15933 static tree
c_parser_omp_clause_uniform(c_parser * parser,tree list)15934 c_parser_omp_clause_uniform (c_parser *parser, tree list)
15935 {
15936   /* The clauses location.  */
15937   location_t loc = c_parser_peek_token (parser)->location;
15938 
15939   matching_parens parens;
15940   if (parens.require_open (parser))
15941     {
15942       list = c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_UNIFORM,
15943 					 list);
15944       parens.skip_until_found_close (parser);
15945     }
15946   return list;
15947 }
15948 
15949 /* Parse all OpenACC clauses.  The set clauses allowed by the directive
15950    is a bitmask in MASK.  Return the list of clauses found.  */
15951 
15952 static tree
15953 c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask,
15954 			   const char *where, bool finish_p = true)
15955 {
15956   tree clauses = NULL;
15957   bool first = true;
15958 
15959   while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
15960     {
15961       location_t here;
15962       pragma_omp_clause c_kind;
15963       const char *c_name;
15964       tree prev = clauses;
15965 
15966       if (!first && c_parser_next_token_is (parser, CPP_COMMA))
15967 	c_parser_consume_token (parser);
15968 
15969       here = c_parser_peek_token (parser)->location;
15970       c_kind = c_parser_omp_clause_name (parser);
15971 
15972       switch (c_kind)
15973 	{
15974 	case PRAGMA_OACC_CLAUSE_ASYNC:
15975 	  clauses = c_parser_oacc_clause_async (parser, clauses);
15976 	  c_name = "async";
15977 	  break;
15978 	case PRAGMA_OACC_CLAUSE_AUTO:
15979 	  clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_AUTO,
15980 						 clauses);
15981 	  c_name = "auto";
15982 	  break;
15983 	case PRAGMA_OACC_CLAUSE_ATTACH:
15984 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15985 	  c_name = "attach";
15986 	  break;
15987 	case PRAGMA_OACC_CLAUSE_COLLAPSE:
15988 	  clauses = c_parser_omp_clause_collapse (parser, clauses);
15989 	  c_name = "collapse";
15990 	  break;
15991 	case PRAGMA_OACC_CLAUSE_COPY:
15992 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15993 	  c_name = "copy";
15994 	  break;
15995 	case PRAGMA_OACC_CLAUSE_COPYIN:
15996 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15997 	  c_name = "copyin";
15998 	  break;
15999 	case PRAGMA_OACC_CLAUSE_COPYOUT:
16000 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16001 	  c_name = "copyout";
16002 	  break;
16003 	case PRAGMA_OACC_CLAUSE_CREATE:
16004 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16005 	  c_name = "create";
16006 	  break;
16007 	case PRAGMA_OACC_CLAUSE_DELETE:
16008 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16009 	  c_name = "delete";
16010 	  break;
16011 	case PRAGMA_OMP_CLAUSE_DEFAULT:
16012 	  clauses = c_parser_omp_clause_default (parser, clauses, true);
16013 	  c_name = "default";
16014 	  break;
16015 	case PRAGMA_OACC_CLAUSE_DETACH:
16016 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16017 	  c_name = "detach";
16018 	  break;
16019 	case PRAGMA_OACC_CLAUSE_DEVICE:
16020 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16021 	  c_name = "device";
16022 	  break;
16023 	case PRAGMA_OACC_CLAUSE_DEVICEPTR:
16024 	  clauses = c_parser_oacc_data_clause_deviceptr (parser, clauses);
16025 	  c_name = "deviceptr";
16026 	  break;
16027 	case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
16028 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16029 	  c_name = "device_resident";
16030 	  break;
16031 	case PRAGMA_OACC_CLAUSE_FINALIZE:
16032 	  clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_FINALIZE,
16033 						 clauses);
16034 	  c_name = "finalize";
16035 	  break;
16036 	case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE:
16037 	  clauses = c_parser_omp_clause_firstprivate (parser, clauses);
16038 	  c_name = "firstprivate";
16039 	  break;
16040 	case PRAGMA_OACC_CLAUSE_GANG:
16041 	  c_name = "gang";
16042 	  clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_GANG,
16043 						c_name, clauses);
16044 	  break;
16045 	case PRAGMA_OACC_CLAUSE_HOST:
16046 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16047 	  c_name = "host";
16048 	  break;
16049 	case PRAGMA_OACC_CLAUSE_IF:
16050 	  clauses = c_parser_omp_clause_if (parser, clauses, false);
16051 	  c_name = "if";
16052 	  break;
16053 	case PRAGMA_OACC_CLAUSE_IF_PRESENT:
16054 	  clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_IF_PRESENT,
16055 						 clauses);
16056 	  c_name = "if_present";
16057 	  break;
16058 	case PRAGMA_OACC_CLAUSE_INDEPENDENT:
16059 	  clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_INDEPENDENT,
16060 						 clauses);
16061 	  c_name = "independent";
16062 	  break;
16063 	case PRAGMA_OACC_CLAUSE_LINK:
16064 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16065 	  c_name = "link";
16066 	  break;
16067 	case PRAGMA_OACC_CLAUSE_NO_CREATE:
16068 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16069 	  c_name = "no_create";
16070 	  break;
16071 	case PRAGMA_OACC_CLAUSE_NUM_GANGS:
16072 	  clauses = c_parser_oacc_single_int_clause (parser,
16073 						     OMP_CLAUSE_NUM_GANGS,
16074 						     clauses);
16075 	  c_name = "num_gangs";
16076 	  break;
16077 	case PRAGMA_OACC_CLAUSE_NUM_WORKERS:
16078 	  clauses = c_parser_oacc_single_int_clause (parser,
16079 						     OMP_CLAUSE_NUM_WORKERS,
16080 						     clauses);
16081 	  c_name = "num_workers";
16082 	  break;
16083 	case PRAGMA_OACC_CLAUSE_PRESENT:
16084 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16085 	  c_name = "present";
16086 	  break;
16087 	case PRAGMA_OACC_CLAUSE_PRIVATE:
16088 	  clauses = c_parser_omp_clause_private (parser, clauses);
16089 	  c_name = "private";
16090 	  break;
16091 	case PRAGMA_OACC_CLAUSE_REDUCTION:
16092 	  clauses
16093 	    = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
16094 					     false, clauses);
16095 	  c_name = "reduction";
16096 	  break;
16097 	case PRAGMA_OACC_CLAUSE_SEQ:
16098 	  clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_SEQ,
16099 						 clauses);
16100 	  c_name = "seq";
16101 	  break;
16102 	case PRAGMA_OACC_CLAUSE_TILE:
16103 	  clauses = c_parser_oacc_clause_tile (parser, clauses);
16104 	  c_name = "tile";
16105 	  break;
16106 	case PRAGMA_OACC_CLAUSE_USE_DEVICE:
16107 	  clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
16108 	  c_name = "use_device";
16109 	  break;
16110 	case PRAGMA_OACC_CLAUSE_VECTOR:
16111 	  c_name = "vector";
16112 	  clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_VECTOR,
16113 						c_name,	clauses);
16114 	  break;
16115 	case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH:
16116 	  clauses = c_parser_oacc_single_int_clause (parser,
16117 						     OMP_CLAUSE_VECTOR_LENGTH,
16118 						     clauses);
16119 	  c_name = "vector_length";
16120 	  break;
16121 	case PRAGMA_OACC_CLAUSE_WAIT:
16122 	  clauses = c_parser_oacc_clause_wait (parser, clauses);
16123 	  c_name = "wait";
16124 	  break;
16125 	case PRAGMA_OACC_CLAUSE_WORKER:
16126 	  c_name = "worker";
16127 	  clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_WORKER,
16128 						c_name, clauses);
16129 	  break;
16130 	default:
16131 	  c_parser_error (parser, "expected %<#pragma acc%> clause");
16132 	  goto saw_error;
16133 	}
16134 
16135       first = false;
16136 
16137       if (((mask >> c_kind) & 1) == 0)
16138 	{
16139 	  /* Remove the invalid clause(s) from the list to avoid
16140 	     confusing the rest of the compiler.  */
16141 	  clauses = prev;
16142 	  error_at (here, "%qs is not valid for %qs", c_name, where);
16143 	}
16144     }
16145 
16146  saw_error:
16147   c_parser_skip_to_pragma_eol (parser);
16148 
16149   if (finish_p)
16150     return c_finish_omp_clauses (clauses, C_ORT_ACC);
16151 
16152   return clauses;
16153 }
16154 
16155 /* Parse all OpenMP clauses.  The set clauses allowed by the directive
16156    is a bitmask in MASK.  Return the list of clauses found.
16157    FINISH_P set if c_finish_omp_clauses should be called.
16158    NESTED non-zero if clauses should be terminated by closing paren instead
16159    of end of pragma.  If it is 2, additionally commas are required in between
16160    the clauses.  */
16161 
16162 static tree
16163 c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
16164 			  const char *where, bool finish_p = true,
16165 			  int nested = 0)
16166 {
16167   tree clauses = NULL;
16168   bool first = true;
16169 
16170   while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
16171     {
16172       location_t here;
16173       pragma_omp_clause c_kind;
16174       const char *c_name;
16175       tree prev = clauses;
16176 
16177       if (nested && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
16178 	break;
16179 
16180       if (!first)
16181 	{
16182 	  if (c_parser_next_token_is (parser, CPP_COMMA))
16183 	    c_parser_consume_token (parser);
16184 	  else if (nested == 2)
16185 	    error_at (c_parser_peek_token (parser)->location,
16186 		      "clauses in %<simd%> trait should be separated "
16187 		      "by %<,%>");
16188 	}
16189 
16190       here = c_parser_peek_token (parser)->location;
16191       c_kind = c_parser_omp_clause_name (parser);
16192 
16193       switch (c_kind)
16194 	{
16195 	case PRAGMA_OMP_CLAUSE_BIND:
16196 	  clauses = c_parser_omp_clause_bind (parser, clauses);
16197 	  c_name = "bind";
16198 	  break;
16199 	case PRAGMA_OMP_CLAUSE_COLLAPSE:
16200 	  clauses = c_parser_omp_clause_collapse (parser, clauses);
16201 	  c_name = "collapse";
16202 	  break;
16203 	case PRAGMA_OMP_CLAUSE_COPYIN:
16204 	  clauses = c_parser_omp_clause_copyin (parser, clauses);
16205 	  c_name = "copyin";
16206 	  break;
16207 	case PRAGMA_OMP_CLAUSE_COPYPRIVATE:
16208 	  clauses = c_parser_omp_clause_copyprivate (parser, clauses);
16209 	  c_name = "copyprivate";
16210 	  break;
16211 	case PRAGMA_OMP_CLAUSE_DEFAULT:
16212 	  clauses = c_parser_omp_clause_default (parser, clauses, false);
16213 	  c_name = "default";
16214 	  break;
16215 	case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
16216 	  clauses = c_parser_omp_clause_firstprivate (parser, clauses);
16217 	  c_name = "firstprivate";
16218 	  break;
16219 	case PRAGMA_OMP_CLAUSE_FINAL:
16220 	  clauses = c_parser_omp_clause_final (parser, clauses);
16221 	  c_name = "final";
16222 	  break;
16223 	case PRAGMA_OMP_CLAUSE_GRAINSIZE:
16224 	  clauses = c_parser_omp_clause_grainsize (parser, clauses);
16225 	  c_name = "grainsize";
16226 	  break;
16227 	case PRAGMA_OMP_CLAUSE_HINT:
16228 	  clauses = c_parser_omp_clause_hint (parser, clauses);
16229 	  c_name = "hint";
16230 	  break;
16231 	case PRAGMA_OMP_CLAUSE_DEFAULTMAP:
16232 	  clauses = c_parser_omp_clause_defaultmap (parser, clauses);
16233 	  c_name = "defaultmap";
16234 	  break;
16235 	case PRAGMA_OMP_CLAUSE_IF:
16236 	  clauses = c_parser_omp_clause_if (parser, clauses, true);
16237 	  c_name = "if";
16238 	  break;
16239 	case PRAGMA_OMP_CLAUSE_IN_REDUCTION:
16240 	  clauses
16241 	    = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION,
16242 					     true, clauses);
16243 	  c_name = "in_reduction";
16244 	  break;
16245 	case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
16246 	  clauses = c_parser_omp_clause_lastprivate (parser, clauses);
16247 	  c_name = "lastprivate";
16248 	  break;
16249 	case PRAGMA_OMP_CLAUSE_MERGEABLE:
16250 	  clauses = c_parser_omp_clause_mergeable (parser, clauses);
16251 	  c_name = "mergeable";
16252 	  break;
16253 	case PRAGMA_OMP_CLAUSE_NOWAIT:
16254 	  clauses = c_parser_omp_clause_nowait (parser, clauses);
16255 	  c_name = "nowait";
16256 	  break;
16257 	case PRAGMA_OMP_CLAUSE_NUM_TASKS:
16258 	  clauses = c_parser_omp_clause_num_tasks (parser, clauses);
16259 	  c_name = "num_tasks";
16260 	  break;
16261 	case PRAGMA_OMP_CLAUSE_NUM_THREADS:
16262 	  clauses = c_parser_omp_clause_num_threads (parser, clauses);
16263 	  c_name = "num_threads";
16264 	  break;
16265 	case PRAGMA_OMP_CLAUSE_ORDER:
16266 	  clauses = c_parser_omp_clause_order (parser, clauses);
16267 	  c_name = "order";
16268 	  break;
16269 	case PRAGMA_OMP_CLAUSE_ORDERED:
16270 	  clauses = c_parser_omp_clause_ordered (parser, clauses);
16271 	  c_name = "ordered";
16272 	  break;
16273 	case PRAGMA_OMP_CLAUSE_PRIORITY:
16274 	  clauses = c_parser_omp_clause_priority (parser, clauses);
16275 	  c_name = "priority";
16276 	  break;
16277 	case PRAGMA_OMP_CLAUSE_PRIVATE:
16278 	  clauses = c_parser_omp_clause_private (parser, clauses);
16279 	  c_name = "private";
16280 	  break;
16281 	case PRAGMA_OMP_CLAUSE_REDUCTION:
16282 	  clauses
16283 	    = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
16284 					     true, clauses);
16285 	  c_name = "reduction";
16286 	  break;
16287 	case PRAGMA_OMP_CLAUSE_SCHEDULE:
16288 	  clauses = c_parser_omp_clause_schedule (parser, clauses);
16289 	  c_name = "schedule";
16290 	  break;
16291 	case PRAGMA_OMP_CLAUSE_SHARED:
16292 	  clauses = c_parser_omp_clause_shared (parser, clauses);
16293 	  c_name = "shared";
16294 	  break;
16295 	case PRAGMA_OMP_CLAUSE_TASK_REDUCTION:
16296 	  clauses
16297 	    = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_TASK_REDUCTION,
16298 					     true, clauses);
16299 	  c_name = "task_reduction";
16300 	  break;
16301 	case PRAGMA_OMP_CLAUSE_UNTIED:
16302 	  clauses = c_parser_omp_clause_untied (parser, clauses);
16303 	  c_name = "untied";
16304 	  break;
16305 	case PRAGMA_OMP_CLAUSE_INBRANCH:
16306 	  clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_INBRANCH,
16307 						clauses);
16308 	  c_name = "inbranch";
16309 	  break;
16310 	case PRAGMA_OMP_CLAUSE_NONTEMPORAL:
16311 	  clauses = c_parser_omp_clause_nontemporal (parser, clauses);
16312 	  c_name = "nontemporal";
16313 	  break;
16314 	case PRAGMA_OMP_CLAUSE_NOTINBRANCH:
16315 	  clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_NOTINBRANCH,
16316 						clauses);
16317 	  c_name = "notinbranch";
16318 	  break;
16319 	case PRAGMA_OMP_CLAUSE_PARALLEL:
16320 	  clauses
16321 	    = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_PARALLEL,
16322 					      clauses);
16323 	  c_name = "parallel";
16324 	  if (!first)
16325 	    {
16326 	     clause_not_first:
16327 	      error_at (here, "%qs must be the first clause of %qs",
16328 			c_name, where);
16329 	      clauses = prev;
16330 	    }
16331 	  break;
16332 	case PRAGMA_OMP_CLAUSE_FOR:
16333 	  clauses
16334 	    = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_FOR,
16335 					      clauses);
16336 	  c_name = "for";
16337 	  if (!first)
16338 	    goto clause_not_first;
16339 	  break;
16340 	case PRAGMA_OMP_CLAUSE_SECTIONS:
16341 	  clauses
16342 	    = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_SECTIONS,
16343 					      clauses);
16344 	  c_name = "sections";
16345 	  if (!first)
16346 	    goto clause_not_first;
16347 	  break;
16348 	case PRAGMA_OMP_CLAUSE_TASKGROUP:
16349 	  clauses
16350 	    = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_TASKGROUP,
16351 					      clauses);
16352 	  c_name = "taskgroup";
16353 	  if (!first)
16354 	    goto clause_not_first;
16355 	  break;
16356 	case PRAGMA_OMP_CLAUSE_LINK:
16357 	  clauses
16358 	    = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LINK, clauses);
16359 	  c_name = "link";
16360 	  break;
16361 	case PRAGMA_OMP_CLAUSE_TO:
16362 	  if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0)
16363 	    clauses
16364 	      = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO_DECLARE,
16365 					      clauses);
16366 	  else
16367 	    clauses = c_parser_omp_clause_to (parser, clauses);
16368 	  c_name = "to";
16369 	  break;
16370 	case PRAGMA_OMP_CLAUSE_FROM:
16371 	  clauses = c_parser_omp_clause_from (parser, clauses);
16372 	  c_name = "from";
16373 	  break;
16374 	case PRAGMA_OMP_CLAUSE_UNIFORM:
16375 	  clauses = c_parser_omp_clause_uniform (parser, clauses);
16376 	  c_name = "uniform";
16377 	  break;
16378 	case PRAGMA_OMP_CLAUSE_NUM_TEAMS:
16379 	  clauses = c_parser_omp_clause_num_teams (parser, clauses);
16380 	  c_name = "num_teams";
16381 	  break;
16382 	case PRAGMA_OMP_CLAUSE_THREAD_LIMIT:
16383 	  clauses = c_parser_omp_clause_thread_limit (parser, clauses);
16384 	  c_name = "thread_limit";
16385 	  break;
16386 	case PRAGMA_OMP_CLAUSE_ALIGNED:
16387 	  clauses = c_parser_omp_clause_aligned (parser, clauses);
16388 	  c_name = "aligned";
16389 	  break;
16390 	case PRAGMA_OMP_CLAUSE_LINEAR:
16391 	  clauses = c_parser_omp_clause_linear (parser, clauses);
16392 	  c_name = "linear";
16393 	  break;
16394 	case PRAGMA_OMP_CLAUSE_DEPEND:
16395 	  clauses = c_parser_omp_clause_depend (parser, clauses);
16396 	  c_name = "depend";
16397 	  break;
16398 	case PRAGMA_OMP_CLAUSE_MAP:
16399 	  clauses = c_parser_omp_clause_map (parser, clauses);
16400 	  c_name = "map";
16401 	  break;
16402 	case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR:
16403 	  clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
16404 	  c_name = "use_device_ptr";
16405 	  break;
16406 	case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR:
16407 	  clauses = c_parser_omp_clause_use_device_addr (parser, clauses);
16408 	  c_name = "use_device_addr";
16409 	  break;
16410 	case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR:
16411 	  clauses = c_parser_omp_clause_is_device_ptr (parser, clauses);
16412 	  c_name = "is_device_ptr";
16413 	  break;
16414 	case PRAGMA_OMP_CLAUSE_DEVICE:
16415 	  clauses = c_parser_omp_clause_device (parser, clauses);
16416 	  c_name = "device";
16417 	  break;
16418 	case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE:
16419 	  clauses = c_parser_omp_clause_dist_schedule (parser, clauses);
16420 	  c_name = "dist_schedule";
16421 	  break;
16422 	case PRAGMA_OMP_CLAUSE_PROC_BIND:
16423 	  clauses = c_parser_omp_clause_proc_bind (parser, clauses);
16424 	  c_name = "proc_bind";
16425 	  break;
16426 	case PRAGMA_OMP_CLAUSE_DEVICE_TYPE:
16427 	  clauses = c_parser_omp_clause_device_type (parser, clauses);
16428 	  c_name = "device_type";
16429 	  break;
16430 	case PRAGMA_OMP_CLAUSE_SAFELEN:
16431 	  clauses = c_parser_omp_clause_safelen (parser, clauses);
16432 	  c_name = "safelen";
16433 	  break;
16434 	case PRAGMA_OMP_CLAUSE_SIMDLEN:
16435 	  clauses = c_parser_omp_clause_simdlen (parser, clauses);
16436 	  c_name = "simdlen";
16437 	  break;
16438 	case PRAGMA_OMP_CLAUSE_NOGROUP:
16439 	  clauses = c_parser_omp_clause_nogroup (parser, clauses);
16440 	  c_name = "nogroup";
16441 	  break;
16442 	case PRAGMA_OMP_CLAUSE_THREADS:
16443 	  clauses
16444 	    = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_THREADS,
16445 					       clauses);
16446 	  c_name = "threads";
16447 	  break;
16448 	case PRAGMA_OMP_CLAUSE_SIMD:
16449 	  clauses
16450 	    = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_SIMD,
16451 					       clauses);
16452 	  c_name = "simd";
16453 	  break;
16454 	default:
16455 	  c_parser_error (parser, "expected %<#pragma omp%> clause");
16456 	  goto saw_error;
16457 	}
16458 
16459       first = false;
16460 
16461       if (((mask >> c_kind) & 1) == 0)
16462 	{
16463 	  /* Remove the invalid clause(s) from the list to avoid
16464 	     confusing the rest of the compiler.  */
16465 	  clauses = prev;
16466 	  error_at (here, "%qs is not valid for %qs", c_name, where);
16467 	}
16468     }
16469 
16470  saw_error:
16471   if (!nested)
16472     c_parser_skip_to_pragma_eol (parser);
16473 
16474   if (finish_p)
16475     {
16476       if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)) != 0)
16477 	return c_finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD);
16478       return c_finish_omp_clauses (clauses, C_ORT_OMP);
16479     }
16480 
16481   return clauses;
16482 }
16483 
16484 /* OpenACC 2.0, OpenMP 2.5:
16485    structured-block:
16486      statement
16487 
16488    In practice, we're also interested in adding the statement to an
16489    outer node.  So it is convenient if we work around the fact that
16490    c_parser_statement calls add_stmt.  */
16491 
16492 static tree
c_parser_omp_structured_block(c_parser * parser,bool * if_p)16493 c_parser_omp_structured_block (c_parser *parser, bool *if_p)
16494 {
16495   tree stmt = push_stmt_list ();
16496   c_parser_statement (parser, if_p);
16497   return pop_stmt_list (stmt);
16498 }
16499 
16500 /* OpenACC 2.0:
16501    # pragma acc cache (variable-list) new-line
16502 
16503    LOC is the location of the #pragma token.
16504 */
16505 
16506 static tree
c_parser_oacc_cache(location_t loc,c_parser * parser)16507 c_parser_oacc_cache (location_t loc, c_parser *parser)
16508 {
16509   tree stmt, clauses;
16510 
16511   clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE__CACHE_, NULL);
16512   clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
16513 
16514   c_parser_skip_to_pragma_eol (parser);
16515 
16516   stmt = make_node (OACC_CACHE);
16517   TREE_TYPE (stmt) = void_type_node;
16518   OACC_CACHE_CLAUSES (stmt) = clauses;
16519   SET_EXPR_LOCATION (stmt, loc);
16520   add_stmt (stmt);
16521 
16522   return stmt;
16523 }
16524 
16525 /* OpenACC 2.0:
16526    # pragma acc data oacc-data-clause[optseq] new-line
16527      structured-block
16528 
16529    LOC is the location of the #pragma token.
16530 */
16531 
16532 #define OACC_DATA_CLAUSE_MASK						\
16533 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH)		\
16534 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY)		\
16535 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)		\
16536 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)		\
16537 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)		\
16538 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)		\
16539 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)			\
16540 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE)		\
16541 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
16542 
16543 static tree
c_parser_oacc_data(location_t loc,c_parser * parser,bool * if_p)16544 c_parser_oacc_data (location_t loc, c_parser *parser, bool *if_p)
16545 {
16546   tree stmt, clauses, block;
16547 
16548   clauses = c_parser_oacc_all_clauses (parser, OACC_DATA_CLAUSE_MASK,
16549 				       "#pragma acc data");
16550 
16551   block = c_begin_omp_parallel ();
16552   add_stmt (c_parser_omp_structured_block (parser, if_p));
16553 
16554   stmt = c_finish_oacc_data (loc, clauses, block);
16555 
16556   return stmt;
16557 }
16558 
16559 /* OpenACC 2.0:
16560    # pragma acc declare oacc-data-clause[optseq] new-line
16561 */
16562 
16563 #define OACC_DECLARE_CLAUSE_MASK					\
16564 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY)		\
16565 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)		\
16566 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)		\
16567 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)		\
16568 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)		\
16569 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT)	\
16570 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK)		\
16571 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
16572 
16573 static void
c_parser_oacc_declare(c_parser * parser)16574 c_parser_oacc_declare (c_parser *parser)
16575 {
16576   location_t pragma_loc = c_parser_peek_token (parser)->location;
16577   tree clauses, stmt, t, decl;
16578 
16579   bool error = false;
16580 
16581   c_parser_consume_pragma (parser);
16582 
16583   clauses = c_parser_oacc_all_clauses (parser, OACC_DECLARE_CLAUSE_MASK,
16584 				       "#pragma acc declare");
16585   if (!clauses)
16586     {
16587       error_at (pragma_loc,
16588 		"no valid clauses specified in %<#pragma acc declare%>");
16589       return;
16590     }
16591 
16592   for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
16593     {
16594       location_t loc = OMP_CLAUSE_LOCATION (t);
16595       decl = OMP_CLAUSE_DECL (t);
16596       if (!DECL_P (decl))
16597 	{
16598 	  error_at (loc, "array section in %<#pragma acc declare%>");
16599 	  error = true;
16600 	  continue;
16601 	}
16602 
16603       switch (OMP_CLAUSE_MAP_KIND (t))
16604 	{
16605 	case GOMP_MAP_FIRSTPRIVATE_POINTER:
16606 	case GOMP_MAP_ALLOC:
16607 	case GOMP_MAP_TO:
16608 	case GOMP_MAP_FORCE_DEVICEPTR:
16609 	case GOMP_MAP_DEVICE_RESIDENT:
16610 	  break;
16611 
16612 	case GOMP_MAP_LINK:
16613 	  if (!global_bindings_p ()
16614 	      && (TREE_STATIC (decl)
16615 	       || !DECL_EXTERNAL (decl)))
16616 	    {
16617 	      error_at (loc,
16618 			"%qD must be a global variable in "
16619 			"%<#pragma acc declare link%>",
16620 			decl);
16621 	      error = true;
16622 	      continue;
16623 	    }
16624 	  break;
16625 
16626 	default:
16627 	  if (global_bindings_p ())
16628 	    {
16629 	      error_at (loc, "invalid OpenACC clause at file scope");
16630 	      error = true;
16631 	      continue;
16632 	    }
16633 	  if (DECL_EXTERNAL (decl))
16634 	    {
16635 	      error_at (loc,
16636 			"invalid use of %<extern%> variable %qD "
16637 			"in %<#pragma acc declare%>", decl);
16638 	      error = true;
16639 	      continue;
16640 	    }
16641 	  else if (TREE_PUBLIC (decl))
16642 	    {
16643 	      error_at (loc,
16644 			"invalid use of %<global%> variable %qD "
16645 			"in %<#pragma acc declare%>", decl);
16646 	      error = true;
16647 	      continue;
16648 	    }
16649 	  break;
16650 	}
16651 
16652       if (!c_check_in_current_scope (decl))
16653 	{
16654 	  error_at (loc,
16655 		    "%qD must be a variable declared in the same scope as "
16656 		    "%<#pragma acc declare%>", decl);
16657 	  error = true;
16658 	  continue;
16659 	}
16660 
16661       if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl))
16662 	  || lookup_attribute ("omp declare target link",
16663 			       DECL_ATTRIBUTES (decl)))
16664 	{
16665 	  error_at (loc, "variable %qD used more than once with "
16666 		    "%<#pragma acc declare%>", decl);
16667 	  error = true;
16668 	  continue;
16669 	}
16670 
16671       if (!error)
16672 	{
16673 	  tree id;
16674 
16675 	  if (OMP_CLAUSE_MAP_KIND (t) == GOMP_MAP_LINK)
16676 	    id = get_identifier ("omp declare target link");
16677 	  else
16678 	    id = get_identifier ("omp declare target");
16679 
16680 	  DECL_ATTRIBUTES (decl)
16681 			   = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
16682 
16683 	  if (global_bindings_p ())
16684 	    {
16685 	      symtab_node *node = symtab_node::get (decl);
16686 	      if (node != NULL)
16687 		{
16688 		  node->offloadable = 1;
16689 		  if (ENABLE_OFFLOADING)
16690 		    {
16691 		      g->have_offload = true;
16692 		      if (is_a <varpool_node *> (node))
16693 			vec_safe_push (offload_vars, decl);
16694 		    }
16695 		}
16696 	    }
16697 	}
16698     }
16699 
16700   if (error || global_bindings_p ())
16701     return;
16702 
16703   stmt = make_node (OACC_DECLARE);
16704   TREE_TYPE (stmt) = void_type_node;
16705   OACC_DECLARE_CLAUSES (stmt) = clauses;
16706   SET_EXPR_LOCATION (stmt, pragma_loc);
16707 
16708   add_stmt (stmt);
16709 
16710   return;
16711 }
16712 
16713 /* OpenACC 2.0:
16714    # pragma acc enter data oacc-enter-data-clause[optseq] new-line
16715 
16716    or
16717 
16718    # pragma acc exit data oacc-exit-data-clause[optseq] new-line
16719 
16720 
16721    LOC is the location of the #pragma token.
16722 */
16723 
16724 #define OACC_ENTER_DATA_CLAUSE_MASK					\
16725 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)			\
16726 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)		\
16727 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH)		\
16728 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)		\
16729 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)		\
16730 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16731 
16732 #define OACC_EXIT_DATA_CLAUSE_MASK					\
16733 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)			\
16734 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)		\
16735 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)		\
16736 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) 		\
16737 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) 		\
16738 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) 		\
16739 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16740 
16741 static void
c_parser_oacc_enter_exit_data(c_parser * parser,bool enter)16742 c_parser_oacc_enter_exit_data (c_parser *parser, bool enter)
16743 {
16744   location_t loc = c_parser_peek_token (parser)->location;
16745   tree clauses, stmt;
16746   const char *p = "";
16747 
16748   c_parser_consume_pragma (parser);
16749 
16750   if (c_parser_next_token_is (parser, CPP_NAME))
16751     {
16752       p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16753       c_parser_consume_token (parser);
16754     }
16755 
16756   if (strcmp (p, "data") != 0)
16757     {
16758       error_at (loc, "expected %<data%> after %<#pragma acc %s%>",
16759 		enter ? "enter" : "exit");
16760       parser->error = true;
16761       c_parser_skip_to_pragma_eol (parser);
16762       return;
16763     }
16764 
16765   if (enter)
16766     clauses = c_parser_oacc_all_clauses (parser, OACC_ENTER_DATA_CLAUSE_MASK,
16767 					 "#pragma acc enter data");
16768   else
16769     clauses = c_parser_oacc_all_clauses (parser, OACC_EXIT_DATA_CLAUSE_MASK,
16770 					 "#pragma acc exit data");
16771 
16772   if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
16773     {
16774       error_at (loc, "%<#pragma acc %s data%> has no data movement clause",
16775 		enter ? "enter" : "exit");
16776       return;
16777     }
16778 
16779   stmt = enter ? make_node (OACC_ENTER_DATA) : make_node (OACC_EXIT_DATA);
16780   TREE_TYPE (stmt) = void_type_node;
16781   OMP_STANDALONE_CLAUSES (stmt) = clauses;
16782   SET_EXPR_LOCATION (stmt, loc);
16783   add_stmt (stmt);
16784 }
16785 
16786 
16787 /* OpenACC 2.0:
16788    # pragma acc host_data oacc-data-clause[optseq] new-line
16789      structured-block
16790 */
16791 
16792 #define OACC_HOST_DATA_CLAUSE_MASK					\
16793 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE)          \
16794 	 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)                  \
16795 	 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
16796 
16797 static tree
c_parser_oacc_host_data(location_t loc,c_parser * parser,bool * if_p)16798 c_parser_oacc_host_data (location_t loc, c_parser *parser, bool *if_p)
16799 {
16800   tree stmt, clauses, block;
16801 
16802   clauses = c_parser_oacc_all_clauses (parser, OACC_HOST_DATA_CLAUSE_MASK,
16803 				       "#pragma acc host_data");
16804 
16805   block = c_begin_omp_parallel ();
16806   add_stmt (c_parser_omp_structured_block (parser, if_p));
16807   stmt = c_finish_oacc_host_data (loc, clauses, block);
16808   return stmt;
16809 }
16810 
16811 
16812 /* OpenACC 2.0:
16813 
16814    # pragma acc loop oacc-loop-clause[optseq] new-line
16815      structured-block
16816 
16817    LOC is the location of the #pragma token.
16818 */
16819 
16820 #define OACC_LOOP_CLAUSE_MASK						\
16821 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE)		\
16822 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE)		\
16823 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION)		\
16824 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG)		\
16825 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER)		\
16826 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR)		\
16827 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO)		\
16828 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) 	\
16829 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ)			\
16830 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
16831 static tree
c_parser_oacc_loop(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)16832 c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name,
16833 		    omp_clause_mask mask, tree *cclauses, bool *if_p)
16834 {
16835   bool is_parallel = ((mask >> PRAGMA_OACC_CLAUSE_REDUCTION) & 1) == 1;
16836 
16837   strcat (p_name, " loop");
16838   mask |= OACC_LOOP_CLAUSE_MASK;
16839 
16840   tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name,
16841 					    cclauses == NULL);
16842   if (cclauses)
16843     {
16844       clauses = c_oacc_split_loop_clauses (clauses, cclauses, is_parallel);
16845       if (*cclauses)
16846 	*cclauses = c_finish_omp_clauses (*cclauses, C_ORT_ACC);
16847       if (clauses)
16848 	clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
16849     }
16850 
16851   tree block = c_begin_compound_stmt (true);
16852   tree stmt = c_parser_omp_for_loop (loc, parser, OACC_LOOP, clauses, NULL,
16853 				     if_p);
16854   block = c_end_compound_stmt (loc, block, true);
16855   add_stmt (block);
16856 
16857   return stmt;
16858 }
16859 
16860 /* OpenACC 2.0:
16861    # pragma acc kernels oacc-kernels-clause[optseq] new-line
16862      structured-block
16863 
16864    or
16865 
16866    # pragma acc parallel oacc-parallel-clause[optseq] new-line
16867      structured-block
16868 
16869    OpenACC 2.6:
16870 
16871    # pragma acc serial oacc-serial-clause[optseq] new-line
16872      structured-block
16873 
16874    LOC is the location of the #pragma token.
16875 */
16876 
16877 #define OACC_KERNELS_CLAUSE_MASK					\
16878 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)		\
16879 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH)		\
16880 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY)		\
16881 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)		\
16882 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)		\
16883 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)		\
16884 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT)		\
16885 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)		\
16886 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)			\
16887 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE)		\
16888 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS)		\
16889 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS)		\
16890 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT)		\
16891 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH)	\
16892 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16893 
16894 #define OACC_PARALLEL_CLAUSE_MASK					\
16895 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)		\
16896 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH)		\
16897 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY)		\
16898 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)		\
16899 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)		\
16900 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)		\
16901 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT)		\
16902 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)		\
16903 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)			\
16904 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE)		\
16905 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE)		\
16906 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE)	\
16907 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS)		\
16908 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS)		\
16909 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT)		\
16910 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION)		\
16911 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH)	\
16912 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16913 
16914 #define OACC_SERIAL_CLAUSE_MASK					\
16915 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)		\
16916 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH)		\
16917 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY)		\
16918 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)		\
16919 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)		\
16920 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)		\
16921 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT)		\
16922 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)		\
16923 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)			\
16924 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE)		\
16925 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE)		\
16926 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE)	\
16927 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT)		\
16928 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION)		\
16929 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16930 
16931 static tree
c_parser_oacc_compute(location_t loc,c_parser * parser,enum pragma_kind p_kind,char * p_name,bool * if_p)16932 c_parser_oacc_compute (location_t loc, c_parser *parser,
16933 		       enum pragma_kind p_kind, char *p_name, bool *if_p)
16934 {
16935   omp_clause_mask mask;
16936   enum tree_code code;
16937   switch (p_kind)
16938     {
16939     case PRAGMA_OACC_KERNELS:
16940       strcat (p_name, " kernels");
16941       mask = OACC_KERNELS_CLAUSE_MASK;
16942       code = OACC_KERNELS;
16943       break;
16944     case PRAGMA_OACC_PARALLEL:
16945       strcat (p_name, " parallel");
16946       mask = OACC_PARALLEL_CLAUSE_MASK;
16947       code = OACC_PARALLEL;
16948       break;
16949     case PRAGMA_OACC_SERIAL:
16950       strcat (p_name, " serial");
16951       mask = OACC_SERIAL_CLAUSE_MASK;
16952       code = OACC_SERIAL;
16953       break;
16954     default:
16955       gcc_unreachable ();
16956     }
16957 
16958   if (c_parser_next_token_is (parser, CPP_NAME))
16959     {
16960       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16961       if (strcmp (p, "loop") == 0)
16962 	{
16963 	  c_parser_consume_token (parser);
16964 	  tree block = c_begin_omp_parallel ();
16965 	  tree clauses;
16966 	  c_parser_oacc_loop (loc, parser, p_name, mask, &clauses, if_p);
16967 	  return c_finish_omp_construct (loc, code, block, clauses);
16968 	}
16969     }
16970 
16971   tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name);
16972 
16973   tree block = c_begin_omp_parallel ();
16974   add_stmt (c_parser_omp_structured_block (parser, if_p));
16975 
16976   return c_finish_omp_construct (loc, code, block, clauses);
16977 }
16978 
16979 /* OpenACC 2.0:
16980    # pragma acc routine oacc-routine-clause[optseq] new-line
16981      function-definition
16982 
16983    # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
16984 */
16985 
16986 #define OACC_ROUTINE_CLAUSE_MASK					\
16987 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG)		\
16988 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER)		\
16989 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR)		\
16990 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) )
16991 
16992 /* Parse an OpenACC routine directive.  For named directives, we apply
16993    immediately to the named function.  For unnamed ones we then parse
16994    a declaration or definition, which must be for a function.  */
16995 
16996 static void
c_parser_oacc_routine(c_parser * parser,enum pragma_context context)16997 c_parser_oacc_routine (c_parser *parser, enum pragma_context context)
16998 {
16999   gcc_checking_assert (context == pragma_external);
17000 
17001   oacc_routine_data data;
17002   data.error_seen = false;
17003   data.fndecl_seen = false;
17004   data.loc = c_parser_peek_token (parser)->location;
17005 
17006   c_parser_consume_pragma (parser);
17007 
17008   /* Look for optional '( name )'.  */
17009   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
17010     {
17011       c_parser_consume_token (parser); /* '(' */
17012 
17013       tree decl = NULL_TREE;
17014       c_token *name_token = c_parser_peek_token (parser);
17015       location_t name_loc = name_token->location;
17016       if (name_token->type == CPP_NAME
17017 	  && (name_token->id_kind == C_ID_ID
17018 	      || name_token->id_kind == C_ID_TYPENAME))
17019 	{
17020 	  decl = lookup_name (name_token->value);
17021 	  if (!decl)
17022 	    error_at (name_loc,
17023 		      "%qE has not been declared", name_token->value);
17024 	  c_parser_consume_token (parser);
17025 	}
17026       else
17027 	c_parser_error (parser, "expected function name");
17028 
17029       if (!decl
17030 	  || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
17031 	{
17032 	  c_parser_skip_to_pragma_eol (parser, false);
17033 	  return;
17034 	}
17035 
17036       data.clauses
17037 	= c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
17038 				     "#pragma acc routine");
17039       /* The clauses are in reverse order; fix that to make later diagnostic
17040 	 emission easier.  */
17041       data.clauses = nreverse (data.clauses);
17042 
17043       if (TREE_CODE (decl) != FUNCTION_DECL)
17044 	{
17045 	  error_at (name_loc, "%qD does not refer to a function", decl);
17046 	  return;
17047 	}
17048 
17049       c_finish_oacc_routine (&data, decl, false);
17050     }
17051   else /* No optional '( name )'.  */
17052     {
17053       data.clauses
17054 	= c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
17055 				     "#pragma acc routine");
17056       /* The clauses are in reverse order; fix that to make later diagnostic
17057 	 emission easier.  */
17058       data.clauses = nreverse (data.clauses);
17059 
17060       /* Emit a helpful diagnostic if there's another pragma following this
17061 	 one.  Also don't allow a static assertion declaration, as in the
17062 	 following we'll just parse a *single* "declaration or function
17063 	 definition", and the static assertion counts an one.  */
17064       if (c_parser_next_token_is (parser, CPP_PRAGMA)
17065 	  || c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
17066 	{
17067 	  error_at (data.loc,
17068 		    "%<#pragma acc routine%> not immediately followed by"
17069 		    " function declaration or definition");
17070 	  /* ..., and then just keep going.  */
17071 	  return;
17072 	}
17073 
17074       /* We only have to consider the pragma_external case here.  */
17075       if (c_parser_next_token_is (parser, CPP_KEYWORD)
17076 	  && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
17077 	{
17078 	  int ext = disable_extension_diagnostics ();
17079 	  do
17080 	    c_parser_consume_token (parser);
17081 	  while (c_parser_next_token_is (parser, CPP_KEYWORD)
17082 		 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
17083 	  c_parser_declaration_or_fndef (parser, true, true, true, false, true,
17084 					 NULL, vNULL, false, NULL, &data);
17085 	  restore_extension_diagnostics (ext);
17086 	}
17087       else
17088 	c_parser_declaration_or_fndef (parser, true, true, true, false, true,
17089 				       NULL, vNULL, false, NULL, &data);
17090     }
17091 }
17092 
17093 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
17094    IS_DEFN is true if we're applying it to the definition.  */
17095 
17096 static void
c_finish_oacc_routine(struct oacc_routine_data * data,tree fndecl,bool is_defn)17097 c_finish_oacc_routine (struct oacc_routine_data *data, tree fndecl,
17098 		       bool is_defn)
17099 {
17100   /* Keep going if we're in error reporting mode.  */
17101   if (data->error_seen
17102       || fndecl == error_mark_node)
17103     return;
17104 
17105   if (data->fndecl_seen)
17106     {
17107       error_at (data->loc,
17108 		"%<#pragma acc routine%> not immediately followed by"
17109 		" a single function declaration or definition");
17110       data->error_seen = true;
17111       return;
17112     }
17113   if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
17114     {
17115       error_at (data->loc,
17116 		"%<#pragma acc routine%> not immediately followed by"
17117 		" function declaration or definition");
17118       data->error_seen = true;
17119       return;
17120     }
17121 
17122   int compatible
17123     = oacc_verify_routine_clauses (fndecl, &data->clauses, data->loc,
17124 				   "#pragma acc routine");
17125   if (compatible < 0)
17126     {
17127       data->error_seen = true;
17128       return;
17129     }
17130   if (compatible > 0)
17131     {
17132     }
17133   else
17134     {
17135       if (TREE_USED (fndecl) || (!is_defn && DECL_SAVED_TREE (fndecl)))
17136 	{
17137 	  error_at (data->loc,
17138 		    TREE_USED (fndecl)
17139 		    ? G_("%<#pragma acc routine%> must be applied before use")
17140 		    : G_("%<#pragma acc routine%> must be applied before"
17141 			 " definition"));
17142 	  data->error_seen = true;
17143 	  return;
17144 	}
17145 
17146       /* Set the routine's level of parallelism.  */
17147       tree dims = oacc_build_routine_dims (data->clauses);
17148       oacc_replace_fn_attrib (fndecl, dims);
17149 
17150       /* Add an "omp declare target" attribute.  */
17151       DECL_ATTRIBUTES (fndecl)
17152 	= tree_cons (get_identifier ("omp declare target"),
17153 		     data->clauses, DECL_ATTRIBUTES (fndecl));
17154     }
17155 
17156   /* Remember that we've used this "#pragma acc routine".  */
17157   data->fndecl_seen = true;
17158 }
17159 
17160 /* OpenACC 2.0:
17161    # pragma acc update oacc-update-clause[optseq] new-line
17162 */
17163 
17164 #define OACC_UPDATE_CLAUSE_MASK						\
17165 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)		\
17166 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE)		\
17167 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST)		\
17168 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)			\
17169 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT)		\
17170 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17171 
17172 static void
c_parser_oacc_update(c_parser * parser)17173 c_parser_oacc_update (c_parser *parser)
17174 {
17175   location_t loc = c_parser_peek_token (parser)->location;
17176 
17177   c_parser_consume_pragma (parser);
17178 
17179   tree clauses = c_parser_oacc_all_clauses (parser, OACC_UPDATE_CLAUSE_MASK,
17180 					    "#pragma acc update");
17181   if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
17182     {
17183       error_at (loc,
17184 		"%<#pragma acc update%> must contain at least one "
17185 		"%<device%> or %<host%> or %<self%> clause");
17186       return;
17187     }
17188 
17189   if (parser->error)
17190     return;
17191 
17192   tree stmt = make_node (OACC_UPDATE);
17193   TREE_TYPE (stmt) = void_type_node;
17194   OACC_UPDATE_CLAUSES (stmt) = clauses;
17195   SET_EXPR_LOCATION (stmt, loc);
17196   add_stmt (stmt);
17197 }
17198 
17199 /* OpenACC 2.0:
17200    # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
17201 
17202    LOC is the location of the #pragma token.
17203 */
17204 
17205 #define OACC_WAIT_CLAUSE_MASK						\
17206 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
17207 
17208 static tree
c_parser_oacc_wait(location_t loc,c_parser * parser,char * p_name)17209 c_parser_oacc_wait (location_t loc, c_parser *parser, char *p_name)
17210 {
17211   tree clauses, list = NULL_TREE, stmt = NULL_TREE;
17212 
17213   if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
17214     list = c_parser_oacc_wait_list (parser, loc, list);
17215 
17216   strcpy (p_name, " wait");
17217   clauses = c_parser_oacc_all_clauses (parser, OACC_WAIT_CLAUSE_MASK, p_name);
17218   stmt = c_finish_oacc_wait (loc, list, clauses);
17219   add_stmt (stmt);
17220 
17221   return stmt;
17222 }
17223 
17224 /* OpenMP 2.5:
17225    # pragma omp atomic new-line
17226      expression-stmt
17227 
17228    expression-stmt:
17229      x binop= expr | x++ | ++x | x-- | --x
17230    binop:
17231      +, *, -, /, &, ^, |, <<, >>
17232 
17233   where x is an lvalue expression with scalar type.
17234 
17235    OpenMP 3.1:
17236    # pragma omp atomic new-line
17237      update-stmt
17238 
17239    # pragma omp atomic read new-line
17240      read-stmt
17241 
17242    # pragma omp atomic write new-line
17243      write-stmt
17244 
17245    # pragma omp atomic update new-line
17246      update-stmt
17247 
17248    # pragma omp atomic capture new-line
17249      capture-stmt
17250 
17251    # pragma omp atomic capture new-line
17252      capture-block
17253 
17254    read-stmt:
17255      v = x
17256    write-stmt:
17257      x = expr
17258    update-stmt:
17259      expression-stmt | x = x binop expr
17260    capture-stmt:
17261      v = expression-stmt
17262    capture-block:
17263      { v = x; update-stmt; } | { update-stmt; v = x; }
17264 
17265    OpenMP 4.0:
17266    update-stmt:
17267      expression-stmt | x = x binop expr | x = expr binop x
17268    capture-stmt:
17269      v = update-stmt
17270    capture-block:
17271      { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
17272 
17273   where x and v are lvalue expressions with scalar type.
17274 
17275   LOC is the location of the #pragma token.  */
17276 
17277 static void
c_parser_omp_atomic(location_t loc,c_parser * parser)17278 c_parser_omp_atomic (location_t loc, c_parser *parser)
17279 {
17280   tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE;
17281   tree lhs1 = NULL_TREE, rhs1 = NULL_TREE;
17282   tree stmt, orig_lhs, unfolded_lhs = NULL_TREE, unfolded_lhs1 = NULL_TREE;
17283   enum tree_code code = ERROR_MARK, opcode = NOP_EXPR;
17284   enum omp_memory_order memory_order = OMP_MEMORY_ORDER_UNSPECIFIED;
17285   struct c_expr expr;
17286   location_t eloc;
17287   bool structured_block = false;
17288   bool swapped = false;
17289   bool non_lvalue_p;
17290   bool first = true;
17291   tree clauses = NULL_TREE;
17292 
17293   while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
17294     {
17295       if (!first && c_parser_next_token_is (parser, CPP_COMMA))
17296 	c_parser_consume_token (parser);
17297 
17298       first = false;
17299 
17300       if (c_parser_next_token_is (parser, CPP_NAME))
17301 	{
17302 	  const char *p
17303 	    = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17304 	  location_t cloc = c_parser_peek_token (parser)->location;
17305 	  enum tree_code new_code = ERROR_MARK;
17306 	  enum omp_memory_order new_memory_order
17307 	    = OMP_MEMORY_ORDER_UNSPECIFIED;
17308 
17309 	  if (!strcmp (p, "read"))
17310 	    new_code = OMP_ATOMIC_READ;
17311 	  else if (!strcmp (p, "write"))
17312 	    new_code = NOP_EXPR;
17313 	  else if (!strcmp (p, "update"))
17314 	    new_code = OMP_ATOMIC;
17315 	  else if (!strcmp (p, "capture"))
17316 	    new_code = OMP_ATOMIC_CAPTURE_NEW;
17317 	  else if (!strcmp (p, "seq_cst"))
17318 	    new_memory_order = OMP_MEMORY_ORDER_SEQ_CST;
17319 	  else if (!strcmp (p, "acq_rel"))
17320 	    new_memory_order = OMP_MEMORY_ORDER_ACQ_REL;
17321 	  else if (!strcmp (p, "release"))
17322 	    new_memory_order = OMP_MEMORY_ORDER_RELEASE;
17323 	  else if (!strcmp (p, "acquire"))
17324 	    new_memory_order = OMP_MEMORY_ORDER_ACQUIRE;
17325 	  else if (!strcmp (p, "relaxed"))
17326 	    new_memory_order = OMP_MEMORY_ORDER_RELAXED;
17327 	  else if (!strcmp (p, "hint"))
17328 	    {
17329 	      c_parser_consume_token (parser);
17330 	      clauses = c_parser_omp_clause_hint (parser, clauses);
17331 	      continue;
17332 	    }
17333 	  else
17334 	    {
17335 	      p = NULL;
17336 	      error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
17337 			      "%<capture%>, %<seq_cst%>, %<acq_rel%>, "
17338 			      "%<release%>, %<relaxed%> or %<hint%> clause");
17339 	    }
17340 	  if (p)
17341 	    {
17342 	      if (new_code != ERROR_MARK)
17343 		{
17344 		  if (code != ERROR_MARK)
17345 		    error_at (cloc, "too many atomic clauses");
17346 		  else
17347 		    code = new_code;
17348 		}
17349 	      else if (new_memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
17350 		{
17351 		  if (memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
17352 		    error_at (cloc, "too many memory order clauses");
17353 		  else
17354 		    memory_order = new_memory_order;
17355 		}
17356 	      c_parser_consume_token (parser);
17357 	      continue;
17358 	    }
17359 	}
17360       break;
17361     }
17362   c_parser_skip_to_pragma_eol (parser);
17363 
17364   if (code == ERROR_MARK)
17365     code = OMP_ATOMIC;
17366   if (memory_order == OMP_MEMORY_ORDER_UNSPECIFIED)
17367     {
17368       omp_requires_mask
17369 	= (enum omp_requires) (omp_requires_mask
17370 			       | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED);
17371       switch ((enum omp_memory_order)
17372 	      (omp_requires_mask & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER))
17373 	{
17374 	case OMP_MEMORY_ORDER_UNSPECIFIED:
17375 	case OMP_MEMORY_ORDER_RELAXED:
17376 	  memory_order = OMP_MEMORY_ORDER_RELAXED;
17377 	  break;
17378 	case OMP_MEMORY_ORDER_SEQ_CST:
17379 	  memory_order = OMP_MEMORY_ORDER_SEQ_CST;
17380 	  break;
17381 	case OMP_MEMORY_ORDER_ACQ_REL:
17382 	  switch (code)
17383 	    {
17384 	    case OMP_ATOMIC_READ:
17385 	      memory_order = OMP_MEMORY_ORDER_ACQUIRE;
17386 	      break;
17387 	    case NOP_EXPR: /* atomic write */
17388 	    case OMP_ATOMIC:
17389 	      memory_order = OMP_MEMORY_ORDER_RELEASE;
17390 	      break;
17391 	    default:
17392 	      memory_order = OMP_MEMORY_ORDER_ACQ_REL;
17393 	      break;
17394 	    }
17395 	  break;
17396 	default:
17397 	  gcc_unreachable ();
17398 	}
17399     }
17400   else
17401     switch (code)
17402       {
17403       case OMP_ATOMIC_READ:
17404 	if (memory_order == OMP_MEMORY_ORDER_ACQ_REL
17405 	    || memory_order == OMP_MEMORY_ORDER_RELEASE)
17406 	  {
17407 	    error_at (loc, "%<#pragma omp atomic read%> incompatible with "
17408 			   "%<acq_rel%> or %<release%> clauses");
17409 	    memory_order = OMP_MEMORY_ORDER_SEQ_CST;
17410 	  }
17411 	break;
17412       case NOP_EXPR: /* atomic write */
17413 	if (memory_order == OMP_MEMORY_ORDER_ACQ_REL
17414 	    || memory_order == OMP_MEMORY_ORDER_ACQUIRE)
17415 	  {
17416 	    error_at (loc, "%<#pragma omp atomic write%> incompatible with "
17417 			   "%<acq_rel%> or %<acquire%> clauses");
17418 	    memory_order = OMP_MEMORY_ORDER_SEQ_CST;
17419 	  }
17420 	break;
17421       case OMP_ATOMIC:
17422 	if (memory_order == OMP_MEMORY_ORDER_ACQ_REL
17423 	    || memory_order == OMP_MEMORY_ORDER_ACQUIRE)
17424 	  {
17425 	    error_at (loc, "%<#pragma omp atomic update%> incompatible with "
17426 			   "%<acq_rel%> or %<acquire%> clauses");
17427 	    memory_order = OMP_MEMORY_ORDER_SEQ_CST;
17428 	  }
17429 	break;
17430       default:
17431 	break;
17432       }
17433 
17434   switch (code)
17435     {
17436     case OMP_ATOMIC_READ:
17437     case NOP_EXPR: /* atomic write */
17438       v = c_parser_cast_expression (parser, NULL).value;
17439       non_lvalue_p = !lvalue_p (v);
17440       v = c_fully_fold (v, false, NULL, true);
17441       if (v == error_mark_node)
17442 	goto saw_error;
17443       if (non_lvalue_p)
17444 	v = non_lvalue (v);
17445       loc = c_parser_peek_token (parser)->location;
17446       if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
17447 	goto saw_error;
17448       if (code == NOP_EXPR)
17449 	{
17450 	  lhs = c_parser_expression (parser).value;
17451 	  lhs = c_fully_fold (lhs, false, NULL);
17452 	  if (lhs == error_mark_node)
17453 	    goto saw_error;
17454 	}
17455       else
17456 	{
17457 	  lhs = c_parser_cast_expression (parser, NULL).value;
17458 	  non_lvalue_p = !lvalue_p (lhs);
17459 	  lhs = c_fully_fold (lhs, false, NULL, true);
17460 	  if (lhs == error_mark_node)
17461 	    goto saw_error;
17462 	  if (non_lvalue_p)
17463 	    lhs = non_lvalue (lhs);
17464 	}
17465       if (code == NOP_EXPR)
17466 	{
17467 	  /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
17468 	     opcode.  */
17469 	  code = OMP_ATOMIC;
17470 	  rhs = lhs;
17471 	  lhs = v;
17472 	  v = NULL_TREE;
17473 	}
17474       goto done;
17475     case OMP_ATOMIC_CAPTURE_NEW:
17476       if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
17477 	{
17478 	  c_parser_consume_token (parser);
17479 	  structured_block = true;
17480 	}
17481       else
17482 	{
17483 	  v = c_parser_cast_expression (parser, NULL).value;
17484 	  non_lvalue_p = !lvalue_p (v);
17485 	  v = c_fully_fold (v, false, NULL, true);
17486 	  if (v == error_mark_node)
17487 	    goto saw_error;
17488 	  if (non_lvalue_p)
17489 	    v = non_lvalue (v);
17490 	  if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
17491 	    goto saw_error;
17492 	}
17493       break;
17494     default:
17495       break;
17496     }
17497 
17498   /* For structured_block case we don't know yet whether
17499      old or new x should be captured.  */
17500 restart:
17501   eloc = c_parser_peek_token (parser)->location;
17502   expr = c_parser_cast_expression (parser, NULL);
17503   lhs = expr.value;
17504   expr = default_function_array_conversion (eloc, expr);
17505   unfolded_lhs = expr.value;
17506   lhs = c_fully_fold (lhs, false, NULL, true);
17507   orig_lhs = lhs;
17508   switch (TREE_CODE (lhs))
17509     {
17510     case ERROR_MARK:
17511     saw_error:
17512       c_parser_skip_to_end_of_block_or_statement (parser);
17513       if (structured_block)
17514 	{
17515 	  if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
17516 	    c_parser_consume_token (parser);
17517 	  else if (code == OMP_ATOMIC_CAPTURE_NEW)
17518 	    {
17519 	      c_parser_skip_to_end_of_block_or_statement (parser);
17520 	      if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
17521 		c_parser_consume_token (parser);
17522 	    }
17523 	}
17524       return;
17525 
17526     case POSTINCREMENT_EXPR:
17527       if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
17528 	code = OMP_ATOMIC_CAPTURE_OLD;
17529       /* FALLTHROUGH */
17530     case PREINCREMENT_EXPR:
17531       lhs = TREE_OPERAND (lhs, 0);
17532       unfolded_lhs = NULL_TREE;
17533       opcode = PLUS_EXPR;
17534       rhs = integer_one_node;
17535       break;
17536 
17537     case POSTDECREMENT_EXPR:
17538       if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
17539 	code = OMP_ATOMIC_CAPTURE_OLD;
17540       /* FALLTHROUGH */
17541     case PREDECREMENT_EXPR:
17542       lhs = TREE_OPERAND (lhs, 0);
17543       unfolded_lhs = NULL_TREE;
17544       opcode = MINUS_EXPR;
17545       rhs = integer_one_node;
17546       break;
17547 
17548     case COMPOUND_EXPR:
17549       if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR
17550 	  && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR
17551 	  && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR
17552 	  && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0)
17553 	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
17554 					      (TREE_OPERAND (lhs, 1), 0), 0)))
17555 	     == BOOLEAN_TYPE)
17556 	/* Undo effects of boolean_increment for post {in,de}crement.  */
17557 	lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
17558       /* FALLTHRU */
17559     case MODIFY_EXPR:
17560       if (TREE_CODE (lhs) == MODIFY_EXPR
17561 	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) == BOOLEAN_TYPE)
17562 	{
17563 	  /* Undo effects of boolean_increment.  */
17564 	  if (integer_onep (TREE_OPERAND (lhs, 1)))
17565 	    {
17566 	      /* This is pre or post increment.  */
17567 	      rhs = TREE_OPERAND (lhs, 1);
17568 	      lhs = TREE_OPERAND (lhs, 0);
17569 	      unfolded_lhs = NULL_TREE;
17570 	      opcode = NOP_EXPR;
17571 	      if (code == OMP_ATOMIC_CAPTURE_NEW
17572 		  && !structured_block
17573 		  && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
17574 		code = OMP_ATOMIC_CAPTURE_OLD;
17575 	      break;
17576 	    }
17577 	  if (TREE_CODE (TREE_OPERAND (lhs, 1)) == TRUTH_NOT_EXPR
17578 	      && TREE_OPERAND (lhs, 0)
17579 		 == TREE_OPERAND (TREE_OPERAND (lhs, 1), 0))
17580 	    {
17581 	      /* This is pre or post decrement.  */
17582 	      rhs = TREE_OPERAND (lhs, 1);
17583 	      lhs = TREE_OPERAND (lhs, 0);
17584 	      unfolded_lhs = NULL_TREE;
17585 	      opcode = NOP_EXPR;
17586 	      if (code == OMP_ATOMIC_CAPTURE_NEW
17587 		  && !structured_block
17588 		  && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
17589 		code = OMP_ATOMIC_CAPTURE_OLD;
17590 	      break;
17591 	    }
17592 	}
17593       /* FALLTHRU */
17594     default:
17595       if (!lvalue_p (unfolded_lhs))
17596 	lhs = non_lvalue (lhs);
17597       switch (c_parser_peek_token (parser)->type)
17598 	{
17599 	case CPP_MULT_EQ:
17600 	  opcode = MULT_EXPR;
17601 	  break;
17602 	case CPP_DIV_EQ:
17603 	  opcode = TRUNC_DIV_EXPR;
17604 	  break;
17605 	case CPP_PLUS_EQ:
17606 	  opcode = PLUS_EXPR;
17607 	  break;
17608 	case CPP_MINUS_EQ:
17609 	  opcode = MINUS_EXPR;
17610 	  break;
17611 	case CPP_LSHIFT_EQ:
17612 	  opcode = LSHIFT_EXPR;
17613 	  break;
17614 	case CPP_RSHIFT_EQ:
17615 	  opcode = RSHIFT_EXPR;
17616 	  break;
17617 	case CPP_AND_EQ:
17618 	  opcode = BIT_AND_EXPR;
17619 	  break;
17620 	case CPP_OR_EQ:
17621 	  opcode = BIT_IOR_EXPR;
17622 	  break;
17623 	case CPP_XOR_EQ:
17624 	  opcode = BIT_XOR_EXPR;
17625 	  break;
17626 	case CPP_EQ:
17627 	  c_parser_consume_token (parser);
17628 	  eloc = c_parser_peek_token (parser)->location;
17629 	  expr = c_parser_expr_no_commas (parser, NULL, unfolded_lhs);
17630 	  rhs1 = expr.value;
17631 	  switch (TREE_CODE (rhs1))
17632 	    {
17633 	    case MULT_EXPR:
17634 	    case TRUNC_DIV_EXPR:
17635 	    case RDIV_EXPR:
17636 	    case PLUS_EXPR:
17637 	    case MINUS_EXPR:
17638 	    case LSHIFT_EXPR:
17639 	    case RSHIFT_EXPR:
17640 	    case BIT_AND_EXPR:
17641 	    case BIT_IOR_EXPR:
17642 	    case BIT_XOR_EXPR:
17643 	      if (c_tree_equal (TREE_OPERAND (rhs1, 0), unfolded_lhs))
17644 		{
17645 		  opcode = TREE_CODE (rhs1);
17646 		  rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
17647 				      true);
17648 		  rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
17649 				       true);
17650 		  goto stmt_done;
17651 		}
17652 	      if (c_tree_equal (TREE_OPERAND (rhs1, 1), unfolded_lhs))
17653 		{
17654 		  opcode = TREE_CODE (rhs1);
17655 		  rhs = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
17656 				      true);
17657 		  rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
17658 				       true);
17659 		  swapped = !commutative_tree_code (opcode);
17660 		  goto stmt_done;
17661 		}
17662 	      break;
17663 	    case ERROR_MARK:
17664 	      goto saw_error;
17665 	    default:
17666 	      break;
17667 	    }
17668 	  if (c_parser_peek_token (parser)->type == CPP_SEMICOLON)
17669 	    {
17670 	      if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
17671 		{
17672 		  code = OMP_ATOMIC_CAPTURE_OLD;
17673 		  v = lhs;
17674 		  lhs = NULL_TREE;
17675 		  expr = default_function_array_read_conversion (eloc, expr);
17676 		  unfolded_lhs1 = expr.value;
17677 		  lhs1 = c_fully_fold (unfolded_lhs1, false, NULL, true);
17678 		  rhs1 = NULL_TREE;
17679 		  c_parser_consume_token (parser);
17680 		  goto restart;
17681 		}
17682 	      if (structured_block)
17683 		{
17684 		  opcode = NOP_EXPR;
17685 		  expr = default_function_array_read_conversion (eloc, expr);
17686 		  rhs = c_fully_fold (expr.value, false, NULL, true);
17687 		  rhs1 = NULL_TREE;
17688 		  goto stmt_done;
17689 		}
17690 	    }
17691 	  c_parser_error (parser, "invalid form of %<#pragma omp atomic%>");
17692 	  goto saw_error;
17693 	default:
17694 	  c_parser_error (parser,
17695 			  "invalid operator for %<#pragma omp atomic%>");
17696 	  goto saw_error;
17697 	}
17698 
17699       /* Arrange to pass the location of the assignment operator to
17700 	 c_finish_omp_atomic.  */
17701       loc = c_parser_peek_token (parser)->location;
17702       c_parser_consume_token (parser);
17703       eloc = c_parser_peek_token (parser)->location;
17704       expr = c_parser_expression (parser);
17705       expr = default_function_array_read_conversion (eloc, expr);
17706       rhs = expr.value;
17707       rhs = c_fully_fold (rhs, false, NULL, true);
17708       break;
17709     }
17710 stmt_done:
17711   if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
17712     {
17713       if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
17714 	goto saw_error;
17715       v = c_parser_cast_expression (parser, NULL).value;
17716       non_lvalue_p = !lvalue_p (v);
17717       v = c_fully_fold (v, false, NULL, true);
17718       if (v == error_mark_node)
17719 	goto saw_error;
17720       if (non_lvalue_p)
17721 	v = non_lvalue (v);
17722       if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
17723 	goto saw_error;
17724       eloc = c_parser_peek_token (parser)->location;
17725       expr = c_parser_cast_expression (parser, NULL);
17726       lhs1 = expr.value;
17727       expr = default_function_array_read_conversion (eloc, expr);
17728       unfolded_lhs1 = expr.value;
17729       lhs1 = c_fully_fold (lhs1, false, NULL, true);
17730       if (lhs1 == error_mark_node)
17731 	goto saw_error;
17732       if (!lvalue_p (unfolded_lhs1))
17733 	lhs1 = non_lvalue (lhs1);
17734     }
17735   if (structured_block)
17736     {
17737       c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
17738       c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>");
17739     }
17740 done:
17741   if (unfolded_lhs && unfolded_lhs1
17742       && !c_tree_equal (unfolded_lhs, unfolded_lhs1))
17743     {
17744       error ("%<#pragma omp atomic capture%> uses two different "
17745 	     "expressions for memory");
17746       stmt = error_mark_node;
17747     }
17748   else
17749     stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs, v, lhs1, rhs1,
17750 				swapped, memory_order);
17751   if (stmt != error_mark_node)
17752     add_stmt (stmt);
17753 
17754   if (!structured_block)
17755     c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
17756 }
17757 
17758 
17759 /* OpenMP 2.5:
17760    # pragma omp barrier new-line
17761 */
17762 
17763 static void
c_parser_omp_barrier(c_parser * parser)17764 c_parser_omp_barrier (c_parser *parser)
17765 {
17766   location_t loc = c_parser_peek_token (parser)->location;
17767   c_parser_consume_pragma (parser);
17768   c_parser_skip_to_pragma_eol (parser);
17769 
17770   c_finish_omp_barrier (loc);
17771 }
17772 
17773 /* OpenMP 2.5:
17774    # pragma omp critical [(name)] new-line
17775      structured-block
17776 
17777    OpenMP 4.5:
17778    # pragma omp critical [(name) [hint(expression)]] new-line
17779 
17780   LOC is the location of the #pragma itself.  */
17781 
17782 #define OMP_CRITICAL_CLAUSE_MASK		\
17783 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
17784 
17785 static tree
c_parser_omp_critical(location_t loc,c_parser * parser,bool * if_p)17786 c_parser_omp_critical (location_t loc, c_parser *parser, bool *if_p)
17787 {
17788   tree stmt, name = NULL_TREE, clauses = NULL_TREE;
17789 
17790   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
17791     {
17792       c_parser_consume_token (parser);
17793       if (c_parser_next_token_is (parser, CPP_NAME))
17794 	{
17795 	  name = c_parser_peek_token (parser)->value;
17796 	  c_parser_consume_token (parser);
17797 	  c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
17798 	}
17799       else
17800 	c_parser_error (parser, "expected identifier");
17801 
17802       if (c_parser_next_token_is (parser, CPP_COMMA)
17803 	  && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
17804 	c_parser_consume_token (parser);
17805 
17806       clauses = c_parser_omp_all_clauses (parser,
17807 					  OMP_CRITICAL_CLAUSE_MASK,
17808 					  "#pragma omp critical");
17809     }
17810   else
17811     {
17812       if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
17813 	c_parser_error (parser, "expected %<(%> or end of line");
17814       c_parser_skip_to_pragma_eol (parser);
17815     }
17816 
17817   stmt = c_parser_omp_structured_block (parser, if_p);
17818   return c_finish_omp_critical (loc, stmt, name, clauses);
17819 }
17820 
17821 /* OpenMP 5.0:
17822    # pragma omp depobj ( depobj ) depobj-clause new-line
17823 
17824    depobj-clause:
17825      depend (dependence-type : locator)
17826      destroy
17827      update (dependence-type)
17828 
17829    dependence-type:
17830      in
17831      out
17832      inout
17833      mutexinout  */
17834 
17835 static void
c_parser_omp_depobj(c_parser * parser)17836 c_parser_omp_depobj (c_parser *parser)
17837 {
17838   location_t loc = c_parser_peek_token (parser)->location;
17839   c_parser_consume_pragma (parser);
17840   matching_parens parens;
17841   if (!parens.require_open (parser))
17842     {
17843       c_parser_skip_to_pragma_eol (parser);
17844       return;
17845     }
17846 
17847   tree depobj = c_parser_expr_no_commas (parser, NULL).value;
17848   if (depobj != error_mark_node)
17849     {
17850       if (!lvalue_p (depobj))
17851 	{
17852 	  error_at (EXPR_LOC_OR_LOC (depobj, loc),
17853 		    "%<depobj%> expression is not lvalue expression");
17854 	  depobj = error_mark_node;
17855 	}
17856       else
17857 	{
17858 	  tree addr = build_unary_op (EXPR_LOC_OR_LOC (depobj, loc), ADDR_EXPR,
17859 				      depobj, false);
17860 	  if (addr == error_mark_node)
17861 	    depobj = error_mark_node;
17862 	  else
17863 	    depobj = build_indirect_ref (EXPR_LOC_OR_LOC (depobj, loc),
17864 					 addr, RO_UNARY_STAR);
17865 	}
17866     }
17867 
17868   parens.skip_until_found_close (parser);
17869   tree clause = NULL_TREE;
17870   enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_SOURCE;
17871   location_t c_loc = c_parser_peek_token (parser)->location;
17872   if (c_parser_next_token_is (parser, CPP_NAME))
17873     {
17874       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17875 
17876       c_parser_consume_token (parser);
17877       if (!strcmp ("depend", p))
17878 	{
17879 	  clause = c_parser_omp_clause_depend (parser, NULL_TREE);
17880 	  clause = c_finish_omp_clauses (clause, C_ORT_OMP);
17881 	  if (!clause)
17882 	    clause = error_mark_node;
17883 	}
17884       else if (!strcmp ("destroy", p))
17885 	kind = OMP_CLAUSE_DEPEND_LAST;
17886       else if (!strcmp ("update", p))
17887 	{
17888 	  matching_parens c_parens;
17889 	  if (c_parens.require_open (parser))
17890 	    {
17891 	      location_t c2_loc = c_parser_peek_token (parser)->location;
17892 	      if (c_parser_next_token_is (parser, CPP_NAME))
17893 		{
17894 		  const char *p2
17895 		    = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17896 
17897 		  c_parser_consume_token (parser);
17898 		  if (!strcmp ("in", p2))
17899 		    kind = OMP_CLAUSE_DEPEND_IN;
17900 		  else if (!strcmp ("out", p2))
17901 		    kind = OMP_CLAUSE_DEPEND_OUT;
17902 		  else if (!strcmp ("inout", p2))
17903 		    kind = OMP_CLAUSE_DEPEND_INOUT;
17904 		  else if (!strcmp ("mutexinoutset", p2))
17905 		    kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
17906 		}
17907 	      if (kind == OMP_CLAUSE_DEPEND_SOURCE)
17908 		{
17909 		  clause = error_mark_node;
17910 		  error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%> or "
17911 				    "%<mutexinoutset%>");
17912 		}
17913 	      c_parens.skip_until_found_close (parser);
17914 	    }
17915 	  else
17916 	    clause = error_mark_node;
17917 	}
17918     }
17919   if (!clause && kind == OMP_CLAUSE_DEPEND_SOURCE)
17920     {
17921       clause = error_mark_node;
17922       error_at (c_loc, "expected %<depend%>, %<destroy%> or %<update%> clause");
17923     }
17924   c_parser_skip_to_pragma_eol (parser);
17925 
17926   c_finish_omp_depobj (loc, depobj, kind, clause);
17927 }
17928 
17929 
17930 /* OpenMP 2.5:
17931    # pragma omp flush flush-vars[opt] new-line
17932 
17933    flush-vars:
17934      ( variable-list )
17935 
17936    OpenMP 5.0:
17937    # pragma omp flush memory-order-clause new-line  */
17938 
17939 static void
c_parser_omp_flush(c_parser * parser)17940 c_parser_omp_flush (c_parser *parser)
17941 {
17942   location_t loc = c_parser_peek_token (parser)->location;
17943   c_parser_consume_pragma (parser);
17944   enum memmodel mo = MEMMODEL_LAST;
17945   if (c_parser_next_token_is (parser, CPP_NAME))
17946     {
17947       const char *p
17948 	= IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17949 
17950       if (!strcmp (p, "acq_rel"))
17951 	mo = MEMMODEL_ACQ_REL;
17952       else if (!strcmp (p, "release"))
17953 	mo = MEMMODEL_RELEASE;
17954       else if (!strcmp (p, "acquire"))
17955 	mo = MEMMODEL_ACQUIRE;
17956       else
17957 	error_at (c_parser_peek_token (parser)->location,
17958 		  "expected %<acq_rel%>, %<release%> or %<acquire%>");
17959       c_parser_consume_token (parser);
17960     }
17961   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
17962     {
17963       if (mo != MEMMODEL_LAST)
17964 	error_at (c_parser_peek_token (parser)->location,
17965 		  "%<flush%> list specified together with memory order "
17966 		  "clause");
17967       c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
17968     }
17969   else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
17970     c_parser_error (parser, "expected %<(%> or end of line");
17971   c_parser_skip_to_pragma_eol (parser);
17972 
17973   c_finish_omp_flush (loc, mo);
17974 }
17975 
17976 /* OpenMP 5.0:
17977 
17978    scan-loop-body:
17979      { structured-block scan-directive structured-block }  */
17980 
17981 static void
c_parser_omp_scan_loop_body(c_parser * parser,bool open_brace_parsed)17982 c_parser_omp_scan_loop_body (c_parser *parser, bool open_brace_parsed)
17983 {
17984   tree substmt;
17985   location_t loc;
17986   tree clauses = NULL_TREE;
17987 
17988   loc = c_parser_peek_token (parser)->location;
17989   if (!open_brace_parsed
17990       && !c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
17991     {
17992       /* Avoid skipping until the end of the block.  */
17993       parser->error = false;
17994       return;
17995     }
17996 
17997   substmt = c_parser_omp_structured_block (parser, NULL);
17998   substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE);
17999   SET_EXPR_LOCATION (substmt, loc);
18000   add_stmt (substmt);
18001 
18002   loc = c_parser_peek_token (parser)->location;
18003   if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SCAN)
18004     {
18005       enum omp_clause_code clause = OMP_CLAUSE_ERROR;
18006 
18007       c_parser_consume_pragma (parser);
18008 
18009       if (c_parser_next_token_is (parser, CPP_NAME))
18010 	{
18011 	  const char *p
18012 	    = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18013 	  if (strcmp (p, "inclusive") == 0)
18014 	    clause = OMP_CLAUSE_INCLUSIVE;
18015 	  else if (strcmp (p, "exclusive") == 0)
18016 	    clause = OMP_CLAUSE_EXCLUSIVE;
18017 	}
18018       if (clause != OMP_CLAUSE_ERROR)
18019 	{
18020 	  c_parser_consume_token (parser);
18021 	  clauses = c_parser_omp_var_list_parens (parser, clause, NULL_TREE);
18022 	}
18023       else
18024 	c_parser_error (parser, "expected %<inclusive%> or "
18025 				"%<exclusive%> clause");
18026       c_parser_skip_to_pragma_eol (parser);
18027     }
18028   else
18029     error ("expected %<#pragma omp scan%>");
18030 
18031   clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
18032   substmt = c_parser_omp_structured_block (parser, NULL);
18033   substmt = build2 (OMP_SCAN, void_type_node, substmt, clauses);
18034   SET_EXPR_LOCATION (substmt, loc);
18035   add_stmt (substmt);
18036 
18037   c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
18038 			     "expected %<}%>");
18039 }
18040 
18041 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
18042    The real trick here is to determine the loop control variable early
18043    so that we can push a new decl if necessary to make it private.
18044    LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
18045    respectively.  */
18046 
18047 static tree
c_parser_omp_for_loop(location_t loc,c_parser * parser,enum tree_code code,tree clauses,tree * cclauses,bool * if_p)18048 c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
18049 		       tree clauses, tree *cclauses, bool *if_p)
18050 {
18051   tree decl, cond, incr, save_break, save_cont, body, init, stmt, cl;
18052   tree declv, condv, incrv, initv, ret = NULL_TREE;
18053   tree pre_body = NULL_TREE, this_pre_body;
18054   tree ordered_cl = NULL_TREE;
18055   bool fail = false, open_brace_parsed = false;
18056   int i, collapse = 1, ordered = 0, count, nbraces = 0;
18057   location_t for_loc;
18058   bool tiling = false;
18059   bool inscan = false;
18060   vec<tree, va_gc> *for_block = make_tree_vector ();
18061 
18062   for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
18063     if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
18064       collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl));
18065     else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_TILE)
18066       {
18067 	tiling = true;
18068 	collapse = list_length (OMP_CLAUSE_TILE_LIST (cl));
18069       }
18070     else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED
18071 	     && OMP_CLAUSE_ORDERED_EXPR (cl))
18072       {
18073 	ordered_cl = cl;
18074 	ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
18075       }
18076     else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_REDUCTION
18077 	     && OMP_CLAUSE_REDUCTION_INSCAN (cl)
18078 	     && (code == OMP_SIMD || code == OMP_FOR))
18079       inscan = true;
18080 
18081   if (ordered && ordered < collapse)
18082     {
18083       error_at (OMP_CLAUSE_LOCATION (ordered_cl),
18084 		"%<ordered%> clause parameter is less than %<collapse%>");
18085       OMP_CLAUSE_ORDERED_EXPR (ordered_cl)
18086 	= build_int_cst (NULL_TREE, collapse);
18087       ordered = collapse;
18088     }
18089   if (ordered)
18090     {
18091       for (tree *pc = &clauses; *pc; )
18092 	if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LINEAR)
18093 	  {
18094 	    error_at (OMP_CLAUSE_LOCATION (*pc),
18095 		      "%<linear%> clause may not be specified together "
18096 		      "with %<ordered%> clause with a parameter");
18097 	    *pc = OMP_CLAUSE_CHAIN (*pc);
18098 	  }
18099 	else
18100 	  pc = &OMP_CLAUSE_CHAIN (*pc);
18101     }
18102 
18103   gcc_assert (tiling || (collapse >= 1 && ordered >= 0));
18104   count = ordered ? ordered : collapse;
18105 
18106   declv = make_tree_vec (count);
18107   initv = make_tree_vec (count);
18108   condv = make_tree_vec (count);
18109   incrv = make_tree_vec (count);
18110 
18111   if (!c_parser_next_token_is_keyword (parser, RID_FOR))
18112     {
18113       c_parser_error (parser, "for statement expected");
18114       return NULL;
18115     }
18116   for_loc = c_parser_peek_token (parser)->location;
18117   c_parser_consume_token (parser);
18118 
18119   for (i = 0; i < count; i++)
18120     {
18121       int bracecount = 0;
18122 
18123       matching_parens parens;
18124       if (!parens.require_open (parser))
18125 	goto pop_scopes;
18126 
18127       /* Parse the initialization declaration or expression.  */
18128       if (c_parser_next_tokens_start_declaration (parser))
18129 	{
18130 	  if (i > 0)
18131 	    vec_safe_push (for_block, c_begin_compound_stmt (true));
18132 	  this_pre_body = push_stmt_list ();
18133 	  c_parser_declaration_or_fndef (parser, true, true, true, true, true,
18134 					 NULL, vNULL);
18135 	  if (this_pre_body)
18136 	    {
18137 	      this_pre_body = pop_stmt_list (this_pre_body);
18138 	      if (pre_body)
18139 		{
18140 		  tree t = pre_body;
18141 		  pre_body = push_stmt_list ();
18142 		  add_stmt (t);
18143 		  add_stmt (this_pre_body);
18144 		  pre_body = pop_stmt_list (pre_body);
18145 		}
18146 	      else
18147 		pre_body = this_pre_body;
18148 	    }
18149 	  decl = check_for_loop_decls (for_loc, flag_isoc99);
18150 	  if (decl == NULL)
18151 	    goto error_init;
18152 	  if (DECL_INITIAL (decl) == error_mark_node)
18153 	    decl = error_mark_node;
18154 	  init = decl;
18155 	}
18156       else if (c_parser_next_token_is (parser, CPP_NAME)
18157 	       && c_parser_peek_2nd_token (parser)->type == CPP_EQ)
18158 	{
18159 	  struct c_expr decl_exp;
18160 	  struct c_expr init_exp;
18161 	  location_t init_loc;
18162 
18163 	  decl_exp = c_parser_postfix_expression (parser);
18164 	  decl = decl_exp.value;
18165 
18166 	  c_parser_require (parser, CPP_EQ, "expected %<=%>");
18167 
18168 	  init_loc = c_parser_peek_token (parser)->location;
18169 	  init_exp = c_parser_expr_no_commas (parser, NULL);
18170 	  init_exp = default_function_array_read_conversion (init_loc,
18171 							     init_exp);
18172 	  init = build_modify_expr (init_loc, decl, decl_exp.original_type,
18173 				    NOP_EXPR, init_loc, init_exp.value,
18174 				    init_exp.original_type);
18175 	  init = c_process_expr_stmt (init_loc, init);
18176 
18177 	  c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
18178 	}
18179       else
18180 	{
18181 	error_init:
18182 	  c_parser_error (parser,
18183 			  "expected iteration declaration or initialization");
18184 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
18185 				     "expected %<)%>");
18186 	  fail = true;
18187 	  goto parse_next;
18188 	}
18189 
18190       /* Parse the loop condition.  */
18191       cond = NULL_TREE;
18192       if (c_parser_next_token_is_not (parser, CPP_SEMICOLON))
18193 	{
18194 	  location_t cond_loc = c_parser_peek_token (parser)->location;
18195 	  struct c_expr cond_expr
18196 	    = c_parser_binary_expression (parser, NULL, NULL_TREE);
18197 
18198 	  cond = cond_expr.value;
18199 	  cond = c_objc_common_truthvalue_conversion (cond_loc, cond);
18200 	  if (COMPARISON_CLASS_P (cond))
18201 	    {
18202 	      tree op0 = TREE_OPERAND (cond, 0), op1 = TREE_OPERAND (cond, 1);
18203 	      op0 = c_fully_fold (op0, false, NULL);
18204 	      op1 = c_fully_fold (op1, false, NULL);
18205 	      TREE_OPERAND (cond, 0) = op0;
18206 	      TREE_OPERAND (cond, 1) = op1;
18207 	    }
18208 	  switch (cond_expr.original_code)
18209 	    {
18210 	    case GT_EXPR:
18211 	    case GE_EXPR:
18212 	    case LT_EXPR:
18213 	    case LE_EXPR:
18214 	      break;
18215 	    case NE_EXPR:
18216 	      if (code != OACC_LOOP)
18217 		break;
18218 	      /* FALLTHRU.  */
18219 	    default:
18220 	      /* Can't be cond = error_mark_node, because we want to preserve
18221 		 the location until c_finish_omp_for.  */
18222 	      cond = build1 (NOP_EXPR, boolean_type_node, error_mark_node);
18223 	      break;
18224 	    }
18225 	  protected_set_expr_location (cond, cond_loc);
18226 	}
18227       c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
18228 
18229       /* Parse the increment expression.  */
18230       incr = NULL_TREE;
18231       if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
18232 	{
18233 	  location_t incr_loc = c_parser_peek_token (parser)->location;
18234 
18235 	  incr = c_process_expr_stmt (incr_loc,
18236 				      c_parser_expression (parser).value);
18237 	}
18238       parens.skip_until_found_close (parser);
18239 
18240       if (decl == NULL || decl == error_mark_node || init == error_mark_node)
18241 	fail = true;
18242       else
18243 	{
18244 	  TREE_VEC_ELT (declv, i) = decl;
18245 	  TREE_VEC_ELT (initv, i) = init;
18246 	  TREE_VEC_ELT (condv, i) = cond;
18247 	  TREE_VEC_ELT (incrv, i) = incr;
18248 	}
18249 
18250     parse_next:
18251       if (i == count - 1)
18252 	break;
18253 
18254       /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
18255 	 in between the collapsed for loops to be still considered perfectly
18256 	 nested.  Hopefully the final version clarifies this.
18257 	 For now handle (multiple) {'s and empty statements.  */
18258       do
18259 	{
18260 	  if (c_parser_next_token_is_keyword (parser, RID_FOR))
18261 	    {
18262 	      c_parser_consume_token (parser);
18263 	      break;
18264 	    }
18265 	  else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
18266 	    {
18267 	      c_parser_consume_token (parser);
18268 	      bracecount++;
18269 	    }
18270 	  else if (bracecount
18271 		   && c_parser_next_token_is (parser, CPP_SEMICOLON))
18272 	    c_parser_consume_token (parser);
18273 	  else
18274 	    {
18275 	      c_parser_error (parser, "not enough perfectly nested loops");
18276 	      if (bracecount)
18277 		{
18278 		  open_brace_parsed = true;
18279 		  bracecount--;
18280 		}
18281 	      fail = true;
18282 	      count = 0;
18283 	      break;
18284 	    }
18285 	}
18286       while (1);
18287 
18288       nbraces += bracecount;
18289     }
18290 
18291   if (nbraces)
18292     if_p = NULL;
18293 
18294   save_break = c_break_label;
18295   c_break_label = size_one_node;
18296   save_cont = c_cont_label;
18297   c_cont_label = NULL_TREE;
18298   body = push_stmt_list ();
18299 
18300   if (inscan)
18301     c_parser_omp_scan_loop_body (parser, open_brace_parsed);
18302   else if (open_brace_parsed)
18303     {
18304       location_t here = c_parser_peek_token (parser)->location;
18305       stmt = c_begin_compound_stmt (true);
18306       c_parser_compound_statement_nostart (parser);
18307       add_stmt (c_end_compound_stmt (here, stmt, true));
18308     }
18309   else
18310     add_stmt (c_parser_c99_block_statement (parser, if_p));
18311   if (c_cont_label)
18312     {
18313       tree t = build1 (LABEL_EXPR, void_type_node, c_cont_label);
18314       SET_EXPR_LOCATION (t, loc);
18315       add_stmt (t);
18316     }
18317 
18318   body = pop_stmt_list (body);
18319   c_break_label = save_break;
18320   c_cont_label = save_cont;
18321 
18322   while (nbraces)
18323     {
18324       if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18325 	{
18326 	  c_parser_consume_token (parser);
18327 	  nbraces--;
18328 	}
18329       else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
18330 	c_parser_consume_token (parser);
18331       else
18332 	{
18333 	  c_parser_error (parser, "collapsed loops not perfectly nested");
18334 	  while (nbraces)
18335 	    {
18336 	      location_t here = c_parser_peek_token (parser)->location;
18337 	      stmt = c_begin_compound_stmt (true);
18338 	      add_stmt (body);
18339 	      c_parser_compound_statement_nostart (parser);
18340 	      body = c_end_compound_stmt (here, stmt, true);
18341 	      nbraces--;
18342 	    }
18343 	  goto pop_scopes;
18344 	}
18345     }
18346 
18347   /* Only bother calling c_finish_omp_for if we haven't already generated
18348      an error from the initialization parsing.  */
18349   if (!fail)
18350     {
18351       stmt = c_finish_omp_for (loc, code, declv, NULL, initv, condv,
18352 			       incrv, body, pre_body, true);
18353 
18354       /* Check for iterators appearing in lb, b or incr expressions.  */
18355       if (stmt && !c_omp_check_loop_iv (stmt, declv, NULL))
18356 	stmt = NULL_TREE;
18357 
18358       if (stmt)
18359 	{
18360 	  add_stmt (stmt);
18361 
18362 	  if (cclauses != NULL
18363 	      && cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL)
18364 	    {
18365 	      tree *c;
18366 	      for (c = &cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; *c ; )
18367 		if (OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_FIRSTPRIVATE
18368 		    && OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_LASTPRIVATE)
18369 		  c = &OMP_CLAUSE_CHAIN (*c);
18370 		else
18371 		  {
18372 		    for (i = 0; i < count; i++)
18373 		      if (TREE_VEC_ELT (declv, i) == OMP_CLAUSE_DECL (*c))
18374 			break;
18375 		    if (i == count)
18376 		      c = &OMP_CLAUSE_CHAIN (*c);
18377 		    else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE)
18378 		      {
18379 			error_at (loc,
18380 				  "iteration variable %qD should not be firstprivate",
18381 				  OMP_CLAUSE_DECL (*c));
18382 			*c = OMP_CLAUSE_CHAIN (*c);
18383 		      }
18384 		    else
18385 		      {
18386 			/* Move lastprivate (decl) clause to OMP_FOR_CLAUSES.  */
18387 			tree l = *c;
18388 			*c = OMP_CLAUSE_CHAIN (*c);
18389 			if (code == OMP_SIMD)
18390 			  {
18391 			    OMP_CLAUSE_CHAIN (l)
18392 			      = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
18393 			    cclauses[C_OMP_CLAUSE_SPLIT_FOR] = l;
18394 			  }
18395 			else
18396 			  {
18397 			    OMP_CLAUSE_CHAIN (l) = clauses;
18398 			    clauses = l;
18399 			  }
18400 		      }
18401 		  }
18402 	    }
18403 	  OMP_FOR_CLAUSES (stmt) = clauses;
18404 	}
18405       ret = stmt;
18406     }
18407 pop_scopes:
18408   while (!for_block->is_empty ())
18409     {
18410       /* FIXME diagnostics: LOC below should be the actual location of
18411 	 this particular for block.  We need to build a list of
18412 	 locations to go along with FOR_BLOCK.  */
18413       stmt = c_end_compound_stmt (loc, for_block->pop (), true);
18414       add_stmt (stmt);
18415     }
18416   release_tree_vector (for_block);
18417   return ret;
18418 }
18419 
18420 /* Helper function for OpenMP parsing, split clauses and call
18421    finish_omp_clauses on each of the set of clauses afterwards.  */
18422 
18423 static void
omp_split_clauses(location_t loc,enum tree_code code,omp_clause_mask mask,tree clauses,tree * cclauses)18424 omp_split_clauses (location_t loc, enum tree_code code,
18425 		   omp_clause_mask mask, tree clauses, tree *cclauses)
18426 {
18427   int i;
18428   c_omp_split_clauses (loc, code, mask, clauses, cclauses);
18429   for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
18430     if (cclauses[i])
18431       cclauses[i] = c_finish_omp_clauses (cclauses[i], C_ORT_OMP);
18432 }
18433 
18434 /* OpenMP 5.0:
18435    #pragma omp loop loop-clause[optseq] new-line
18436      for-loop
18437 
18438    LOC is the location of the #pragma token.
18439 */
18440 
18441 #define OMP_LOOP_CLAUSE_MASK					\
18442 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
18443 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)	\
18444 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)	\
18445 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)	\
18446 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND)		\
18447 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
18448 
18449 static tree
c_parser_omp_loop(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)18450 c_parser_omp_loop (location_t loc, c_parser *parser,
18451 		   char *p_name, omp_clause_mask mask, tree *cclauses,
18452 		   bool *if_p)
18453 {
18454   tree block, clauses, ret;
18455 
18456   strcat (p_name, " loop");
18457   mask |= OMP_LOOP_CLAUSE_MASK;
18458 
18459   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
18460   if (cclauses)
18461     {
18462       omp_split_clauses (loc, OMP_LOOP, mask, clauses, cclauses);
18463       clauses = cclauses[C_OMP_CLAUSE_SPLIT_LOOP];
18464     }
18465 
18466   block = c_begin_compound_stmt (true);
18467   ret = c_parser_omp_for_loop (loc, parser, OMP_LOOP, clauses, cclauses, if_p);
18468   block = c_end_compound_stmt (loc, block, true);
18469   add_stmt (block);
18470 
18471   return ret;
18472 }
18473 
18474 /* OpenMP 4.0:
18475    #pragma omp simd simd-clause[optseq] new-line
18476      for-loop
18477 
18478    LOC is the location of the #pragma token.
18479 */
18480 
18481 #define OMP_SIMD_CLAUSE_MASK					\
18482 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN)	\
18483 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN)	\
18484 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR)	\
18485 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED)	\
18486 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
18487 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)	\
18488 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)	\
18489 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)	\
18490 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
18491 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL)	\
18492 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
18493 
18494 static tree
c_parser_omp_simd(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)18495 c_parser_omp_simd (location_t loc, c_parser *parser,
18496 		   char *p_name, omp_clause_mask mask, tree *cclauses,
18497 		   bool *if_p)
18498 {
18499   tree block, clauses, ret;
18500 
18501   strcat (p_name, " simd");
18502   mask |= OMP_SIMD_CLAUSE_MASK;
18503 
18504   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
18505   if (cclauses)
18506     {
18507       omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses);
18508       clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
18509       tree c = omp_find_clause (cclauses[C_OMP_CLAUSE_SPLIT_FOR],
18510 				OMP_CLAUSE_ORDERED);
18511       if (c && OMP_CLAUSE_ORDERED_EXPR (c))
18512 	{
18513 	  error_at (OMP_CLAUSE_LOCATION (c),
18514 		    "%<ordered%> clause with parameter may not be specified "
18515 		    "on %qs construct", p_name);
18516 	  OMP_CLAUSE_ORDERED_EXPR (c) = NULL_TREE;
18517 	}
18518     }
18519 
18520   block = c_begin_compound_stmt (true);
18521   ret = c_parser_omp_for_loop (loc, parser, OMP_SIMD, clauses, cclauses, if_p);
18522   block = c_end_compound_stmt (loc, block, true);
18523   add_stmt (block);
18524 
18525   return ret;
18526 }
18527 
18528 /* OpenMP 2.5:
18529    #pragma omp for for-clause[optseq] new-line
18530      for-loop
18531 
18532    OpenMP 4.0:
18533    #pragma omp for simd for-simd-clause[optseq] new-line
18534      for-loop
18535 
18536    LOC is the location of the #pragma token.
18537 */
18538 
18539 #define OMP_FOR_CLAUSE_MASK					\
18540 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
18541 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
18542 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)	\
18543 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR)	\
18544 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)	\
18545 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED)	\
18546 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)	\
18547 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)	\
18548 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT)	\
18549 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
18550 
18551 static tree
c_parser_omp_for(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)18552 c_parser_omp_for (location_t loc, c_parser *parser,
18553 		  char *p_name, omp_clause_mask mask, tree *cclauses,
18554 		  bool *if_p)
18555 {
18556   tree block, clauses, ret;
18557 
18558   strcat (p_name, " for");
18559   mask |= OMP_FOR_CLAUSE_MASK;
18560   /* parallel for{, simd} disallows nowait clause, but for
18561      target {teams distribute ,}parallel for{, simd} it should be accepted.  */
18562   if (cclauses && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0)
18563     mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
18564   /* Composite distribute parallel for{, simd} disallows ordered clause.  */
18565   if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
18566     mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED);
18567 
18568   if (c_parser_next_token_is (parser, CPP_NAME))
18569     {
18570       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18571 
18572       if (strcmp (p, "simd") == 0)
18573 	{
18574 	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18575 	  if (cclauses == NULL)
18576 	    cclauses = cclauses_buf;
18577 
18578 	  c_parser_consume_token (parser);
18579 	  if (!flag_openmp)  /* flag_openmp_simd  */
18580 	    return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
18581 				      if_p);
18582 	  block = c_begin_compound_stmt (true);
18583 	  ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
18584 	  block = c_end_compound_stmt (loc, block, true);
18585 	  if (ret == NULL_TREE)
18586 	    return ret;
18587 	  ret = make_node (OMP_FOR);
18588 	  TREE_TYPE (ret) = void_type_node;
18589 	  OMP_FOR_BODY (ret) = block;
18590 	  OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
18591 	  SET_EXPR_LOCATION (ret, loc);
18592 	  add_stmt (ret);
18593 	  return ret;
18594 	}
18595     }
18596   if (!flag_openmp)  /* flag_openmp_simd  */
18597     {
18598       c_parser_skip_to_pragma_eol (parser, false);
18599       return NULL_TREE;
18600     }
18601 
18602   /* Composite distribute parallel for disallows linear clause.  */
18603   if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
18604     mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR);
18605 
18606   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
18607   if (cclauses)
18608     {
18609       omp_split_clauses (loc, OMP_FOR, mask, clauses, cclauses);
18610       clauses = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
18611     }
18612 
18613   block = c_begin_compound_stmt (true);
18614   ret = c_parser_omp_for_loop (loc, parser, OMP_FOR, clauses, cclauses, if_p);
18615   block = c_end_compound_stmt (loc, block, true);
18616   add_stmt (block);
18617 
18618   return ret;
18619 }
18620 
18621 static tree c_parser_omp_taskloop (location_t, c_parser *, char *,
18622 				   omp_clause_mask, tree *, bool *);
18623 
18624 /* OpenMP 2.5:
18625    # pragma omp master new-line
18626      structured-block
18627 
18628    LOC is the location of the #pragma token.
18629 */
18630 
18631 static tree
c_parser_omp_master(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)18632 c_parser_omp_master (location_t loc, c_parser *parser,
18633 		     char *p_name, omp_clause_mask mask, tree *cclauses,
18634 		     bool *if_p)
18635 {
18636   tree block, clauses, ret;
18637 
18638   strcat (p_name, " master");
18639 
18640   if (c_parser_next_token_is (parser, CPP_NAME))
18641     {
18642       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18643 
18644       if (strcmp (p, "taskloop") == 0)
18645 	{
18646 	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18647 	  if (cclauses == NULL)
18648 	    cclauses = cclauses_buf;
18649 
18650 	  c_parser_consume_token (parser);
18651 	  if (!flag_openmp)  /* flag_openmp_simd  */
18652 	    return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
18653 					  if_p);
18654 	  block = c_begin_compound_stmt (true);
18655 	  ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
18656 				       if_p);
18657 	  block = c_end_compound_stmt (loc, block, true);
18658 	  if (ret == NULL_TREE)
18659 	    return ret;
18660 	  ret = c_finish_omp_master (loc, block);
18661 	  return ret;
18662 	}
18663     }
18664   if (!flag_openmp)  /* flag_openmp_simd  */
18665     {
18666       c_parser_skip_to_pragma_eol (parser, false);
18667       return NULL_TREE;
18668     }
18669 
18670   if (cclauses)
18671     {
18672       clauses = c_parser_omp_all_clauses (parser, mask, p_name, false);
18673       omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses);
18674     }
18675   else
18676     c_parser_skip_to_pragma_eol (parser);
18677 
18678   return c_finish_omp_master (loc, c_parser_omp_structured_block (parser,
18679 								  if_p));
18680 }
18681 
18682 /* OpenMP 2.5:
18683    # pragma omp ordered new-line
18684      structured-block
18685 
18686    OpenMP 4.5:
18687    # pragma omp ordered ordered-clauses new-line
18688      structured-block
18689 
18690    # pragma omp ordered depend-clauses new-line  */
18691 
18692 #define OMP_ORDERED_CLAUSE_MASK					\
18693 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS)	\
18694 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
18695 
18696 #define OMP_ORDERED_DEPEND_CLAUSE_MASK				\
18697 	(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
18698 
18699 static bool
c_parser_omp_ordered(c_parser * parser,enum pragma_context context,bool * if_p)18700 c_parser_omp_ordered (c_parser *parser, enum pragma_context context,
18701 		      bool *if_p)
18702 {
18703   location_t loc = c_parser_peek_token (parser)->location;
18704   c_parser_consume_pragma (parser);
18705 
18706   if (context != pragma_stmt && context != pragma_compound)
18707     {
18708       c_parser_error (parser, "expected declaration specifiers");
18709       c_parser_skip_to_pragma_eol (parser, false);
18710       return false;
18711     }
18712 
18713   if (c_parser_next_token_is (parser, CPP_NAME))
18714     {
18715       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18716 
18717       if (!strcmp ("depend", p))
18718 	{
18719 	  if (!flag_openmp)	/* flag_openmp_simd  */
18720 	    {
18721 	      c_parser_skip_to_pragma_eol (parser, false);
18722 	      return false;
18723 	    }
18724 	  if (context == pragma_stmt)
18725 	    {
18726 	      error_at (loc,
18727 			"%<#pragma omp ordered%> with %<depend%> clause may "
18728 			"only be used in compound statements");
18729 	      c_parser_skip_to_pragma_eol (parser, false);
18730 	      return false;
18731 	    }
18732 
18733 	  tree clauses
18734 	    = c_parser_omp_all_clauses (parser,
18735 					OMP_ORDERED_DEPEND_CLAUSE_MASK,
18736 					"#pragma omp ordered");
18737 	  c_finish_omp_ordered (loc, clauses, NULL_TREE);
18738 	  return false;
18739 	}
18740     }
18741 
18742   tree clauses = c_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK,
18743 					   "#pragma omp ordered");
18744 
18745   if (!flag_openmp	/* flag_openmp_simd  */
18746       && omp_find_clause (clauses, OMP_CLAUSE_SIMD) == NULL_TREE)
18747     return false;
18748 
18749   c_finish_omp_ordered (loc, clauses,
18750 			c_parser_omp_structured_block (parser, if_p));
18751   return true;
18752 }
18753 
18754 /* OpenMP 2.5:
18755 
18756    section-scope:
18757      { section-sequence }
18758 
18759    section-sequence:
18760      section-directive[opt] structured-block
18761      section-sequence section-directive structured-block
18762 
18763     SECTIONS_LOC is the location of the #pragma omp sections.  */
18764 
18765 static tree
c_parser_omp_sections_scope(location_t sections_loc,c_parser * parser)18766 c_parser_omp_sections_scope (location_t sections_loc, c_parser *parser)
18767 {
18768   tree stmt, substmt;
18769   bool error_suppress = false;
18770   location_t loc;
18771 
18772   loc = c_parser_peek_token (parser)->location;
18773   if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
18774     {
18775       /* Avoid skipping until the end of the block.  */
18776       parser->error = false;
18777       return NULL_TREE;
18778     }
18779 
18780   stmt = push_stmt_list ();
18781 
18782   if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION)
18783     {
18784       substmt = c_parser_omp_structured_block (parser, NULL);
18785       substmt = build1 (OMP_SECTION, void_type_node, substmt);
18786       SET_EXPR_LOCATION (substmt, loc);
18787       add_stmt (substmt);
18788     }
18789 
18790   while (1)
18791     {
18792       if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18793 	break;
18794       if (c_parser_next_token_is (parser, CPP_EOF))
18795 	break;
18796 
18797       loc = c_parser_peek_token (parser)->location;
18798       if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION)
18799 	{
18800 	  c_parser_consume_pragma (parser);
18801 	  c_parser_skip_to_pragma_eol (parser);
18802 	  error_suppress = false;
18803 	}
18804       else if (!error_suppress)
18805 	{
18806 	  error_at (loc, "expected %<#pragma omp section%> or %<}%>");
18807 	  error_suppress = true;
18808 	}
18809 
18810       substmt = c_parser_omp_structured_block (parser, NULL);
18811       substmt = build1 (OMP_SECTION, void_type_node, substmt);
18812       SET_EXPR_LOCATION (substmt, loc);
18813       add_stmt (substmt);
18814     }
18815   c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
18816 			     "expected %<#pragma omp section%> or %<}%>");
18817 
18818   substmt = pop_stmt_list (stmt);
18819 
18820   stmt = make_node (OMP_SECTIONS);
18821   SET_EXPR_LOCATION (stmt, sections_loc);
18822   TREE_TYPE (stmt) = void_type_node;
18823   OMP_SECTIONS_BODY (stmt) = substmt;
18824 
18825   return add_stmt (stmt);
18826 }
18827 
18828 /* OpenMP 2.5:
18829    # pragma omp sections sections-clause[optseq] newline
18830      sections-scope
18831 
18832    LOC is the location of the #pragma token.
18833 */
18834 
18835 #define OMP_SECTIONS_CLAUSE_MASK				\
18836 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
18837 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
18838 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)	\
18839 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)	\
18840 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
18841 
18842 static tree
c_parser_omp_sections(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses)18843 c_parser_omp_sections (location_t loc, c_parser *parser,
18844 		       char *p_name, omp_clause_mask mask, tree *cclauses)
18845 {
18846   tree block, clauses, ret;
18847 
18848   strcat (p_name, " sections");
18849   mask |= OMP_SECTIONS_CLAUSE_MASK;
18850   if (cclauses)
18851     mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
18852 
18853   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
18854   if (cclauses)
18855     {
18856       omp_split_clauses (loc, OMP_SECTIONS, mask, clauses, cclauses);
18857       clauses = cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS];
18858     }
18859 
18860   block = c_begin_compound_stmt (true);
18861   ret = c_parser_omp_sections_scope (loc, parser);
18862   if (ret)
18863     OMP_SECTIONS_CLAUSES (ret) = clauses;
18864   block = c_end_compound_stmt (loc, block, true);
18865   add_stmt (block);
18866 
18867   return ret;
18868 }
18869 
18870 /* OpenMP 2.5:
18871    # pragma omp parallel parallel-clause[optseq] new-line
18872      structured-block
18873    # pragma omp parallel for parallel-for-clause[optseq] new-line
18874      structured-block
18875    # pragma omp parallel sections parallel-sections-clause[optseq] new-line
18876      structured-block
18877 
18878    OpenMP 4.0:
18879    # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
18880      structured-block
18881 
18882    LOC is the location of the #pragma token.
18883 */
18884 
18885 #define OMP_PARALLEL_CLAUSE_MASK				\
18886 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
18887 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
18888 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
18889 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT)	\
18890 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED)	\
18891 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN)	\
18892 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)	\
18893 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)	\
18894 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
18895 
18896 static tree
c_parser_omp_parallel(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)18897 c_parser_omp_parallel (location_t loc, c_parser *parser,
18898 		       char *p_name, omp_clause_mask mask, tree *cclauses,
18899 		       bool *if_p)
18900 {
18901   tree stmt, clauses, block;
18902 
18903   strcat (p_name, " parallel");
18904   mask |= OMP_PARALLEL_CLAUSE_MASK;
18905   /* #pragma omp target parallel{, for, for simd} disallow copyin clause.  */
18906   if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0
18907       && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
18908     mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN);
18909 
18910   if (c_parser_next_token_is_keyword (parser, RID_FOR))
18911     {
18912       tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18913       if (cclauses == NULL)
18914 	cclauses = cclauses_buf;
18915 
18916       c_parser_consume_token (parser);
18917       if (!flag_openmp)  /* flag_openmp_simd  */
18918 	return c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
18919       block = c_begin_omp_parallel ();
18920       tree ret = c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
18921       stmt
18922 	= c_finish_omp_parallel (loc, cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
18923 				 block);
18924       if (ret == NULL_TREE)
18925 	return ret;
18926       OMP_PARALLEL_COMBINED (stmt) = 1;
18927       return stmt;
18928     }
18929   /* When combined with distribute, parallel has to be followed by for.
18930      #pragma omp target parallel is allowed though.  */
18931   else if (cclauses
18932 	   && (mask & (OMP_CLAUSE_MASK_1
18933 		       << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
18934     {
18935       error_at (loc, "expected %<for%> after %qs", p_name);
18936       c_parser_skip_to_pragma_eol (parser);
18937       return NULL_TREE;
18938     }
18939   else if (c_parser_next_token_is (parser, CPP_NAME))
18940     {
18941       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18942       if (cclauses == NULL && strcmp (p, "master") == 0)
18943 	{
18944 	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18945 	  cclauses = cclauses_buf;
18946 
18947 	  c_parser_consume_token (parser);
18948 	  if (!flag_openmp)  /* flag_openmp_simd  */
18949 	    return c_parser_omp_master (loc, parser, p_name, mask, cclauses,
18950 					if_p);
18951 	  block = c_begin_omp_parallel ();
18952 	  tree ret = c_parser_omp_master (loc, parser, p_name, mask, cclauses,
18953 					  if_p);
18954 	  stmt = c_finish_omp_parallel (loc,
18955 					cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
18956 					block);
18957 	  if (ret == NULL)
18958 	    return ret;
18959 	  OMP_PARALLEL_COMBINED (stmt) = 1;
18960 	  return stmt;
18961 	}
18962       else if (strcmp (p, "loop") == 0)
18963 	{
18964 	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18965 	  if (cclauses == NULL)
18966 	    cclauses = cclauses_buf;
18967 
18968 	  c_parser_consume_token (parser);
18969 	  if (!flag_openmp)  /* flag_openmp_simd  */
18970 	    return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
18971 				      if_p);
18972 	  block = c_begin_omp_parallel ();
18973 	  tree ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
18974 					if_p);
18975 	  stmt
18976 	    = c_finish_omp_parallel (loc,
18977 				     cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
18978 				     block);
18979 	  if (ret == NULL_TREE)
18980 	    return ret;
18981 	  OMP_PARALLEL_COMBINED (stmt) = 1;
18982 	  return stmt;
18983 	}
18984       else if (!flag_openmp)  /* flag_openmp_simd  */
18985 	{
18986 	  c_parser_skip_to_pragma_eol (parser, false);
18987 	  return NULL_TREE;
18988 	}
18989       else if (cclauses == NULL && strcmp (p, "sections") == 0)
18990 	{
18991 	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18992 	  cclauses = cclauses_buf;
18993 
18994 	  c_parser_consume_token (parser);
18995 	  block = c_begin_omp_parallel ();
18996 	  c_parser_omp_sections (loc, parser, p_name, mask, cclauses);
18997 	  stmt = c_finish_omp_parallel (loc,
18998 					cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
18999 					block);
19000 	  OMP_PARALLEL_COMBINED (stmt) = 1;
19001 	  return stmt;
19002 	}
19003     }
19004   else if (!flag_openmp)  /* flag_openmp_simd  */
19005     {
19006       c_parser_skip_to_pragma_eol (parser, false);
19007       return NULL_TREE;
19008     }
19009 
19010   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19011   if (cclauses)
19012     {
19013       omp_split_clauses (loc, OMP_PARALLEL, mask, clauses, cclauses);
19014       clauses = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
19015     }
19016 
19017   block = c_begin_omp_parallel ();
19018   c_parser_statement (parser, if_p);
19019   stmt = c_finish_omp_parallel (loc, clauses, block);
19020 
19021   return stmt;
19022 }
19023 
19024 /* OpenMP 2.5:
19025    # pragma omp single single-clause[optseq] new-line
19026      structured-block
19027 
19028    LOC is the location of the #pragma.
19029 */
19030 
19031 #define OMP_SINGLE_CLAUSE_MASK					\
19032 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
19033 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
19034 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE)	\
19035 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19036 
19037 static tree
c_parser_omp_single(location_t loc,c_parser * parser,bool * if_p)19038 c_parser_omp_single (location_t loc, c_parser *parser, bool *if_p)
19039 {
19040   tree stmt = make_node (OMP_SINGLE);
19041   SET_EXPR_LOCATION (stmt, loc);
19042   TREE_TYPE (stmt) = void_type_node;
19043 
19044   OMP_SINGLE_CLAUSES (stmt)
19045     = c_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK,
19046 				"#pragma omp single");
19047   OMP_SINGLE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
19048 
19049   return add_stmt (stmt);
19050 }
19051 
19052 /* OpenMP 3.0:
19053    # pragma omp task task-clause[optseq] new-line
19054 
19055    LOC is the location of the #pragma.
19056 */
19057 
19058 #define OMP_TASK_CLAUSE_MASK					\
19059 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
19060 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED)	\
19061 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT)	\
19062 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
19063 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
19064 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED)	\
19065 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL)	\
19066 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE)	\
19067 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)	\
19068 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY)	\
19069 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
19070 
19071 static tree
c_parser_omp_task(location_t loc,c_parser * parser,bool * if_p)19072 c_parser_omp_task (location_t loc, c_parser *parser, bool *if_p)
19073 {
19074   tree clauses, block;
19075 
19076   clauses = c_parser_omp_all_clauses (parser, OMP_TASK_CLAUSE_MASK,
19077 				      "#pragma omp task");
19078 
19079   block = c_begin_omp_task ();
19080   c_parser_statement (parser, if_p);
19081   return c_finish_omp_task (loc, clauses, block);
19082 }
19083 
19084 /* OpenMP 3.0:
19085    # pragma omp taskwait new-line
19086 
19087    OpenMP 5.0:
19088    # pragma omp taskwait taskwait-clause[optseq] new-line
19089 */
19090 
19091 #define OMP_TASKWAIT_CLAUSE_MASK					\
19092 	(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
19093 
19094 static void
c_parser_omp_taskwait(c_parser * parser)19095 c_parser_omp_taskwait (c_parser *parser)
19096 {
19097   location_t loc = c_parser_peek_token (parser)->location;
19098   c_parser_consume_pragma (parser);
19099 
19100   tree clauses
19101     = c_parser_omp_all_clauses (parser, OMP_TASKWAIT_CLAUSE_MASK,
19102 				"#pragma omp taskwait");
19103 
19104   if (clauses)
19105     {
19106       tree stmt = make_node (OMP_TASK);
19107       TREE_TYPE (stmt) = void_node;
19108       OMP_TASK_CLAUSES (stmt) = clauses;
19109       OMP_TASK_BODY (stmt) = NULL_TREE;
19110       SET_EXPR_LOCATION (stmt, loc);
19111       add_stmt (stmt);
19112     }
19113   else
19114     c_finish_omp_taskwait (loc);
19115 }
19116 
19117 /* OpenMP 3.1:
19118    # pragma omp taskyield new-line
19119 */
19120 
19121 static void
c_parser_omp_taskyield(c_parser * parser)19122 c_parser_omp_taskyield (c_parser *parser)
19123 {
19124   location_t loc = c_parser_peek_token (parser)->location;
19125   c_parser_consume_pragma (parser);
19126   c_parser_skip_to_pragma_eol (parser);
19127 
19128   c_finish_omp_taskyield (loc);
19129 }
19130 
19131 /* OpenMP 4.0:
19132    # pragma omp taskgroup new-line
19133 
19134    OpenMP 5.0:
19135    # pragma omp taskgroup taskgroup-clause[optseq] new-line
19136 */
19137 
19138 #define OMP_TASKGROUP_CLAUSE_MASK				\
19139 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
19140 
19141 static tree
c_parser_omp_taskgroup(location_t loc,c_parser * parser,bool * if_p)19142 c_parser_omp_taskgroup (location_t loc, c_parser *parser, bool *if_p)
19143 {
19144   tree clauses = c_parser_omp_all_clauses (parser, OMP_TASKGROUP_CLAUSE_MASK,
19145 					   "#pragma omp taskgroup");
19146 
19147   tree body = c_parser_omp_structured_block (parser, if_p);
19148   return c_finish_omp_taskgroup (loc, body, clauses);
19149 }
19150 
19151 /* OpenMP 4.0:
19152    # pragma omp cancel cancel-clause[optseq] new-line
19153 
19154    LOC is the location of the #pragma.
19155 */
19156 
19157 #define OMP_CANCEL_CLAUSE_MASK					\
19158 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL)	\
19159 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR)		\
19160 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS)	\
19161 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP)	\
19162 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
19163 
19164 static void
c_parser_omp_cancel(c_parser * parser)19165 c_parser_omp_cancel (c_parser *parser)
19166 {
19167   location_t loc = c_parser_peek_token (parser)->location;
19168 
19169   c_parser_consume_pragma (parser);
19170   tree clauses = c_parser_omp_all_clauses (parser, OMP_CANCEL_CLAUSE_MASK,
19171 					   "#pragma omp cancel");
19172 
19173   c_finish_omp_cancel (loc, clauses);
19174 }
19175 
19176 /* OpenMP 4.0:
19177    # pragma omp cancellation point cancelpt-clause[optseq] new-line
19178 
19179    LOC is the location of the #pragma.
19180 */
19181 
19182 #define OMP_CANCELLATION_POINT_CLAUSE_MASK			\
19183 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL)	\
19184 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR)		\
19185 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS)	\
19186 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
19187 
19188 static void
c_parser_omp_cancellation_point(c_parser * parser,enum pragma_context context)19189 c_parser_omp_cancellation_point (c_parser *parser, enum pragma_context context)
19190 {
19191   location_t loc = c_parser_peek_token (parser)->location;
19192   tree clauses;
19193   bool point_seen = false;
19194 
19195   c_parser_consume_pragma (parser);
19196   if (c_parser_next_token_is (parser, CPP_NAME))
19197     {
19198       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19199       if (strcmp (p, "point") == 0)
19200 	{
19201 	  c_parser_consume_token (parser);
19202 	  point_seen = true;
19203 	}
19204     }
19205   if (!point_seen)
19206     {
19207       c_parser_error (parser, "expected %<point%>");
19208       c_parser_skip_to_pragma_eol (parser);
19209       return;
19210     }
19211 
19212   if (context != pragma_compound)
19213     {
19214       if (context == pragma_stmt)
19215 	error_at (loc,
19216 		  "%<#pragma %s%> may only be used in compound statements",
19217 		  "omp cancellation point");
19218       else
19219 	c_parser_error (parser, "expected declaration specifiers");
19220       c_parser_skip_to_pragma_eol (parser, false);
19221       return;
19222     }
19223 
19224   clauses
19225     = c_parser_omp_all_clauses (parser, OMP_CANCELLATION_POINT_CLAUSE_MASK,
19226 				"#pragma omp cancellation point");
19227 
19228   c_finish_omp_cancellation_point (loc, clauses);
19229 }
19230 
19231 /* OpenMP 4.0:
19232    #pragma omp distribute distribute-clause[optseq] new-line
19233      for-loop  */
19234 
19235 #define OMP_DISTRIBUTE_CLAUSE_MASK				\
19236 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
19237 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
19238 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)	\
19239 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
19240 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE))
19241 
19242 static tree
c_parser_omp_distribute(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)19243 c_parser_omp_distribute (location_t loc, c_parser *parser,
19244 			 char *p_name, omp_clause_mask mask, tree *cclauses,
19245 			 bool *if_p)
19246 {
19247   tree clauses, block, ret;
19248 
19249   strcat (p_name, " distribute");
19250   mask |= OMP_DISTRIBUTE_CLAUSE_MASK;
19251 
19252   if (c_parser_next_token_is (parser, CPP_NAME))
19253     {
19254       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19255       bool simd = false;
19256       bool parallel = false;
19257 
19258       if (strcmp (p, "simd") == 0)
19259 	simd = true;
19260       else
19261 	parallel = strcmp (p, "parallel") == 0;
19262       if (parallel || simd)
19263 	{
19264 	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19265 	  if (cclauses == NULL)
19266 	    cclauses = cclauses_buf;
19267 	  c_parser_consume_token (parser);
19268 	  if (!flag_openmp)  /* flag_openmp_simd  */
19269 	    {
19270 	      if (simd)
19271 		return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
19272 					  if_p);
19273 	      else
19274 		return c_parser_omp_parallel (loc, parser, p_name, mask,
19275 					      cclauses, if_p);
19276 	    }
19277 	  block = c_begin_compound_stmt (true);
19278 	  if (simd)
19279 	    ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
19280 				     if_p);
19281 	  else
19282 	    ret = c_parser_omp_parallel (loc, parser, p_name, mask, cclauses,
19283 					 if_p);
19284 	  block = c_end_compound_stmt (loc, block, true);
19285 	  if (ret == NULL)
19286 	    return ret;
19287 	  ret = make_node (OMP_DISTRIBUTE);
19288 	  TREE_TYPE (ret) = void_type_node;
19289 	  OMP_FOR_BODY (ret) = block;
19290 	  OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
19291 	  SET_EXPR_LOCATION (ret, loc);
19292 	  add_stmt (ret);
19293 	  return ret;
19294 	}
19295     }
19296   if (!flag_openmp)  /* flag_openmp_simd  */
19297     {
19298       c_parser_skip_to_pragma_eol (parser, false);
19299       return NULL_TREE;
19300     }
19301 
19302   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19303   if (cclauses)
19304     {
19305       omp_split_clauses (loc, OMP_DISTRIBUTE, mask, clauses, cclauses);
19306       clauses = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
19307     }
19308 
19309   block = c_begin_compound_stmt (true);
19310   ret = c_parser_omp_for_loop (loc, parser, OMP_DISTRIBUTE, clauses, NULL,
19311 			       if_p);
19312   block = c_end_compound_stmt (loc, block, true);
19313   add_stmt (block);
19314 
19315   return ret;
19316 }
19317 
19318 /* OpenMP 4.0:
19319    # pragma omp teams teams-clause[optseq] new-line
19320      structured-block  */
19321 
19322 #define OMP_TEAMS_CLAUSE_MASK					\
19323 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
19324 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
19325 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED)	\
19326 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)	\
19327 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS)	\
19328 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT)	\
19329 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
19330 
19331 static tree
c_parser_omp_teams(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)19332 c_parser_omp_teams (location_t loc, c_parser *parser,
19333 		    char *p_name, omp_clause_mask mask, tree *cclauses,
19334 		    bool *if_p)
19335 {
19336   tree clauses, block, ret;
19337 
19338   strcat (p_name, " teams");
19339   mask |= OMP_TEAMS_CLAUSE_MASK;
19340 
19341   if (c_parser_next_token_is (parser, CPP_NAME))
19342     {
19343       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19344       if (strcmp (p, "distribute") == 0)
19345 	{
19346 	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19347 	  if (cclauses == NULL)
19348 	    cclauses = cclauses_buf;
19349 
19350 	  c_parser_consume_token (parser);
19351 	  if (!flag_openmp)  /* flag_openmp_simd  */
19352 	    return c_parser_omp_distribute (loc, parser, p_name, mask,
19353 					    cclauses, if_p);
19354 	  block = c_begin_omp_parallel ();
19355 	  ret = c_parser_omp_distribute (loc, parser, p_name, mask, cclauses,
19356 					 if_p);
19357 	  block = c_end_compound_stmt (loc, block, true);
19358 	  if (ret == NULL)
19359 	    return ret;
19360 	  clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
19361 	  ret = make_node (OMP_TEAMS);
19362 	  TREE_TYPE (ret) = void_type_node;
19363 	  OMP_TEAMS_CLAUSES (ret) = clauses;
19364 	  OMP_TEAMS_BODY (ret) = block;
19365 	  OMP_TEAMS_COMBINED (ret) = 1;
19366 	  SET_EXPR_LOCATION (ret, loc);
19367 	  return add_stmt (ret);
19368 	}
19369       else if (strcmp (p, "loop") == 0)
19370 	{
19371 	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19372 	  if (cclauses == NULL)
19373 	    cclauses = cclauses_buf;
19374 
19375 	  c_parser_consume_token (parser);
19376 	  if (!flag_openmp)  /* flag_openmp_simd  */
19377 	    return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
19378 				      if_p);
19379 	  block = c_begin_omp_parallel ();
19380 	  ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses, if_p);
19381 	  block = c_end_compound_stmt (loc, block, true);
19382 	  if (ret == NULL)
19383 	    return ret;
19384 	  clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
19385 	  ret = make_node (OMP_TEAMS);
19386 	  TREE_TYPE (ret) = void_type_node;
19387 	  OMP_TEAMS_CLAUSES (ret) = clauses;
19388 	  OMP_TEAMS_BODY (ret) = block;
19389 	  OMP_TEAMS_COMBINED (ret) = 1;
19390 	  SET_EXPR_LOCATION (ret, loc);
19391 	  return add_stmt (ret);
19392 	}
19393     }
19394   if (!flag_openmp)  /* flag_openmp_simd  */
19395     {
19396       c_parser_skip_to_pragma_eol (parser, false);
19397       return NULL_TREE;
19398     }
19399 
19400   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19401   if (cclauses)
19402     {
19403       omp_split_clauses (loc, OMP_TEAMS, mask, clauses, cclauses);
19404       clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
19405     }
19406 
19407   tree stmt = make_node (OMP_TEAMS);
19408   TREE_TYPE (stmt) = void_type_node;
19409   OMP_TEAMS_CLAUSES (stmt) = clauses;
19410   block = c_begin_omp_parallel ();
19411   add_stmt (c_parser_omp_structured_block (parser, if_p));
19412   OMP_TEAMS_BODY (stmt) = c_end_compound_stmt (loc, block, true);
19413   SET_EXPR_LOCATION (stmt, loc);
19414 
19415   return add_stmt (stmt);
19416 }
19417 
19418 /* OpenMP 4.0:
19419    # pragma omp target data target-data-clause[optseq] new-line
19420      structured-block  */
19421 
19422 #define OMP_TARGET_DATA_CLAUSE_MASK				\
19423 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE)	\
19424 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)		\
19425 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
19426 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
19427 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
19428 
19429 static tree
c_parser_omp_target_data(location_t loc,c_parser * parser,bool * if_p)19430 c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p)
19431 {
19432   tree clauses
19433     = c_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
19434 				"#pragma omp target data");
19435   int map_seen = 0;
19436   for (tree *pc = &clauses; *pc;)
19437     {
19438       if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
19439 	switch (OMP_CLAUSE_MAP_KIND (*pc))
19440 	  {
19441 	  case GOMP_MAP_TO:
19442 	  case GOMP_MAP_ALWAYS_TO:
19443 	  case GOMP_MAP_FROM:
19444 	  case GOMP_MAP_ALWAYS_FROM:
19445 	  case GOMP_MAP_TOFROM:
19446 	  case GOMP_MAP_ALWAYS_TOFROM:
19447 	  case GOMP_MAP_ALLOC:
19448 	    map_seen = 3;
19449 	    break;
19450 	  case GOMP_MAP_FIRSTPRIVATE_POINTER:
19451 	  case GOMP_MAP_ALWAYS_POINTER:
19452 	    break;
19453 	  default:
19454 	    map_seen |= 1;
19455 	    error_at (OMP_CLAUSE_LOCATION (*pc),
19456 		      "%<#pragma omp target data%> with map-type other "
19457 		      "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
19458 		      "on %<map%> clause");
19459 	    *pc = OMP_CLAUSE_CHAIN (*pc);
19460 	    continue;
19461 	  }
19462       else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
19463 	       || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
19464 	map_seen = 3;
19465       pc = &OMP_CLAUSE_CHAIN (*pc);
19466     }
19467 
19468   if (map_seen != 3)
19469     {
19470       if (map_seen == 0)
19471 	error_at (loc,
19472 		  "%<#pragma omp target data%> must contain at least "
19473 		  "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
19474 		  "clause");
19475       return NULL_TREE;
19476     }
19477 
19478   tree stmt = make_node (OMP_TARGET_DATA);
19479   TREE_TYPE (stmt) = void_type_node;
19480   OMP_TARGET_DATA_CLAUSES (stmt) = clauses;
19481   keep_next_level ();
19482   tree block = c_begin_compound_stmt (true);
19483   add_stmt (c_parser_omp_structured_block (parser, if_p));
19484   OMP_TARGET_DATA_BODY (stmt) = c_end_compound_stmt (loc, block, true);
19485 
19486   SET_EXPR_LOCATION (stmt, loc);
19487   return add_stmt (stmt);
19488 }
19489 
19490 /* OpenMP 4.0:
19491    # pragma omp target update target-update-clause[optseq] new-line */
19492 
19493 #define OMP_TARGET_UPDATE_CLAUSE_MASK				\
19494 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM)		\
19495 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO)		\
19496 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE)	\
19497 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
19498 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)	\
19499 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19500 
19501 static bool
c_parser_omp_target_update(location_t loc,c_parser * parser,enum pragma_context context)19502 c_parser_omp_target_update (location_t loc, c_parser *parser,
19503 			    enum pragma_context context)
19504 {
19505   if (context == pragma_stmt)
19506     {
19507       error_at (loc, "%<#pragma %s%> may only be used in compound statements",
19508 		"omp target update");
19509       c_parser_skip_to_pragma_eol (parser, false);
19510       return false;
19511     }
19512 
19513   tree clauses
19514     = c_parser_omp_all_clauses (parser, OMP_TARGET_UPDATE_CLAUSE_MASK,
19515 				"#pragma omp target update");
19516   if (omp_find_clause (clauses, OMP_CLAUSE_TO) == NULL_TREE
19517       && omp_find_clause (clauses, OMP_CLAUSE_FROM) == NULL_TREE)
19518     {
19519       error_at (loc,
19520 		"%<#pragma omp target update%> must contain at least one "
19521 		"%<from%> or %<to%> clauses");
19522       return false;
19523     }
19524 
19525   tree stmt = make_node (OMP_TARGET_UPDATE);
19526   TREE_TYPE (stmt) = void_type_node;
19527   OMP_TARGET_UPDATE_CLAUSES (stmt) = clauses;
19528   SET_EXPR_LOCATION (stmt, loc);
19529   add_stmt (stmt);
19530   return false;
19531 }
19532 
19533 /* OpenMP 4.5:
19534    # pragma omp target enter data target-data-clause[optseq] new-line  */
19535 
19536 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK			\
19537 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE)	\
19538 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)		\
19539 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
19540 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)	\
19541 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19542 
19543 static tree
c_parser_omp_target_enter_data(location_t loc,c_parser * parser,enum pragma_context context)19544 c_parser_omp_target_enter_data (location_t loc, c_parser *parser,
19545 				enum pragma_context context)
19546 {
19547   bool data_seen = false;
19548   if (c_parser_next_token_is (parser, CPP_NAME))
19549     {
19550       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19551       if (strcmp (p, "data") == 0)
19552 	{
19553 	  c_parser_consume_token (parser);
19554 	  data_seen = true;
19555 	}
19556     }
19557   if (!data_seen)
19558     {
19559       c_parser_error (parser, "expected %<data%>");
19560       c_parser_skip_to_pragma_eol (parser);
19561       return NULL_TREE;
19562     }
19563 
19564   if (context == pragma_stmt)
19565     {
19566       error_at (loc, "%<#pragma %s%> may only be used in compound statements",
19567 		"omp target enter data");
19568       c_parser_skip_to_pragma_eol (parser, false);
19569       return NULL_TREE;
19570     }
19571 
19572   tree clauses
19573     = c_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK,
19574 				"#pragma omp target enter data");
19575   int map_seen = 0;
19576   for (tree *pc = &clauses; *pc;)
19577     {
19578       if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
19579 	switch (OMP_CLAUSE_MAP_KIND (*pc))
19580 	  {
19581 	  case GOMP_MAP_TO:
19582 	  case GOMP_MAP_ALWAYS_TO:
19583 	  case GOMP_MAP_ALLOC:
19584 	    map_seen = 3;
19585 	    break;
19586 	  case GOMP_MAP_FIRSTPRIVATE_POINTER:
19587 	  case GOMP_MAP_ALWAYS_POINTER:
19588 	    break;
19589 	  default:
19590 	    map_seen |= 1;
19591 	    error_at (OMP_CLAUSE_LOCATION (*pc),
19592 		      "%<#pragma omp target enter data%> with map-type other "
19593 		      "than %<to%> or %<alloc%> on %<map%> clause");
19594 	    *pc = OMP_CLAUSE_CHAIN (*pc);
19595 	    continue;
19596 	  }
19597       pc = &OMP_CLAUSE_CHAIN (*pc);
19598     }
19599 
19600   if (map_seen != 3)
19601     {
19602       if (map_seen == 0)
19603 	error_at (loc,
19604 		  "%<#pragma omp target enter data%> must contain at least "
19605 		  "one %<map%> clause");
19606       return NULL_TREE;
19607     }
19608 
19609   tree stmt = make_node (OMP_TARGET_ENTER_DATA);
19610   TREE_TYPE (stmt) = void_type_node;
19611   OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses;
19612   SET_EXPR_LOCATION (stmt, loc);
19613   add_stmt (stmt);
19614   return stmt;
19615 }
19616 
19617 /* OpenMP 4.5:
19618    # pragma omp target exit data target-data-clause[optseq] new-line  */
19619 
19620 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK			\
19621 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE)	\
19622 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)		\
19623 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
19624 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)	\
19625 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19626 
19627 static tree
c_parser_omp_target_exit_data(location_t loc,c_parser * parser,enum pragma_context context)19628 c_parser_omp_target_exit_data (location_t loc, c_parser *parser,
19629 			       enum pragma_context context)
19630 {
19631   bool data_seen = false;
19632   if (c_parser_next_token_is (parser, CPP_NAME))
19633     {
19634       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19635       if (strcmp (p, "data") == 0)
19636 	{
19637 	  c_parser_consume_token (parser);
19638 	  data_seen = true;
19639 	}
19640     }
19641   if (!data_seen)
19642     {
19643       c_parser_error (parser, "expected %<data%>");
19644       c_parser_skip_to_pragma_eol (parser);
19645       return NULL_TREE;
19646     }
19647 
19648   if (context == pragma_stmt)
19649     {
19650       error_at (loc, "%<#pragma %s%> may only be used in compound statements",
19651 		"omp target exit data");
19652       c_parser_skip_to_pragma_eol (parser, false);
19653       return NULL_TREE;
19654     }
19655 
19656   tree clauses
19657     = c_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK,
19658 				"#pragma omp target exit data");
19659 
19660   int map_seen = 0;
19661   for (tree *pc = &clauses; *pc;)
19662     {
19663       if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
19664 	switch (OMP_CLAUSE_MAP_KIND (*pc))
19665 	  {
19666 	  case GOMP_MAP_FROM:
19667 	  case GOMP_MAP_ALWAYS_FROM:
19668 	  case GOMP_MAP_RELEASE:
19669 	  case GOMP_MAP_DELETE:
19670 	    map_seen = 3;
19671 	    break;
19672 	  case GOMP_MAP_FIRSTPRIVATE_POINTER:
19673 	  case GOMP_MAP_ALWAYS_POINTER:
19674 	    break;
19675 	  default:
19676 	    map_seen |= 1;
19677 	    error_at (OMP_CLAUSE_LOCATION (*pc),
19678 		      "%<#pragma omp target exit data%> with map-type other "
19679 		      "than %<from%>, %<release%> or %<delete%> on %<map%>"
19680 		      " clause");
19681 	    *pc = OMP_CLAUSE_CHAIN (*pc);
19682 	    continue;
19683 	  }
19684       pc = &OMP_CLAUSE_CHAIN (*pc);
19685     }
19686 
19687   if (map_seen != 3)
19688     {
19689       if (map_seen == 0)
19690 	error_at (loc,
19691 		  "%<#pragma omp target exit data%> must contain at least one "
19692 		  "%<map%> clause");
19693       return NULL_TREE;
19694     }
19695 
19696   tree stmt = make_node (OMP_TARGET_EXIT_DATA);
19697   TREE_TYPE (stmt) = void_type_node;
19698   OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses;
19699   SET_EXPR_LOCATION (stmt, loc);
19700   add_stmt (stmt);
19701   return stmt;
19702 }
19703 
19704 /* OpenMP 4.0:
19705    # pragma omp target target-clause[optseq] new-line
19706      structured-block  */
19707 
19708 #define OMP_TARGET_CLAUSE_MASK					\
19709 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE)	\
19710 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)		\
19711 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
19712 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)	\
19713 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT)	\
19714 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
19715 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
19716 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP)	\
19717 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR))
19718 
19719 static bool
c_parser_omp_target(c_parser * parser,enum pragma_context context,bool * if_p)19720 c_parser_omp_target (c_parser *parser, enum pragma_context context, bool *if_p)
19721 {
19722   location_t loc = c_parser_peek_token (parser)->location;
19723   c_parser_consume_pragma (parser);
19724   tree *pc = NULL, stmt, block;
19725 
19726   if (context != pragma_stmt && context != pragma_compound)
19727     {
19728       c_parser_error (parser, "expected declaration specifiers");
19729       c_parser_skip_to_pragma_eol (parser);
19730       return false;
19731     }
19732 
19733   if (flag_openmp)
19734     omp_requires_mask
19735       = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
19736 
19737   if (c_parser_next_token_is (parser, CPP_NAME))
19738     {
19739       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19740       enum tree_code ccode = ERROR_MARK;
19741 
19742       if (strcmp (p, "teams") == 0)
19743 	ccode = OMP_TEAMS;
19744       else if (strcmp (p, "parallel") == 0)
19745 	ccode = OMP_PARALLEL;
19746       else if (strcmp (p, "simd") == 0)
19747 	ccode = OMP_SIMD;
19748       if (ccode != ERROR_MARK)
19749 	{
19750 	  tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT];
19751 	  char p_name[sizeof ("#pragma omp target teams distribute "
19752 			      "parallel for simd")];
19753 
19754 	  c_parser_consume_token (parser);
19755 	  strcpy (p_name, "#pragma omp target");
19756 	  if (!flag_openmp)  /* flag_openmp_simd  */
19757 	    {
19758 	      tree stmt;
19759 	      switch (ccode)
19760 		{
19761 		case OMP_TEAMS:
19762 		  stmt = c_parser_omp_teams (loc, parser, p_name,
19763 					     OMP_TARGET_CLAUSE_MASK,
19764 					     cclauses, if_p);
19765 		  break;
19766 		case OMP_PARALLEL:
19767 		  stmt = c_parser_omp_parallel (loc, parser, p_name,
19768 						OMP_TARGET_CLAUSE_MASK,
19769 						cclauses, if_p);
19770 		  break;
19771 		case OMP_SIMD:
19772 		  stmt = c_parser_omp_simd (loc, parser, p_name,
19773 					    OMP_TARGET_CLAUSE_MASK,
19774 					    cclauses, if_p);
19775 		  break;
19776 		default:
19777 		  gcc_unreachable ();
19778 		}
19779 	      return stmt != NULL_TREE;
19780 	    }
19781 	  keep_next_level ();
19782 	  tree block = c_begin_compound_stmt (true), ret;
19783 	  switch (ccode)
19784 	    {
19785 	    case OMP_TEAMS:
19786 	      ret = c_parser_omp_teams (loc, parser, p_name,
19787 					OMP_TARGET_CLAUSE_MASK, cclauses,
19788 					if_p);
19789 	      break;
19790 	    case OMP_PARALLEL:
19791 	      ret = c_parser_omp_parallel (loc, parser, p_name,
19792 					   OMP_TARGET_CLAUSE_MASK, cclauses,
19793 					   if_p);
19794 	      break;
19795 	    case OMP_SIMD:
19796 	      ret = c_parser_omp_simd (loc, parser, p_name,
19797 				       OMP_TARGET_CLAUSE_MASK, cclauses,
19798 				       if_p);
19799 	      break;
19800 	    default:
19801 	      gcc_unreachable ();
19802 	    }
19803 	  block = c_end_compound_stmt (loc, block, true);
19804 	  if (ret == NULL_TREE)
19805 	    return false;
19806 	  if (ccode == OMP_TEAMS)
19807 	    {
19808 	      /* For combined target teams, ensure the num_teams and
19809 		 thread_limit clause expressions are evaluated on the host,
19810 		 before entering the target construct.  */
19811 	      tree c;
19812 	      for (c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
19813 		   c; c = OMP_CLAUSE_CHAIN (c))
19814 		if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
19815 		     || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
19816 		    && TREE_CODE (OMP_CLAUSE_OPERAND (c, 0)) != INTEGER_CST)
19817 		  {
19818 		    tree expr = OMP_CLAUSE_OPERAND (c, 0);
19819 		    tree tmp = create_tmp_var_raw (TREE_TYPE (expr));
19820 		    expr = build4 (TARGET_EXPR, TREE_TYPE (expr), tmp,
19821 				   expr, NULL_TREE, NULL_TREE);
19822 		    add_stmt (expr);
19823 		    OMP_CLAUSE_OPERAND (c, 0) = expr;
19824 		    tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
19825 						OMP_CLAUSE_FIRSTPRIVATE);
19826 		    OMP_CLAUSE_DECL (tc) = tmp;
19827 		    OMP_CLAUSE_CHAIN (tc)
19828 		      = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
19829 		    cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc;
19830 		  }
19831 	    }
19832 	  tree stmt = make_node (OMP_TARGET);
19833 	  TREE_TYPE (stmt) = void_type_node;
19834 	  OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
19835 	  OMP_TARGET_BODY (stmt) = block;
19836 	  OMP_TARGET_COMBINED (stmt) = 1;
19837 	  SET_EXPR_LOCATION (stmt, loc);
19838 	  add_stmt (stmt);
19839 	  pc = &OMP_TARGET_CLAUSES (stmt);
19840 	  goto check_clauses;
19841 	}
19842       else if (!flag_openmp)  /* flag_openmp_simd  */
19843 	{
19844 	  c_parser_skip_to_pragma_eol (parser, false);
19845 	  return false;
19846 	}
19847       else if (strcmp (p, "data") == 0)
19848 	{
19849 	  c_parser_consume_token (parser);
19850 	  c_parser_omp_target_data (loc, parser, if_p);
19851 	  return true;
19852 	}
19853       else if (strcmp (p, "enter") == 0)
19854 	{
19855 	  c_parser_consume_token (parser);
19856 	  c_parser_omp_target_enter_data (loc, parser, context);
19857 	  return false;
19858 	}
19859       else if (strcmp (p, "exit") == 0)
19860 	{
19861 	  c_parser_consume_token (parser);
19862 	  c_parser_omp_target_exit_data (loc, parser, context);
19863 	  return false;
19864 	}
19865       else if (strcmp (p, "update") == 0)
19866 	{
19867 	  c_parser_consume_token (parser);
19868 	  return c_parser_omp_target_update (loc, parser, context);
19869 	}
19870     }
19871   if (!flag_openmp) /* flag_openmp_simd  */
19872     {
19873       c_parser_skip_to_pragma_eol (parser, false);
19874       return false;
19875     }
19876 
19877   stmt = make_node (OMP_TARGET);
19878   TREE_TYPE (stmt) = void_type_node;
19879 
19880   OMP_TARGET_CLAUSES (stmt)
19881     = c_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK,
19882 				"#pragma omp target");
19883   pc = &OMP_TARGET_CLAUSES (stmt);
19884   keep_next_level ();
19885   block = c_begin_compound_stmt (true);
19886   add_stmt (c_parser_omp_structured_block (parser, if_p));
19887   OMP_TARGET_BODY (stmt) = c_end_compound_stmt (loc, block, true);
19888 
19889   SET_EXPR_LOCATION (stmt, loc);
19890   add_stmt (stmt);
19891 
19892 check_clauses:
19893   while (*pc)
19894     {
19895       if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
19896 	switch (OMP_CLAUSE_MAP_KIND (*pc))
19897 	  {
19898 	  case GOMP_MAP_TO:
19899 	  case GOMP_MAP_ALWAYS_TO:
19900 	  case GOMP_MAP_FROM:
19901 	  case GOMP_MAP_ALWAYS_FROM:
19902 	  case GOMP_MAP_TOFROM:
19903 	  case GOMP_MAP_ALWAYS_TOFROM:
19904 	  case GOMP_MAP_ALLOC:
19905 	  case GOMP_MAP_FIRSTPRIVATE_POINTER:
19906 	  case GOMP_MAP_ALWAYS_POINTER:
19907 	    break;
19908 	  default:
19909 	    error_at (OMP_CLAUSE_LOCATION (*pc),
19910 		      "%<#pragma omp target%> with map-type other "
19911 		      "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
19912 		      "on %<map%> clause");
19913 	    *pc = OMP_CLAUSE_CHAIN (*pc);
19914 	    continue;
19915 	  }
19916       pc = &OMP_CLAUSE_CHAIN (*pc);
19917     }
19918   return true;
19919 }
19920 
19921 /* OpenMP 4.0:
19922    # pragma omp declare simd declare-simd-clauses[optseq] new-line
19923 
19924    OpenMP 5.0:
19925    # pragma omp declare variant (identifier) match(context-selector) new-line
19926    */
19927 
19928 #define OMP_DECLARE_SIMD_CLAUSE_MASK				\
19929 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN)	\
19930 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR)	\
19931 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED)	\
19932 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)	\
19933 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH)	\
19934 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
19935 
19936 static void
c_parser_omp_declare_simd(c_parser * parser,enum pragma_context context)19937 c_parser_omp_declare_simd (c_parser *parser, enum pragma_context context)
19938 {
19939   c_token *token = c_parser_peek_token (parser);
19940   gcc_assert (token->type == CPP_NAME);
19941   tree kind = token->value;
19942   gcc_assert (strcmp (IDENTIFIER_POINTER (kind), "simd") == 0
19943 	      || strcmp (IDENTIFIER_POINTER (kind), "variant") == 0);
19944 
19945   auto_vec<c_token> clauses;
19946   while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
19947     {
19948       c_token *token = c_parser_peek_token (parser);
19949       if (token->type == CPP_EOF)
19950 	{
19951 	  c_parser_skip_to_pragma_eol (parser);
19952 	  return;
19953 	}
19954       clauses.safe_push (*token);
19955       c_parser_consume_token (parser);
19956     }
19957   clauses.safe_push (*c_parser_peek_token (parser));
19958   c_parser_skip_to_pragma_eol (parser);
19959 
19960   while (c_parser_next_token_is (parser, CPP_PRAGMA))
19961     {
19962       if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_DECLARE
19963 	  || c_parser_peek_2nd_token (parser)->type != CPP_NAME
19964 	  || c_parser_peek_2nd_token (parser)->value != kind)
19965 	{
19966 	  error ("%<#pragma omp declare %s%> must be followed by "
19967 		 "function declaration or definition or another "
19968 		 "%<#pragma omp declare %s%>",
19969 		 IDENTIFIER_POINTER (kind), IDENTIFIER_POINTER (kind));
19970 	  return;
19971 	}
19972       c_parser_consume_pragma (parser);
19973       while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
19974 	{
19975 	  c_token *token = c_parser_peek_token (parser);
19976 	  if (token->type == CPP_EOF)
19977 	    {
19978 	      c_parser_skip_to_pragma_eol (parser);
19979 	      return;
19980 	    }
19981 	  clauses.safe_push (*token);
19982 	  c_parser_consume_token (parser);
19983 	}
19984       clauses.safe_push (*c_parser_peek_token (parser));
19985       c_parser_skip_to_pragma_eol (parser);
19986     }
19987 
19988   /* Make sure nothing tries to read past the end of the tokens.  */
19989   c_token eof_token;
19990   memset (&eof_token, 0, sizeof (eof_token));
19991   eof_token.type = CPP_EOF;
19992   clauses.safe_push (eof_token);
19993   clauses.safe_push (eof_token);
19994 
19995   switch (context)
19996     {
19997     case pragma_external:
19998       if (c_parser_next_token_is (parser, CPP_KEYWORD)
19999 	  && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
20000 	{
20001 	  int ext = disable_extension_diagnostics ();
20002 	  do
20003 	    c_parser_consume_token (parser);
20004 	  while (c_parser_next_token_is (parser, CPP_KEYWORD)
20005 		 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
20006 	  c_parser_declaration_or_fndef (parser, true, true, true, false, true,
20007 					 NULL, clauses);
20008 	  restore_extension_diagnostics (ext);
20009 	}
20010       else
20011 	c_parser_declaration_or_fndef (parser, true, true, true, false, true,
20012 				       NULL, clauses);
20013       break;
20014     case pragma_struct:
20015     case pragma_param:
20016     case pragma_stmt:
20017       error ("%<#pragma omp declare %s%> must be followed by "
20018 	     "function declaration or definition",
20019 	     IDENTIFIER_POINTER (kind));
20020       break;
20021     case pragma_compound:
20022       if (c_parser_next_token_is (parser, CPP_KEYWORD)
20023 	  && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
20024 	{
20025 	  int ext = disable_extension_diagnostics ();
20026 	  do
20027 	    c_parser_consume_token (parser);
20028 	  while (c_parser_next_token_is (parser, CPP_KEYWORD)
20029 		 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
20030 	  if (c_parser_next_tokens_start_declaration (parser))
20031 	    {
20032 	      c_parser_declaration_or_fndef (parser, true, true, true, true,
20033 					     true, NULL, clauses);
20034 	      restore_extension_diagnostics (ext);
20035 	      break;
20036 	    }
20037 	  restore_extension_diagnostics (ext);
20038 	}
20039       else if (c_parser_next_tokens_start_declaration (parser))
20040 	{
20041 	  c_parser_declaration_or_fndef (parser, true, true, true, true, true,
20042 					 NULL, clauses);
20043 	  break;
20044 	}
20045       error ("%<#pragma omp declare %s%> must be followed by "
20046 	     "function declaration or definition",
20047 	     IDENTIFIER_POINTER (kind));
20048       break;
20049     default:
20050       gcc_unreachable ();
20051     }
20052 }
20053 
20054 static const char *const omp_construct_selectors[] = {
20055   "simd", "target", "teams", "parallel", "for", NULL };
20056 static const char *const omp_device_selectors[] = {
20057   "kind", "isa", "arch", NULL };
20058 static const char *const omp_implementation_selectors[] = {
20059   "vendor", "extension", "atomic_default_mem_order", "unified_address",
20060   "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL };
20061 static const char *const omp_user_selectors[] = {
20062   "condition", NULL };
20063 
20064 /* OpenMP 5.0:
20065 
20066    trait-selector:
20067      trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
20068 
20069    trait-score:
20070      score(score-expression)  */
20071 
20072 static tree
c_parser_omp_context_selector(c_parser * parser,tree set,tree parms)20073 c_parser_omp_context_selector (c_parser *parser, tree set, tree parms)
20074 {
20075   tree ret = NULL_TREE;
20076   do
20077     {
20078       tree selector;
20079       if (c_parser_next_token_is (parser, CPP_KEYWORD)
20080 	  || c_parser_next_token_is (parser, CPP_NAME))
20081 	selector = c_parser_peek_token (parser)->value;
20082       else
20083 	{
20084 	  c_parser_error (parser, "expected trait selector name");
20085 	  return error_mark_node;
20086 	}
20087 
20088       tree properties = NULL_TREE;
20089       const char *const *selectors = NULL;
20090       bool allow_score = true;
20091       bool allow_user = false;
20092       int property_limit = 0;
20093       enum { CTX_PROPERTY_NONE, CTX_PROPERTY_USER, CTX_PROPERTY_NAME_LIST,
20094 	     CTX_PROPERTY_ID, CTX_PROPERTY_EXPR,
20095 	     CTX_PROPERTY_SIMD } property_kind = CTX_PROPERTY_NONE;
20096       switch (IDENTIFIER_POINTER (set)[0])
20097 	{
20098 	case 'c': /* construct */
20099 	  selectors = omp_construct_selectors;
20100 	  allow_score = false;
20101 	  property_limit = 1;
20102 	  property_kind = CTX_PROPERTY_SIMD;
20103 	  break;
20104 	case 'd': /* device */
20105 	  selectors = omp_device_selectors;
20106 	  allow_score = false;
20107 	  allow_user = true;
20108 	  property_limit = 3;
20109 	  property_kind = CTX_PROPERTY_NAME_LIST;
20110 	  break;
20111 	case 'i': /* implementation */
20112 	  selectors = omp_implementation_selectors;
20113 	  allow_user = true;
20114 	  property_limit = 3;
20115 	  property_kind = CTX_PROPERTY_NAME_LIST;
20116 	  break;
20117 	case 'u': /* user */
20118 	  selectors = omp_user_selectors;
20119 	  property_limit = 1;
20120 	  property_kind = CTX_PROPERTY_EXPR;
20121 	  break;
20122 	default:
20123 	  gcc_unreachable ();
20124 	}
20125       for (int i = 0; ; i++)
20126 	{
20127 	  if (selectors[i] == NULL)
20128 	    {
20129 	      if (allow_user)
20130 		{
20131 		  property_kind = CTX_PROPERTY_USER;
20132 		  break;
20133 		}
20134 	      else
20135 		{
20136 		  error_at (c_parser_peek_token (parser)->location,
20137 			    "selector %qs not allowed for context selector "
20138 			    "set %qs", IDENTIFIER_POINTER (selector),
20139 			    IDENTIFIER_POINTER (set));
20140 		  c_parser_consume_token (parser);
20141 		  return error_mark_node;
20142 		}
20143 	    }
20144 	  if (i == property_limit)
20145 	    property_kind = CTX_PROPERTY_NONE;
20146 	  if (strcmp (selectors[i], IDENTIFIER_POINTER (selector)) == 0)
20147 	    break;
20148 	}
20149       if (property_kind == CTX_PROPERTY_NAME_LIST
20150 	  && IDENTIFIER_POINTER (set)[0] == 'i'
20151 	  && strcmp (IDENTIFIER_POINTER (selector),
20152 		     "atomic_default_mem_order") == 0)
20153 	property_kind = CTX_PROPERTY_ID;
20154 
20155       c_parser_consume_token (parser);
20156 
20157       if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
20158 	{
20159 	  if (property_kind == CTX_PROPERTY_NONE)
20160 	    {
20161 	      error_at (c_parser_peek_token (parser)->location,
20162 			"selector %qs does not accept any properties",
20163 			IDENTIFIER_POINTER (selector));
20164 	      return error_mark_node;
20165 	    }
20166 
20167 	  matching_parens parens;
20168 	  parens.require_open (parser);
20169 
20170 	  c_token *token = c_parser_peek_token (parser);
20171 	  if (allow_score
20172 	      && c_parser_next_token_is (parser, CPP_NAME)
20173 	      && strcmp (IDENTIFIER_POINTER (token->value), "score") == 0
20174 	      && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
20175 	    {
20176 	      c_parser_consume_token (parser);
20177 
20178 	      matching_parens parens2;
20179 	      parens2.require_open (parser);
20180 	      tree score = c_parser_expr_no_commas (parser, NULL).value;
20181 	      parens2.skip_until_found_close (parser);
20182 	      c_parser_require (parser, CPP_COLON, "expected %<:%>");
20183 	      if (score != error_mark_node)
20184 		{
20185 		  mark_exp_read (score);
20186 		  score = c_fully_fold (score, false, NULL);
20187 		  if (!INTEGRAL_TYPE_P (TREE_TYPE (score))
20188 		      || TREE_CODE (score) != INTEGER_CST)
20189 		    error_at (token->location, "score argument must be "
20190 			      "constant integer expression");
20191 		  else if (tree_int_cst_sgn (score) < 0)
20192 		    error_at (token->location, "score argument must be "
20193 			      "non-negative");
20194 		  else
20195 		    properties = tree_cons (get_identifier (" score"),
20196 					    score, properties);
20197 		}
20198 	      token = c_parser_peek_token (parser);
20199 	    }
20200 
20201 	  switch (property_kind)
20202 	    {
20203 	      tree t;
20204 	    case CTX_PROPERTY_USER:
20205 	      do
20206 		{
20207 		  t = c_parser_expr_no_commas (parser, NULL).value;
20208 		  if (TREE_CODE (t) == STRING_CST)
20209 		    properties = tree_cons (NULL_TREE, t, properties);
20210 		  else if (t != error_mark_node)
20211 		    {
20212 		      mark_exp_read (t);
20213 		      t = c_fully_fold (t, false, NULL);
20214 		      if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
20215 			  || !tree_fits_shwi_p (t))
20216 			error_at (token->location, "property must be "
20217 				  "constant integer expression or string "
20218 				  "literal");
20219 		      else
20220 			properties = tree_cons (NULL_TREE, t, properties);
20221 		    }
20222 		  else
20223 		    return error_mark_node;
20224 
20225 		  if (c_parser_next_token_is (parser, CPP_COMMA))
20226 		    c_parser_consume_token (parser);
20227 		  else
20228 		    break;
20229 		}
20230 	      while (1);
20231 	      break;
20232 	    case CTX_PROPERTY_ID:
20233 	      if (c_parser_next_token_is (parser, CPP_KEYWORD)
20234 		  || c_parser_next_token_is (parser, CPP_NAME))
20235 		{
20236 		  tree prop = c_parser_peek_token (parser)->value;
20237 		  c_parser_consume_token (parser);
20238 		  properties = tree_cons (prop, NULL_TREE, properties);
20239 		}
20240 	      else
20241 		{
20242 		  c_parser_error (parser, "expected identifier");
20243 		  return error_mark_node;
20244 		}
20245 	      break;
20246 	    case CTX_PROPERTY_NAME_LIST:
20247 	      do
20248 		{
20249 		  tree prop = NULL_TREE, value = NULL_TREE;
20250 		  if (c_parser_next_token_is (parser, CPP_KEYWORD)
20251 		      || c_parser_next_token_is (parser, CPP_NAME))
20252 		    {
20253 		      prop = c_parser_peek_token (parser)->value;
20254 		      c_parser_consume_token (parser);
20255 		    }
20256 		  else if (c_parser_next_token_is (parser, CPP_STRING))
20257 		    value = c_parser_string_literal (parser, false,
20258 						     false).value;
20259 		  else
20260 		    {
20261 		      c_parser_error (parser, "expected identifier or "
20262 					      "string literal");
20263 		      return error_mark_node;
20264 		    }
20265 
20266 		  properties = tree_cons (prop, value, properties);
20267 
20268 		  if (c_parser_next_token_is (parser, CPP_COMMA))
20269 		    c_parser_consume_token (parser);
20270 		  else
20271 		    break;
20272 		}
20273 	      while (1);
20274 	      break;
20275 	    case CTX_PROPERTY_EXPR:
20276 	      t = c_parser_expr_no_commas (parser, NULL).value;
20277 	      if (t != error_mark_node)
20278 		{
20279 		  mark_exp_read (t);
20280 		  t = c_fully_fold (t, false, NULL);
20281 		  if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
20282 		      || !tree_fits_shwi_p (t))
20283 		    error_at (token->location, "property must be "
20284 			      "constant integer expression");
20285 		  else
20286 		    properties = tree_cons (NULL_TREE, t, properties);
20287 		}
20288 	      else
20289 		return error_mark_node;
20290 	      break;
20291 	    case CTX_PROPERTY_SIMD:
20292 	      if (parms == NULL_TREE)
20293 		{
20294 		  error_at (token->location, "properties for %<simd%> "
20295 			    "selector may not be specified in "
20296 			    "%<metadirective%>");
20297 		  return error_mark_node;
20298 		}
20299 	      tree c;
20300 	      c = c_parser_omp_all_clauses (parser,
20301 					    OMP_DECLARE_SIMD_CLAUSE_MASK,
20302 					    "simd", true, 2);
20303 	      c = c_omp_declare_simd_clauses_to_numbers (parms
20304 							 == error_mark_node
20305 							 ? NULL_TREE : parms,
20306 							 c);
20307 	      properties = c;
20308 	      break;
20309 	    default:
20310 	      gcc_unreachable ();
20311 	    }
20312 
20313 	  parens.skip_until_found_close (parser);
20314 	  properties = nreverse (properties);
20315 	}
20316       else if (property_kind == CTX_PROPERTY_NAME_LIST
20317 	       || property_kind == CTX_PROPERTY_ID
20318 	       || property_kind == CTX_PROPERTY_EXPR)
20319 	{
20320 	  c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>");
20321 	  return error_mark_node;
20322 	}
20323 
20324       ret = tree_cons (selector, properties, ret);
20325 
20326       if (c_parser_next_token_is (parser, CPP_COMMA))
20327 	c_parser_consume_token (parser);
20328       else
20329 	break;
20330     }
20331   while (1);
20332 
20333   return nreverse (ret);
20334 }
20335 
20336 /* OpenMP 5.0:
20337 
20338    trait-set-selector[,trait-set-selector[,...]]
20339 
20340    trait-set-selector:
20341      trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
20342 
20343    trait-set-selector-name:
20344      constructor
20345      device
20346      implementation
20347      user  */
20348 
20349 static tree
c_parser_omp_context_selector_specification(c_parser * parser,tree parms)20350 c_parser_omp_context_selector_specification (c_parser *parser, tree parms)
20351 {
20352   tree ret = NULL_TREE;
20353   do
20354     {
20355       const char *setp = "";
20356       if (c_parser_next_token_is (parser, CPP_NAME))
20357 	setp = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20358       switch (setp[0])
20359 	{
20360 	case 'c':
20361 	  if (strcmp (setp, "construct") == 0)
20362 	    setp = NULL;
20363 	  break;
20364 	case 'd':
20365 	  if (strcmp (setp, "device") == 0)
20366 	    setp = NULL;
20367 	  break;
20368 	case 'i':
20369 	  if (strcmp (setp, "implementation") == 0)
20370 	    setp = NULL;
20371 	  break;
20372 	case 'u':
20373 	  if (strcmp (setp, "user") == 0)
20374 	    setp = NULL;
20375 	  break;
20376 	default:
20377 	  break;
20378 	}
20379       if (setp)
20380 	{
20381 	  c_parser_error (parser, "expected %<construct%>, %<device%>, "
20382 				  "%<implementation%> or %<user%>");
20383 	  return error_mark_node;
20384 	}
20385 
20386       tree set = c_parser_peek_token (parser)->value;
20387       c_parser_consume_token (parser);
20388 
20389       if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
20390 	return error_mark_node;
20391 
20392       matching_braces braces;
20393       if (!braces.require_open (parser))
20394 	return error_mark_node;
20395 
20396       tree selectors = c_parser_omp_context_selector (parser, set, parms);
20397       if (selectors == error_mark_node)
20398 	ret = error_mark_node;
20399       else if (ret != error_mark_node)
20400 	ret = tree_cons (set, selectors, ret);
20401 
20402       braces.skip_until_found_close (parser);
20403 
20404       if (c_parser_next_token_is (parser, CPP_COMMA))
20405 	c_parser_consume_token (parser);
20406       else
20407 	break;
20408     }
20409   while (1);
20410 
20411   if (ret == error_mark_node)
20412     return ret;
20413   return nreverse (ret);
20414 }
20415 
20416 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
20417    that into "omp declare variant base" attribute.  */
20418 
20419 static void
c_finish_omp_declare_variant(c_parser * parser,tree fndecl,tree parms)20420 c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms)
20421 {
20422   matching_parens parens;
20423   if (!parens.require_open (parser))
20424     {
20425      fail:
20426       c_parser_skip_to_pragma_eol (parser, false);
20427       return;
20428     }
20429 
20430   if (c_parser_next_token_is_not (parser, CPP_NAME)
20431       || c_parser_peek_token (parser)->id_kind != C_ID_ID)
20432     {
20433       c_parser_error (parser, "expected identifier");
20434       goto fail;
20435     }
20436 
20437   c_token *token = c_parser_peek_token (parser);
20438   tree variant = lookup_name (token->value);
20439 
20440   if (variant == NULL_TREE)
20441     {
20442       undeclared_variable (token->location, token->value);
20443       variant = error_mark_node;
20444     }
20445 
20446   c_parser_consume_token (parser);
20447 
20448   parens.require_close (parser);
20449 
20450   const char *clause = "";
20451   location_t match_loc = c_parser_peek_token (parser)->location;
20452   if (c_parser_next_token_is (parser, CPP_NAME))
20453     clause = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20454   if (strcmp (clause, "match"))
20455     {
20456       c_parser_error (parser, "expected %<match%>");
20457       goto fail;
20458     }
20459 
20460   c_parser_consume_token (parser);
20461 
20462   if (!parens.require_open (parser))
20463     goto fail;
20464 
20465   if (parms == NULL_TREE)
20466     parms = error_mark_node;
20467 
20468   tree ctx = c_parser_omp_context_selector_specification (parser, parms);
20469   if (ctx == error_mark_node)
20470     goto fail;
20471   ctx = c_omp_check_context_selector (match_loc, ctx);
20472   if (ctx != error_mark_node && variant != error_mark_node)
20473     {
20474       if (TREE_CODE (variant) != FUNCTION_DECL)
20475 	{
20476 	  error_at (token->location, "variant %qD is not a function", variant);
20477 	  variant = error_mark_node;
20478 	}
20479       else if (omp_get_context_selector (ctx, "construct", "simd") == NULL_TREE
20480 	       && !comptypes (TREE_TYPE (fndecl), TREE_TYPE (variant)))
20481 	{
20482 	  error_at (token->location, "variant %qD and base %qD have "
20483 				     "incompatible types", variant, fndecl);
20484 	  variant = error_mark_node;
20485 	}
20486       else if (fndecl_built_in_p (variant)
20487 	       && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
20488 			    "__builtin_", strlen ("__builtin_")) == 0
20489 		   || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
20490 			       "__sync_", strlen ("__sync_")) == 0
20491 		   || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
20492 			       "__atomic_", strlen ("__atomic_")) == 0))
20493 	{
20494 	  error_at (token->location, "variant %qD is a built-in", variant);
20495 	  variant = error_mark_node;
20496 	}
20497       if (variant != error_mark_node)
20498 	{
20499 	  C_DECL_USED (variant) = 1;
20500 	  tree construct = omp_get_context_selector (ctx, "construct", NULL);
20501 	  c_omp_mark_declare_variant (match_loc, variant, construct);
20502 	  if (omp_context_selector_matches (ctx))
20503 	    {
20504 	      tree attr
20505 		= tree_cons (get_identifier ("omp declare variant base"),
20506 			     build_tree_list (variant, ctx),
20507 			     DECL_ATTRIBUTES (fndecl));
20508 	      DECL_ATTRIBUTES (fndecl) = attr;
20509 	    }
20510 	}
20511     }
20512 
20513   parens.require_close (parser);
20514   c_parser_skip_to_pragma_eol (parser);
20515 }
20516 
20517 /* Finalize #pragma omp declare simd or #pragma omp declare variant
20518    clauses after FNDECL has been parsed, and put that into "omp declare simd"
20519    or "omp declare variant base" attribute.  */
20520 
20521 static void
c_finish_omp_declare_simd(c_parser * parser,tree fndecl,tree parms,vec<c_token> clauses)20522 c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms,
20523 			   vec<c_token> clauses)
20524 {
20525   /* Normally first token is CPP_NAME "simd" or "variant".  CPP_EOF there
20526      indicates error has been reported and CPP_PRAGMA that
20527      c_finish_omp_declare_simd has already processed the tokens.  */
20528   if (clauses.exists () && clauses[0].type == CPP_EOF)
20529     return;
20530   const char *kind = "simd";
20531   if (clauses.exists ()
20532       && (clauses[0].type == CPP_NAME || clauses[0].type == CPP_PRAGMA))
20533     kind = IDENTIFIER_POINTER (clauses[0].value);
20534   gcc_assert (strcmp (kind, "simd") == 0 || strcmp (kind, "variant") == 0);
20535   if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
20536     {
20537       error ("%<#pragma omp declare %s%> not immediately followed by "
20538 	     "a function declaration or definition", kind);
20539       clauses[0].type = CPP_EOF;
20540       return;
20541     }
20542   if (clauses.exists () && clauses[0].type != CPP_NAME)
20543     {
20544       error_at (DECL_SOURCE_LOCATION (fndecl),
20545 		"%<#pragma omp declare %s%> not immediately followed by "
20546 		"a single function declaration or definition", kind);
20547       clauses[0].type = CPP_EOF;
20548       return;
20549     }
20550 
20551   if (parms == NULL_TREE)
20552     parms = DECL_ARGUMENTS (fndecl);
20553 
20554   unsigned int tokens_avail = parser->tokens_avail;
20555   gcc_assert (parser->tokens == &parser->tokens_buf[0]);
20556 
20557   parser->tokens = clauses.address ();
20558   parser->tokens_avail = clauses.length ();
20559 
20560   /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end.  */
20561   while (parser->tokens_avail > 3)
20562     {
20563       c_token *token = c_parser_peek_token (parser);
20564       gcc_assert (token->type == CPP_NAME
20565 		  && strcmp (IDENTIFIER_POINTER (token->value), kind) == 0);
20566       c_parser_consume_token (parser);
20567       parser->in_pragma = true;
20568 
20569       if (strcmp (kind, "simd") == 0)
20570 	{
20571 	  tree c;
20572 	  c = c_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
20573 					"#pragma omp declare simd");
20574 	  c = c_omp_declare_simd_clauses_to_numbers (parms, c);
20575 	  if (c != NULL_TREE)
20576 	    c = tree_cons (NULL_TREE, c, NULL_TREE);
20577 	  c = build_tree_list (get_identifier ("omp declare simd"), c);
20578 	  TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl);
20579 	  DECL_ATTRIBUTES (fndecl) = c;
20580 	}
20581       else
20582 	{
20583 	  gcc_assert (strcmp (kind, "variant") == 0);
20584 	  c_finish_omp_declare_variant (parser, fndecl, parms);
20585 	}
20586     }
20587 
20588   parser->tokens = &parser->tokens_buf[0];
20589   parser->tokens_avail = tokens_avail;
20590   if (clauses.exists ())
20591     clauses[0].type = CPP_PRAGMA;
20592 }
20593 
20594 
20595 /* OpenMP 4.0:
20596    # pragma omp declare target new-line
20597    declarations and definitions
20598    # pragma omp end declare target new-line
20599 
20600    OpenMP 4.5:
20601    # pragma omp declare target ( extended-list ) new-line
20602 
20603    # pragma omp declare target declare-target-clauses[seq] new-line  */
20604 
20605 #define OMP_DECLARE_TARGET_CLAUSE_MASK				\
20606 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO)		\
20607 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)		\
20608 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
20609 
20610 static void
c_parser_omp_declare_target(c_parser * parser)20611 c_parser_omp_declare_target (c_parser *parser)
20612 {
20613   tree clauses = NULL_TREE;
20614   int device_type = 0;
20615   bool only_device_type = true;
20616   if (c_parser_next_token_is (parser, CPP_NAME))
20617     clauses = c_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
20618 					"#pragma omp declare target");
20619   else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
20620     {
20621       clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO_DECLARE,
20622 					      clauses);
20623       clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
20624       c_parser_skip_to_pragma_eol (parser);
20625     }
20626   else
20627     {
20628       c_parser_skip_to_pragma_eol (parser);
20629       current_omp_declare_target_attribute++;
20630       return;
20631     }
20632   for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
20633     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
20634       device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
20635   for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
20636     {
20637       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
20638 	continue;
20639       tree t = OMP_CLAUSE_DECL (c), id;
20640       tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
20641       tree at2 = lookup_attribute ("omp declare target link",
20642 				   DECL_ATTRIBUTES (t));
20643       only_device_type = false;
20644       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
20645 	{
20646 	  id = get_identifier ("omp declare target link");
20647 	  std::swap (at1, at2);
20648 	}
20649       else
20650 	id = get_identifier ("omp declare target");
20651       if (at2)
20652 	{
20653 	  error_at (OMP_CLAUSE_LOCATION (c),
20654 		    "%qD specified both in declare target %<link%> and %<to%>"
20655 		    " clauses", t);
20656 	  continue;
20657 	}
20658       if (!at1)
20659 	{
20660 	  DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
20661 	  if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t))
20662 	    continue;
20663 
20664 	  symtab_node *node = symtab_node::get (t);
20665 	  if (node != NULL)
20666 	    {
20667 	      node->offloadable = 1;
20668 	      if (ENABLE_OFFLOADING)
20669 		{
20670 		  g->have_offload = true;
20671 		  if (is_a <varpool_node *> (node))
20672 		    vec_safe_push (offload_vars, t);
20673 		}
20674 	    }
20675 	}
20676       if (TREE_CODE (t) != FUNCTION_DECL)
20677 	continue;
20678       if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0)
20679 	{
20680 	  tree at3 = lookup_attribute ("omp declare target host",
20681 				       DECL_ATTRIBUTES (t));
20682 	  if (at3 == NULL_TREE)
20683 	    {
20684 	      id = get_identifier ("omp declare target host");
20685 	      DECL_ATTRIBUTES (t)
20686 		= tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
20687 	    }
20688 	}
20689       if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0)
20690 	{
20691 	  tree at3 = lookup_attribute ("omp declare target nohost",
20692 				       DECL_ATTRIBUTES (t));
20693 	  if (at3 == NULL_TREE)
20694 	    {
20695 	      id = get_identifier ("omp declare target nohost");
20696 	      DECL_ATTRIBUTES (t)
20697 		= tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
20698 	    }
20699 	}
20700     }
20701   if (device_type && only_device_type)
20702     warning_at (OMP_CLAUSE_LOCATION (clauses), 0,
20703 		"directive with only %<device_type%> clauses ignored");
20704 }
20705 
20706 static void
c_parser_omp_end_declare_target(c_parser * parser)20707 c_parser_omp_end_declare_target (c_parser *parser)
20708 {
20709   location_t loc = c_parser_peek_token (parser)->location;
20710   c_parser_consume_pragma (parser);
20711   if (c_parser_next_token_is (parser, CPP_NAME)
20712       && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
20713 		 "declare") == 0)
20714     {
20715       c_parser_consume_token (parser);
20716       if (c_parser_next_token_is (parser, CPP_NAME)
20717 	  && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
20718 		     "target") == 0)
20719 	c_parser_consume_token (parser);
20720       else
20721 	{
20722 	  c_parser_error (parser, "expected %<target%>");
20723 	  c_parser_skip_to_pragma_eol (parser);
20724 	  return;
20725 	}
20726     }
20727   else
20728     {
20729       c_parser_error (parser, "expected %<declare%>");
20730       c_parser_skip_to_pragma_eol (parser);
20731       return;
20732     }
20733   c_parser_skip_to_pragma_eol (parser);
20734   if (!current_omp_declare_target_attribute)
20735     error_at (loc, "%<#pragma omp end declare target%> without corresponding "
20736 		   "%<#pragma omp declare target%>");
20737   else
20738     current_omp_declare_target_attribute--;
20739 }
20740 
20741 
20742 /* OpenMP 4.0
20743    #pragma omp declare reduction (reduction-id : typename-list : expression) \
20744       initializer-clause[opt] new-line
20745 
20746    initializer-clause:
20747       initializer (omp_priv = initializer)
20748       initializer (function-name (argument-list))  */
20749 
20750 static void
c_parser_omp_declare_reduction(c_parser * parser,enum pragma_context context)20751 c_parser_omp_declare_reduction (c_parser *parser, enum pragma_context context)
20752 {
20753   unsigned int tokens_avail = 0, i;
20754   vec<tree> types = vNULL;
20755   vec<c_token> clauses = vNULL;
20756   enum tree_code reduc_code = ERROR_MARK;
20757   tree reduc_id = NULL_TREE;
20758   tree type;
20759   location_t rloc = c_parser_peek_token (parser)->location;
20760 
20761   if (context == pragma_struct || context == pragma_param)
20762     {
20763       error ("%<#pragma omp declare reduction%> not at file or block scope");
20764       goto fail;
20765     }
20766 
20767   if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
20768     goto fail;
20769 
20770   switch (c_parser_peek_token (parser)->type)
20771     {
20772     case CPP_PLUS:
20773       reduc_code = PLUS_EXPR;
20774       break;
20775     case CPP_MULT:
20776       reduc_code = MULT_EXPR;
20777       break;
20778     case CPP_MINUS:
20779       reduc_code = MINUS_EXPR;
20780       break;
20781     case CPP_AND:
20782       reduc_code = BIT_AND_EXPR;
20783       break;
20784     case CPP_XOR:
20785       reduc_code = BIT_XOR_EXPR;
20786       break;
20787     case CPP_OR:
20788       reduc_code = BIT_IOR_EXPR;
20789       break;
20790     case CPP_AND_AND:
20791       reduc_code = TRUTH_ANDIF_EXPR;
20792       break;
20793     case CPP_OR_OR:
20794       reduc_code = TRUTH_ORIF_EXPR;
20795       break;
20796     case CPP_NAME:
20797       const char *p;
20798       p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20799       if (strcmp (p, "min") == 0)
20800 	{
20801 	  reduc_code = MIN_EXPR;
20802 	  break;
20803 	}
20804       if (strcmp (p, "max") == 0)
20805 	{
20806 	  reduc_code = MAX_EXPR;
20807 	  break;
20808 	}
20809       reduc_id = c_parser_peek_token (parser)->value;
20810       break;
20811     default:
20812       c_parser_error (parser,
20813 		      "expected %<+%>, %<*%>, %<-%>, %<&%>, "
20814 		      "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
20815       goto fail;
20816     }
20817 
20818   tree orig_reduc_id, reduc_decl;
20819   orig_reduc_id = reduc_id;
20820   reduc_id = c_omp_reduction_id (reduc_code, reduc_id);
20821   reduc_decl = c_omp_reduction_decl (reduc_id);
20822   c_parser_consume_token (parser);
20823 
20824   if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
20825     goto fail;
20826 
20827   while (true)
20828     {
20829       location_t loc = c_parser_peek_token (parser)->location;
20830       struct c_type_name *ctype = c_parser_type_name (parser);
20831       if (ctype != NULL)
20832 	{
20833 	  type = groktypename (ctype, NULL, NULL);
20834 	  if (type == error_mark_node)
20835 	    ;
20836 	  else if ((INTEGRAL_TYPE_P (type)
20837 		    || TREE_CODE (type) == REAL_TYPE
20838 		    || TREE_CODE (type) == COMPLEX_TYPE)
20839 		   && orig_reduc_id == NULL_TREE)
20840 	    error_at (loc, "predeclared arithmetic type in "
20841 			   "%<#pragma omp declare reduction%>");
20842 	  else if (TREE_CODE (type) == FUNCTION_TYPE
20843 		   || TREE_CODE (type) == ARRAY_TYPE)
20844 	    error_at (loc, "function or array type in "
20845 		      "%<#pragma omp declare reduction%>");
20846 	  else if (TYPE_ATOMIC (type))
20847 	    error_at (loc, "%<_Atomic%> qualified type in "
20848 			   "%<#pragma omp declare reduction%>");
20849 	  else if (TYPE_QUALS_NO_ADDR_SPACE (type))
20850 	    error_at (loc, "const, volatile or restrict qualified type in "
20851 			   "%<#pragma omp declare reduction%>");
20852 	  else
20853 	    {
20854 	      tree t;
20855 	      for (t = DECL_INITIAL (reduc_decl); t; t = TREE_CHAIN (t))
20856 		if (comptypes (TREE_PURPOSE (t), type))
20857 		  {
20858 		    error_at (loc, "redeclaration of %qs "
20859 				   "%<#pragma omp declare reduction%> for "
20860 				   "type %qT",
20861 				   IDENTIFIER_POINTER (reduc_id)
20862 				   + sizeof ("omp declare reduction ") - 1,
20863 				   type);
20864 		    location_t ploc
20865 		      = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t),
20866 							    0));
20867 		    error_at (ploc, "previous %<#pragma omp declare "
20868 				    "reduction%>");
20869 		    break;
20870 		  }
20871 	      if (t == NULL_TREE)
20872 		types.safe_push (type);
20873 	    }
20874 	  if (c_parser_next_token_is (parser, CPP_COMMA))
20875 	    c_parser_consume_token (parser);
20876 	  else
20877 	    break;
20878 	}
20879       else
20880 	break;
20881     }
20882 
20883   if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")
20884       || types.is_empty ())
20885     {
20886      fail:
20887       clauses.release ();
20888       types.release ();
20889       while (true)
20890 	{
20891 	  c_token *token = c_parser_peek_token (parser);
20892 	  if (token->type == CPP_EOF || token->type == CPP_PRAGMA_EOL)
20893 	    break;
20894 	  c_parser_consume_token (parser);
20895 	}
20896       c_parser_skip_to_pragma_eol (parser);
20897       return;
20898     }
20899 
20900   if (types.length () > 1)
20901     {
20902       while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
20903 	{
20904 	  c_token *token = c_parser_peek_token (parser);
20905 	  if (token->type == CPP_EOF)
20906 	    goto fail;
20907 	  clauses.safe_push (*token);
20908 	  c_parser_consume_token (parser);
20909 	}
20910       clauses.safe_push (*c_parser_peek_token (parser));
20911       c_parser_skip_to_pragma_eol (parser);
20912 
20913       /* Make sure nothing tries to read past the end of the tokens.  */
20914       c_token eof_token;
20915       memset (&eof_token, 0, sizeof (eof_token));
20916       eof_token.type = CPP_EOF;
20917       clauses.safe_push (eof_token);
20918       clauses.safe_push (eof_token);
20919     }
20920 
20921   int errs = errorcount;
20922   FOR_EACH_VEC_ELT (types, i, type)
20923     {
20924       tokens_avail = parser->tokens_avail;
20925       gcc_assert (parser->tokens == &parser->tokens_buf[0]);
20926       if (!clauses.is_empty ())
20927 	{
20928 	  parser->tokens = clauses.address ();
20929 	  parser->tokens_avail = clauses.length ();
20930 	  parser->in_pragma = true;
20931 	}
20932 
20933       bool nested = current_function_decl != NULL_TREE;
20934       if (nested)
20935 	c_push_function_context ();
20936       tree fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
20937 				reduc_id, default_function_type);
20938       current_function_decl = fndecl;
20939       allocate_struct_function (fndecl, true);
20940       push_scope ();
20941       tree stmt = push_stmt_list ();
20942       /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
20943 	 warn about these.  */
20944       tree omp_out = build_decl (BUILTINS_LOCATION, VAR_DECL,
20945 				 get_identifier ("omp_out"), type);
20946       DECL_ARTIFICIAL (omp_out) = 1;
20947       DECL_CONTEXT (omp_out) = fndecl;
20948       pushdecl (omp_out);
20949       tree omp_in = build_decl (BUILTINS_LOCATION, VAR_DECL,
20950 				get_identifier ("omp_in"), type);
20951       DECL_ARTIFICIAL (omp_in) = 1;
20952       DECL_CONTEXT (omp_in) = fndecl;
20953       pushdecl (omp_in);
20954       struct c_expr combiner = c_parser_expression (parser);
20955       struct c_expr initializer;
20956       tree omp_priv = NULL_TREE, omp_orig = NULL_TREE;
20957       bool bad = false;
20958       initializer.set_error ();
20959       if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
20960 	bad = true;
20961       else if (c_parser_next_token_is (parser, CPP_NAME)
20962 	       && strcmp (IDENTIFIER_POINTER
20963 				(c_parser_peek_token (parser)->value),
20964 			  "initializer") == 0)
20965 	{
20966 	  c_parser_consume_token (parser);
20967 	  pop_scope ();
20968 	  push_scope ();
20969 	  omp_priv = build_decl (BUILTINS_LOCATION, VAR_DECL,
20970 				 get_identifier ("omp_priv"), type);
20971 	  DECL_ARTIFICIAL (omp_priv) = 1;
20972 	  DECL_INITIAL (omp_priv) = error_mark_node;
20973 	  DECL_CONTEXT (omp_priv) = fndecl;
20974 	  pushdecl (omp_priv);
20975 	  omp_orig = build_decl (BUILTINS_LOCATION, VAR_DECL,
20976 				 get_identifier ("omp_orig"), type);
20977 	  DECL_ARTIFICIAL (omp_orig) = 1;
20978 	  DECL_CONTEXT (omp_orig) = fndecl;
20979 	  pushdecl (omp_orig);
20980 	  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
20981 	    bad = true;
20982 	  else if (!c_parser_next_token_is (parser, CPP_NAME))
20983 	    {
20984 	      c_parser_error (parser, "expected %<omp_priv%> or "
20985 				      "function-name");
20986 	      bad = true;
20987 	    }
20988 	  else if (strcmp (IDENTIFIER_POINTER
20989 				(c_parser_peek_token (parser)->value),
20990 			   "omp_priv") != 0)
20991 	    {
20992 	      if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
20993 		  || c_parser_peek_token (parser)->id_kind != C_ID_ID)
20994 		{
20995 		  c_parser_error (parser, "expected function-name %<(%>");
20996 		  bad = true;
20997 		}
20998 	      else
20999 		initializer = c_parser_postfix_expression (parser);
21000 	      if (initializer.value
21001 		  && TREE_CODE (initializer.value) == CALL_EXPR)
21002 		{
21003 		  int j;
21004 		  tree c = initializer.value;
21005 		  for (j = 0; j < call_expr_nargs (c); j++)
21006 		    {
21007 		      tree a = CALL_EXPR_ARG (c, j);
21008 		      STRIP_NOPS (a);
21009 		      if (TREE_CODE (a) == ADDR_EXPR
21010 			  && TREE_OPERAND (a, 0) == omp_priv)
21011 			break;
21012 		    }
21013 		  if (j == call_expr_nargs (c))
21014 		    error ("one of the initializer call arguments should be "
21015 			   "%<&omp_priv%>");
21016 		}
21017 	    }
21018 	  else
21019 	    {
21020 	      c_parser_consume_token (parser);
21021 	      if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
21022 		bad = true;
21023 	      else
21024 		{
21025 		  tree st = push_stmt_list ();
21026 		  location_t loc = c_parser_peek_token (parser)->location;
21027 		  rich_location richloc (line_table, loc);
21028 		  start_init (omp_priv, NULL_TREE, 0, &richloc);
21029 		  struct c_expr init = c_parser_initializer (parser);
21030 		  finish_init ();
21031 		  finish_decl (omp_priv, loc, init.value,
21032 		      	       init.original_type, NULL_TREE);
21033 		  pop_stmt_list (st);
21034 		}
21035 	    }
21036 	  if (!bad
21037 	      && !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
21038 	    bad = true;
21039 	}
21040 
21041       if (!bad)
21042 	{
21043 	  c_parser_skip_to_pragma_eol (parser);
21044 
21045 	  tree t = tree_cons (type, make_tree_vec (omp_priv ? 6 : 3),
21046 			      DECL_INITIAL (reduc_decl));
21047 	  DECL_INITIAL (reduc_decl) = t;
21048 	  DECL_SOURCE_LOCATION (omp_out) = rloc;
21049 	  TREE_VEC_ELT (TREE_VALUE (t), 0) = omp_out;
21050 	  TREE_VEC_ELT (TREE_VALUE (t), 1) = omp_in;
21051 	  TREE_VEC_ELT (TREE_VALUE (t), 2) = combiner.value;
21052 	  walk_tree (&combiner.value, c_check_omp_declare_reduction_r,
21053 		     &TREE_VEC_ELT (TREE_VALUE (t), 0), NULL);
21054 	  if (omp_priv)
21055 	    {
21056 	      DECL_SOURCE_LOCATION (omp_priv) = rloc;
21057 	      TREE_VEC_ELT (TREE_VALUE (t), 3) = omp_priv;
21058 	      TREE_VEC_ELT (TREE_VALUE (t), 4) = omp_orig;
21059 	      TREE_VEC_ELT (TREE_VALUE (t), 5) = initializer.value;
21060 	      walk_tree (&initializer.value, c_check_omp_declare_reduction_r,
21061 			 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
21062 	      walk_tree (&DECL_INITIAL (omp_priv),
21063 			 c_check_omp_declare_reduction_r,
21064 			 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
21065 	    }
21066 	}
21067 
21068       pop_stmt_list (stmt);
21069       pop_scope ();
21070       if (cfun->language != NULL)
21071 	{
21072 	  ggc_free (cfun->language);
21073 	  cfun->language = NULL;
21074 	}
21075       set_cfun (NULL);
21076       current_function_decl = NULL_TREE;
21077       if (nested)
21078 	c_pop_function_context ();
21079 
21080       if (!clauses.is_empty ())
21081 	{
21082 	  parser->tokens = &parser->tokens_buf[0];
21083 	  parser->tokens_avail = tokens_avail;
21084 	}
21085       if (bad)
21086 	goto fail;
21087       if (errs != errorcount)
21088 	break;
21089     }
21090 
21091   clauses.release ();
21092   types.release ();
21093 }
21094 
21095 
21096 /* OpenMP 4.0
21097    #pragma omp declare simd declare-simd-clauses[optseq] new-line
21098    #pragma omp declare reduction (reduction-id : typename-list : expression) \
21099       initializer-clause[opt] new-line
21100    #pragma omp declare target new-line
21101 
21102    OpenMP 5.0
21103    #pragma omp declare variant (identifier) match (context-selector)  */
21104 
21105 static void
c_parser_omp_declare(c_parser * parser,enum pragma_context context)21106 c_parser_omp_declare (c_parser *parser, enum pragma_context context)
21107 {
21108   c_parser_consume_pragma (parser);
21109   if (c_parser_next_token_is (parser, CPP_NAME))
21110     {
21111       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21112       if (strcmp (p, "simd") == 0)
21113 	{
21114 	  /* c_parser_consume_token (parser); done in
21115 	     c_parser_omp_declare_simd.  */
21116 	  c_parser_omp_declare_simd (parser, context);
21117 	  return;
21118 	}
21119       if (strcmp (p, "reduction") == 0)
21120 	{
21121 	  c_parser_consume_token (parser);
21122 	  c_parser_omp_declare_reduction (parser, context);
21123 	  return;
21124 	}
21125       if (!flag_openmp)  /* flag_openmp_simd  */
21126 	{
21127 	  c_parser_skip_to_pragma_eol (parser, false);
21128 	  return;
21129 	}
21130       if (strcmp (p, "target") == 0)
21131 	{
21132 	  c_parser_consume_token (parser);
21133 	  c_parser_omp_declare_target (parser);
21134 	  return;
21135 	}
21136       if (strcmp (p, "variant") == 0)
21137 	{
21138 	  /* c_parser_consume_token (parser); done in
21139 	     c_parser_omp_declare_simd.  */
21140 	  c_parser_omp_declare_simd (parser, context);
21141 	  return;
21142 	}
21143     }
21144 
21145   c_parser_error (parser, "expected %<simd%>, %<reduction%>, "
21146 			  "%<target%> or %<variant%>");
21147   c_parser_skip_to_pragma_eol (parser);
21148 }
21149 
21150 /* OpenMP 5.0
21151    #pragma omp requires clauses[optseq] new-line  */
21152 
21153 static void
c_parser_omp_requires(c_parser * parser)21154 c_parser_omp_requires (c_parser *parser)
21155 {
21156   bool first = true;
21157   enum omp_requires new_req = (enum omp_requires) 0;
21158 
21159   c_parser_consume_pragma (parser);
21160 
21161   location_t loc = c_parser_peek_token (parser)->location;
21162   while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
21163     {
21164       if (!first && c_parser_next_token_is (parser, CPP_COMMA))
21165 	c_parser_consume_token (parser);
21166 
21167       first = false;
21168 
21169       if (c_parser_next_token_is (parser, CPP_NAME))
21170 	{
21171 	  const char *p
21172 	    = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21173 	  location_t cloc = c_parser_peek_token (parser)->location;
21174 	  enum omp_requires this_req = (enum omp_requires) 0;
21175 
21176 	  if (!strcmp (p, "unified_address"))
21177 	    this_req = OMP_REQUIRES_UNIFIED_ADDRESS;
21178 	  else if (!strcmp (p, "unified_shared_memory"))
21179 	    this_req = OMP_REQUIRES_UNIFIED_SHARED_MEMORY;
21180 	  else if (!strcmp (p, "dynamic_allocators"))
21181 	    this_req = OMP_REQUIRES_DYNAMIC_ALLOCATORS;
21182 	  else if (!strcmp (p, "reverse_offload"))
21183 	    this_req = OMP_REQUIRES_REVERSE_OFFLOAD;
21184 	  else if (!strcmp (p, "atomic_default_mem_order"))
21185 	    {
21186 	      c_parser_consume_token (parser);
21187 
21188 	      matching_parens parens;
21189 	      if (parens.require_open (parser))
21190 		{
21191 		  if (c_parser_next_token_is (parser, CPP_NAME))
21192 		    {
21193 		      tree v = c_parser_peek_token (parser)->value;
21194 		      p = IDENTIFIER_POINTER (v);
21195 
21196 		      if (!strcmp (p, "seq_cst"))
21197 			this_req
21198 			  = (enum omp_requires) OMP_MEMORY_ORDER_SEQ_CST;
21199 		      else if (!strcmp (p, "relaxed"))
21200 			this_req
21201 			  = (enum omp_requires) OMP_MEMORY_ORDER_RELAXED;
21202 		      else if (!strcmp (p, "acq_rel"))
21203 			this_req
21204 			  = (enum omp_requires) OMP_MEMORY_ORDER_ACQ_REL;
21205 		    }
21206 		  if (this_req == 0)
21207 		    {
21208 		      error_at (c_parser_peek_token (parser)->location,
21209 				"expected %<seq_cst%>, %<relaxed%> or "
21210 				"%<acq_rel%>");
21211 		      if (c_parser_peek_2nd_token (parser)->type
21212 			  == CPP_CLOSE_PAREN)
21213 			c_parser_consume_token (parser);
21214 		    }
21215 		  else
21216 		    c_parser_consume_token (parser);
21217 
21218 		  parens.skip_until_found_close (parser);
21219 		  if (this_req == 0)
21220 		    {
21221 		      c_parser_skip_to_pragma_eol (parser, false);
21222 		      return;
21223 		    }
21224 		}
21225 	      p = NULL;
21226 	    }
21227 	  else
21228 	    {
21229 	      error_at (cloc, "expected %<unified_address%>, "
21230 			      "%<unified_shared_memory%>, "
21231 			      "%<dynamic_allocators%>, "
21232 			       "%<reverse_offload%> "
21233 			       "or %<atomic_default_mem_order%> clause");
21234 	      c_parser_skip_to_pragma_eol (parser, false);
21235 	      return;
21236 	    }
21237 	  if (p)
21238 	    sorry_at (cloc, "%qs clause on %<requires%> directive not "
21239 			    "supported yet", p);
21240 	  if (p)
21241 	    c_parser_consume_token (parser);
21242 	  if (this_req)
21243 	    {
21244 	      if ((this_req & ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
21245 		{
21246 		  if ((this_req & new_req) != 0)
21247 		    error_at (cloc, "too many %qs clauses", p);
21248 		  if (this_req != OMP_REQUIRES_DYNAMIC_ALLOCATORS
21249 		      && (omp_requires_mask & OMP_REQUIRES_TARGET_USED) != 0)
21250 		    error_at (cloc, "%qs clause used lexically after first "
21251 				    "target construct or offloading API", p);
21252 		}
21253 	      else if ((new_req & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
21254 		{
21255 		  error_at (cloc, "too many %qs clauses",
21256 			    "atomic_default_mem_order");
21257 		  this_req = (enum omp_requires) 0;
21258 		}
21259 	      else if ((omp_requires_mask
21260 			& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
21261 		{
21262 		  error_at (cloc, "more than one %<atomic_default_mem_order%>"
21263 				  " clause in a single compilation unit");
21264 		  this_req
21265 		    = (enum omp_requires)
21266 		       (omp_requires_mask
21267 			& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER);
21268 		}
21269 	      else if ((omp_requires_mask
21270 			& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED) != 0)
21271 		error_at (cloc, "%<atomic_default_mem_order%> clause used "
21272 				"lexically after first %<atomic%> construct "
21273 				"without memory order clause");
21274 	      new_req = (enum omp_requires) (new_req | this_req);
21275 	      omp_requires_mask
21276 		= (enum omp_requires) (omp_requires_mask | this_req);
21277 	      continue;
21278 	    }
21279 	}
21280       break;
21281     }
21282   c_parser_skip_to_pragma_eol (parser);
21283 
21284   if (new_req == 0)
21285     error_at (loc, "%<pragma omp requires%> requires at least one clause");
21286 }
21287 
21288 /* Helper function for c_parser_omp_taskloop.
21289    Disallow zero sized or potentially zero sized task reductions.  */
21290 
21291 static tree
c_finish_taskloop_clauses(tree clauses)21292 c_finish_taskloop_clauses (tree clauses)
21293 {
21294   tree *pc = &clauses;
21295   for (tree c = clauses; c; c = *pc)
21296     {
21297       bool remove = false;
21298       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
21299 	{
21300 	  tree type = strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c)));
21301 	  if (integer_zerop (TYPE_SIZE_UNIT (type)))
21302 	    {
21303 	      error_at (OMP_CLAUSE_LOCATION (c),
21304 			"zero sized type %qT in %<reduction%> clause", type);
21305 	      remove = true;
21306 	    }
21307 	  else if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
21308 	    {
21309 	      error_at (OMP_CLAUSE_LOCATION (c),
21310 			"variable sized type %qT in %<reduction%> clause",
21311 			type);
21312 	      remove = true;
21313 	    }
21314 	}
21315       if (remove)
21316 	*pc = OMP_CLAUSE_CHAIN (c);
21317       else
21318 	pc = &OMP_CLAUSE_CHAIN (c);
21319     }
21320   return clauses;
21321 }
21322 
21323 /* OpenMP 4.5:
21324    #pragma omp taskloop taskloop-clause[optseq] new-line
21325      for-loop
21326 
21327    #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
21328      for-loop  */
21329 
21330 #define OMP_TASKLOOP_CLAUSE_MASK				\
21331 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED)	\
21332 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
21333 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
21334 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)	\
21335 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT)	\
21336 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE)	\
21337 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS)	\
21338 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)	\
21339 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED)	\
21340 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
21341 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL)	\
21342 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE)	\
21343 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP)	\
21344 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY)	\
21345 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)	\
21346 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
21347 
21348 static tree
c_parser_omp_taskloop(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)21349 c_parser_omp_taskloop (location_t loc, c_parser *parser,
21350 		       char *p_name, omp_clause_mask mask, tree *cclauses,
21351 		       bool *if_p)
21352 {
21353   tree clauses, block, ret;
21354 
21355   strcat (p_name, " taskloop");
21356   mask |= OMP_TASKLOOP_CLAUSE_MASK;
21357   /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
21358      clause.  */
21359   if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
21360     mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION);
21361 
21362   if (c_parser_next_token_is (parser, CPP_NAME))
21363     {
21364       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21365 
21366       if (strcmp (p, "simd") == 0)
21367 	{
21368 	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
21369 	  if (cclauses == NULL)
21370 	    cclauses = cclauses_buf;
21371 	  c_parser_consume_token (parser);
21372 	  if (!flag_openmp)  /* flag_openmp_simd  */
21373 	    return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
21374 				      if_p);
21375 	  block = c_begin_compound_stmt (true);
21376 	  ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
21377 	  block = c_end_compound_stmt (loc, block, true);
21378 	  if (ret == NULL)
21379 	    return ret;
21380 	  ret = make_node (OMP_TASKLOOP);
21381 	  TREE_TYPE (ret) = void_type_node;
21382 	  OMP_FOR_BODY (ret) = block;
21383 	  OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
21384 	  OMP_FOR_CLAUSES (ret)
21385 	    = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret));
21386 	  SET_EXPR_LOCATION (ret, loc);
21387 	  add_stmt (ret);
21388 	  return ret;
21389 	}
21390     }
21391   if (!flag_openmp)  /* flag_openmp_simd  */
21392     {
21393       c_parser_skip_to_pragma_eol (parser, false);
21394       return NULL_TREE;
21395     }
21396 
21397   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
21398   if (cclauses)
21399     {
21400       omp_split_clauses (loc, OMP_TASKLOOP, mask, clauses, cclauses);
21401       clauses = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
21402     }
21403 
21404   clauses = c_finish_taskloop_clauses (clauses);
21405   block = c_begin_compound_stmt (true);
21406   ret = c_parser_omp_for_loop (loc, parser, OMP_TASKLOOP, clauses, NULL, if_p);
21407   block = c_end_compound_stmt (loc, block, true);
21408   add_stmt (block);
21409 
21410   return ret;
21411 }
21412 
21413 /* Main entry point to parsing most OpenMP pragmas.  */
21414 
21415 static void
c_parser_omp_construct(c_parser * parser,bool * if_p)21416 c_parser_omp_construct (c_parser *parser, bool *if_p)
21417 {
21418   enum pragma_kind p_kind;
21419   location_t loc;
21420   tree stmt;
21421   char p_name[sizeof "#pragma omp teams distribute parallel for simd"];
21422   omp_clause_mask mask (0);
21423 
21424   loc = c_parser_peek_token (parser)->location;
21425   p_kind = c_parser_peek_token (parser)->pragma_kind;
21426   c_parser_consume_pragma (parser);
21427 
21428   switch (p_kind)
21429     {
21430     case PRAGMA_OACC_ATOMIC:
21431       c_parser_omp_atomic (loc, parser);
21432       return;
21433     case PRAGMA_OACC_CACHE:
21434       strcpy (p_name, "#pragma acc");
21435       stmt = c_parser_oacc_cache (loc, parser);
21436       break;
21437     case PRAGMA_OACC_DATA:
21438       stmt = c_parser_oacc_data (loc, parser, if_p);
21439       break;
21440     case PRAGMA_OACC_HOST_DATA:
21441       stmt = c_parser_oacc_host_data (loc, parser, if_p);
21442       break;
21443     case PRAGMA_OACC_KERNELS:
21444     case PRAGMA_OACC_PARALLEL:
21445     case PRAGMA_OACC_SERIAL:
21446       strcpy (p_name, "#pragma acc");
21447       stmt = c_parser_oacc_compute (loc, parser, p_kind, p_name, if_p);
21448       break;
21449     case PRAGMA_OACC_LOOP:
21450       strcpy (p_name, "#pragma acc");
21451       stmt = c_parser_oacc_loop (loc, parser, p_name, mask, NULL, if_p);
21452       break;
21453     case PRAGMA_OACC_WAIT:
21454       strcpy (p_name, "#pragma wait");
21455       stmt = c_parser_oacc_wait (loc, parser, p_name);
21456       break;
21457     case PRAGMA_OMP_ATOMIC:
21458       c_parser_omp_atomic (loc, parser);
21459       return;
21460     case PRAGMA_OMP_CRITICAL:
21461       stmt = c_parser_omp_critical (loc, parser, if_p);
21462       break;
21463     case PRAGMA_OMP_DISTRIBUTE:
21464       strcpy (p_name, "#pragma omp");
21465       stmt = c_parser_omp_distribute (loc, parser, p_name, mask, NULL, if_p);
21466       break;
21467     case PRAGMA_OMP_FOR:
21468       strcpy (p_name, "#pragma omp");
21469       stmt = c_parser_omp_for (loc, parser, p_name, mask, NULL, if_p);
21470       break;
21471     case PRAGMA_OMP_LOOP:
21472       strcpy (p_name, "#pragma omp");
21473       stmt = c_parser_omp_loop (loc, parser, p_name, mask, NULL, if_p);
21474       break;
21475     case PRAGMA_OMP_MASTER:
21476       strcpy (p_name, "#pragma omp");
21477       stmt = c_parser_omp_master (loc, parser, p_name, mask, NULL, if_p);
21478       break;
21479     case PRAGMA_OMP_PARALLEL:
21480       strcpy (p_name, "#pragma omp");
21481       stmt = c_parser_omp_parallel (loc, parser, p_name, mask, NULL, if_p);
21482       break;
21483     case PRAGMA_OMP_SECTIONS:
21484       strcpy (p_name, "#pragma omp");
21485       stmt = c_parser_omp_sections (loc, parser, p_name, mask, NULL);
21486       break;
21487     case PRAGMA_OMP_SIMD:
21488       strcpy (p_name, "#pragma omp");
21489       stmt = c_parser_omp_simd (loc, parser, p_name, mask, NULL, if_p);
21490       break;
21491     case PRAGMA_OMP_SINGLE:
21492       stmt = c_parser_omp_single (loc, parser, if_p);
21493       break;
21494     case PRAGMA_OMP_TASK:
21495       stmt = c_parser_omp_task (loc, parser, if_p);
21496       break;
21497     case PRAGMA_OMP_TASKGROUP:
21498       stmt = c_parser_omp_taskgroup (loc, parser, if_p);
21499       break;
21500     case PRAGMA_OMP_TASKLOOP:
21501       strcpy (p_name, "#pragma omp");
21502       stmt = c_parser_omp_taskloop (loc, parser, p_name, mask, NULL, if_p);
21503       break;
21504     case PRAGMA_OMP_TEAMS:
21505       strcpy (p_name, "#pragma omp");
21506       stmt = c_parser_omp_teams (loc, parser, p_name, mask, NULL, if_p);
21507       break;
21508     default:
21509       gcc_unreachable ();
21510     }
21511 
21512   if (stmt)
21513     gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION);
21514 }
21515 
21516 
21517 /* OpenMP 2.5:
21518    # pragma omp threadprivate (variable-list) */
21519 
21520 static void
c_parser_omp_threadprivate(c_parser * parser)21521 c_parser_omp_threadprivate (c_parser *parser)
21522 {
21523   tree vars, t;
21524   location_t loc;
21525 
21526   c_parser_consume_pragma (parser);
21527   loc = c_parser_peek_token (parser)->location;
21528   vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
21529 
21530   /* Mark every variable in VARS to be assigned thread local storage.  */
21531   for (t = vars; t; t = TREE_CHAIN (t))
21532     {
21533       tree v = TREE_PURPOSE (t);
21534 
21535       /* FIXME diagnostics: Ideally we should keep individual
21536 	 locations for all the variables in the var list to make the
21537 	 following errors more precise.  Perhaps
21538 	 c_parser_omp_var_list_parens() should construct a list of
21539 	 locations to go along with the var list.  */
21540 
21541       /* If V had already been marked threadprivate, it doesn't matter
21542 	 whether it had been used prior to this point.  */
21543       if (!VAR_P (v))
21544 	error_at (loc, "%qD is not a variable", v);
21545       else if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v))
21546 	error_at (loc, "%qE declared %<threadprivate%> after first use", v);
21547       else if (! is_global_var (v))
21548 	error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v);
21549       else if (TREE_TYPE (v) == error_mark_node)
21550 	;
21551       else if (! COMPLETE_TYPE_P (TREE_TYPE (v)))
21552 	error_at (loc, "%<threadprivate%> %qE has incomplete type", v);
21553       else
21554 	{
21555 	  if (! DECL_THREAD_LOCAL_P (v))
21556 	    {
21557 	      set_decl_tls_model (v, decl_default_tls_model (v));
21558 	      /* If rtl has been already set for this var, call
21559 		 make_decl_rtl once again, so that encode_section_info
21560 		 has a chance to look at the new decl flags.  */
21561 	      if (DECL_RTL_SET_P (v))
21562 		make_decl_rtl (v);
21563 	    }
21564 	  C_DECL_THREADPRIVATE_P (v) = 1;
21565 	}
21566     }
21567 
21568   c_parser_skip_to_pragma_eol (parser);
21569 }
21570 
21571 /* Parse a transaction attribute (GCC Extension).
21572 
21573    transaction-attribute:
21574      gnu-attributes
21575      attribute-specifier
21576 */
21577 
21578 static tree
c_parser_transaction_attributes(c_parser * parser)21579 c_parser_transaction_attributes (c_parser *parser)
21580 {
21581   if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
21582     return c_parser_gnu_attributes (parser);
21583 
21584   if (!c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
21585     return NULL_TREE;
21586   return c_parser_std_attribute_specifier (parser, true);
21587 }
21588 
21589 /* Parse a __transaction_atomic or __transaction_relaxed statement
21590    (GCC Extension).
21591 
21592    transaction-statement:
21593      __transaction_atomic transaction-attribute[opt] compound-statement
21594      __transaction_relaxed compound-statement
21595 
21596    Note that the only valid attribute is: "outer".
21597 */
21598 
21599 static tree
c_parser_transaction(c_parser * parser,enum rid keyword)21600 c_parser_transaction (c_parser *parser, enum rid keyword)
21601 {
21602   unsigned int old_in = parser->in_transaction;
21603   unsigned int this_in = 1, new_in;
21604   location_t loc = c_parser_peek_token (parser)->location;
21605   tree stmt, attrs;
21606 
21607   gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
21608       || keyword == RID_TRANSACTION_RELAXED)
21609       && c_parser_next_token_is_keyword (parser, keyword));
21610   c_parser_consume_token (parser);
21611 
21612   if (keyword == RID_TRANSACTION_RELAXED)
21613     this_in |= TM_STMT_ATTR_RELAXED;
21614   else
21615     {
21616       attrs = c_parser_transaction_attributes (parser);
21617       if (attrs)
21618 	this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
21619     }
21620 
21621   /* Keep track if we're in the lexical scope of an outer transaction.  */
21622   new_in = this_in | (old_in & TM_STMT_ATTR_OUTER);
21623 
21624   parser->in_transaction = new_in;
21625   stmt = c_parser_compound_statement (parser);
21626   parser->in_transaction = old_in;
21627 
21628   if (flag_tm)
21629     stmt = c_finish_transaction (loc, stmt, this_in);
21630   else
21631     error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
21632 	"%<__transaction_atomic%> without transactional memory support enabled"
21633 	: "%<__transaction_relaxed %> "
21634 	"without transactional memory support enabled"));
21635 
21636   return stmt;
21637 }
21638 
21639 /* Parse a __transaction_atomic or __transaction_relaxed expression
21640    (GCC Extension).
21641 
21642    transaction-expression:
21643      __transaction_atomic ( expression )
21644      __transaction_relaxed ( expression )
21645 */
21646 
21647 static struct c_expr
c_parser_transaction_expression(c_parser * parser,enum rid keyword)21648 c_parser_transaction_expression (c_parser *parser, enum rid keyword)
21649 {
21650   struct c_expr ret;
21651   unsigned int old_in = parser->in_transaction;
21652   unsigned int this_in = 1;
21653   location_t loc = c_parser_peek_token (parser)->location;
21654   tree attrs;
21655 
21656   gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
21657       || keyword == RID_TRANSACTION_RELAXED)
21658       && c_parser_next_token_is_keyword (parser, keyword));
21659   c_parser_consume_token (parser);
21660 
21661   if (keyword == RID_TRANSACTION_RELAXED)
21662     this_in |= TM_STMT_ATTR_RELAXED;
21663   else
21664     {
21665       attrs = c_parser_transaction_attributes (parser);
21666       if (attrs)
21667 	this_in |= parse_tm_stmt_attr (attrs, 0);
21668     }
21669 
21670   parser->in_transaction = this_in;
21671   matching_parens parens;
21672   if (parens.require_open (parser))
21673     {
21674       tree expr = c_parser_expression (parser).value;
21675       ret.original_type = TREE_TYPE (expr);
21676       ret.value = build1 (TRANSACTION_EXPR, ret.original_type, expr);
21677       if (this_in & TM_STMT_ATTR_RELAXED)
21678 	TRANSACTION_EXPR_RELAXED (ret.value) = 1;
21679       SET_EXPR_LOCATION (ret.value, loc);
21680       ret.original_code = TRANSACTION_EXPR;
21681       if (!parens.require_close (parser))
21682 	{
21683 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
21684 	  goto error;
21685 	}
21686     }
21687   else
21688     {
21689      error:
21690       ret.set_error ();
21691       ret.original_code = ERROR_MARK;
21692       ret.original_type = NULL;
21693     }
21694   parser->in_transaction = old_in;
21695 
21696   if (!flag_tm)
21697     error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
21698 	"%<__transaction_atomic%> without transactional memory support enabled"
21699 	: "%<__transaction_relaxed %> "
21700 	"without transactional memory support enabled"));
21701 
21702   set_c_expr_source_range (&ret, loc, loc);
21703 
21704   return ret;
21705 }
21706 
21707 /* Parse a __transaction_cancel statement (GCC Extension).
21708 
21709    transaction-cancel-statement:
21710      __transaction_cancel transaction-attribute[opt] ;
21711 
21712    Note that the only valid attribute is "outer".
21713 */
21714 
21715 static tree
c_parser_transaction_cancel(c_parser * parser)21716 c_parser_transaction_cancel (c_parser *parser)
21717 {
21718   location_t loc = c_parser_peek_token (parser)->location;
21719   tree attrs;
21720   bool is_outer = false;
21721 
21722   gcc_assert (c_parser_next_token_is_keyword (parser, RID_TRANSACTION_CANCEL));
21723   c_parser_consume_token (parser);
21724 
21725   attrs = c_parser_transaction_attributes (parser);
21726   if (attrs)
21727     is_outer = (parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER) != 0);
21728 
21729   if (!flag_tm)
21730     {
21731       error_at (loc, "%<__transaction_cancel%> without "
21732 		"transactional memory support enabled");
21733       goto ret_error;
21734     }
21735   else if (parser->in_transaction & TM_STMT_ATTR_RELAXED)
21736     {
21737       error_at (loc, "%<__transaction_cancel%> within a "
21738 		"%<__transaction_relaxed%>");
21739       goto ret_error;
21740     }
21741   else if (is_outer)
21742     {
21743       if ((parser->in_transaction & TM_STMT_ATTR_OUTER) == 0
21744 	  && !is_tm_may_cancel_outer (current_function_decl))
21745 	{
21746 	  error_at (loc, "outer %<__transaction_cancel%> not "
21747 		    "within outer %<__transaction_atomic%> or "
21748 		    "a %<transaction_may_cancel_outer%> function");
21749 	  goto ret_error;
21750 	}
21751     }
21752   else if (parser->in_transaction == 0)
21753     {
21754       error_at (loc, "%<__transaction_cancel%> not within "
21755 		"%<__transaction_atomic%>");
21756       goto ret_error;
21757     }
21758 
21759   return add_stmt (build_tm_abort_call (loc, is_outer));
21760 
21761  ret_error:
21762   return build1 (NOP_EXPR, void_type_node, error_mark_node);
21763 }
21764 
21765 /* Parse a single source file.  */
21766 
21767 void
c_parse_file(void)21768 c_parse_file (void)
21769 {
21770   /* Use local storage to begin.  If the first token is a pragma, parse it.
21771      If it is #pragma GCC pch_preprocess, then this will load a PCH file
21772      which will cause garbage collection.  */
21773   c_parser tparser;
21774 
21775   memset (&tparser, 0, sizeof tparser);
21776   tparser.translate_strings_p = true;
21777   tparser.tokens = &tparser.tokens_buf[0];
21778   the_parser = &tparser;
21779 
21780   if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS)
21781     c_parser_pragma_pch_preprocess (&tparser);
21782   else
21783     c_common_no_more_pch ();
21784 
21785   the_parser = ggc_alloc<c_parser> ();
21786   *the_parser = tparser;
21787   if (tparser.tokens == &tparser.tokens_buf[0])
21788     the_parser->tokens = &the_parser->tokens_buf[0];
21789 
21790   /* Initialize EH, if we've been told to do so.  */
21791   if (flag_exceptions)
21792     using_eh_for_cleanups ();
21793 
21794   c_parser_translation_unit (the_parser);
21795   the_parser = NULL;
21796 }
21797 
21798 /* Parse the body of a function declaration marked with "__RTL".
21799 
21800    The RTL parser works on the level of characters read from a
21801    FILE *, whereas c_parser works at the level of tokens.
21802    Square this circle by consuming all of the tokens up to and
21803    including the closing brace, recording the start/end of the RTL
21804    fragment, and reopening the file and re-reading the relevant
21805    lines within the RTL parser.
21806 
21807    This requires the opening and closing braces of the C function
21808    to be on separate lines from the RTL they wrap.
21809 
21810    Take ownership of START_WITH_PASS, if non-NULL.  */
21811 
21812 location_t
c_parser_parse_rtl_body(c_parser * parser,char * start_with_pass)21813 c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass)
21814 {
21815   if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
21816     {
21817       free (start_with_pass);
21818       return c_parser_peek_token (parser)->location;
21819     }
21820 
21821   location_t start_loc = c_parser_peek_token (parser)->location;
21822 
21823   /* Consume all tokens, up to the closing brace, handling
21824      matching pairs of braces in the rtl dump.  */
21825   int num_open_braces = 1;
21826   while (1)
21827     {
21828       switch (c_parser_peek_token (parser)->type)
21829 	{
21830 	case CPP_OPEN_BRACE:
21831 	  num_open_braces++;
21832 	  break;
21833 	case CPP_CLOSE_BRACE:
21834 	  if (--num_open_braces == 0)
21835 	    goto found_closing_brace;
21836 	  break;
21837 	case CPP_EOF:
21838 	  error_at (start_loc, "no closing brace");
21839 	  free (start_with_pass);
21840 	  return c_parser_peek_token (parser)->location;
21841 	default:
21842 	  break;
21843 	}
21844       c_parser_consume_token (parser);
21845     }
21846 
21847  found_closing_brace:
21848   /* At the closing brace; record its location.  */
21849   location_t end_loc = c_parser_peek_token (parser)->location;
21850 
21851   /* Consume the closing brace.  */
21852   c_parser_consume_token (parser);
21853 
21854   /* Invoke the RTL parser.  */
21855   if (!read_rtl_function_body_from_file_range (start_loc, end_loc))
21856     {
21857       free (start_with_pass);
21858       return end_loc;
21859     }
21860 
21861  /*  Run the backend on the cfun created above, transferring ownership of
21862      START_WITH_PASS.  */
21863   run_rtl_passes (start_with_pass);
21864   return end_loc;
21865 }
21866 
21867 #include "gt-c-c-parser.h"
21868