xref: /netbsd-src/external/gpl3/gcc/dist/gcc/c/c-parser.cc (revision b1e838363e3c6fc78a55519254d99869742dd33c)
1 /* Parser for C and Objective-C.
2    Copyright (C) 1987-2022 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_MEMORY
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 "tree-pretty-print.h"
72 #include "memmodel.h"
73 #include "c-family/known-headers.h"
74 
75 /* We need to walk over decls with incomplete struct/union/enum types
76    after parsing the whole translation unit.
77    In finish_decl(), if the decl is static, has incomplete
78    struct/union/enum type, it is appended to incomplete_record_decls.
79    In c_parser_translation_unit(), we iterate over incomplete_record_decls
80    and report error if any of the decls are still incomplete.  */
81 
82 vec<tree> incomplete_record_decls;
83 
84 void
set_c_expr_source_range(c_expr * expr,location_t start,location_t finish)85 set_c_expr_source_range (c_expr *expr,
86 			 location_t start, location_t finish)
87 {
88   expr->src_range.m_start = start;
89   expr->src_range.m_finish = finish;
90   if (expr->value)
91     set_source_range (expr->value, start, finish);
92 }
93 
94 void
set_c_expr_source_range(c_expr * expr,source_range src_range)95 set_c_expr_source_range (c_expr *expr,
96 			 source_range src_range)
97 {
98   expr->src_range = src_range;
99   if (expr->value)
100     set_source_range (expr->value, src_range);
101 }
102 
103 
104 /* Initialization routine for this file.  */
105 
106 void
c_parse_init(void)107 c_parse_init (void)
108 {
109   /* The only initialization required is of the reserved word
110      identifiers.  */
111   unsigned int i;
112   tree id;
113   int mask = 0;
114 
115   /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in
116      the c_token structure.  */
117   gcc_assert (RID_MAX <= 255);
118 
119   mask |= D_CXXONLY;
120   if (!flag_isoc99)
121     mask |= D_C99;
122   if (flag_no_asm)
123     {
124       mask |= D_ASM | D_EXT;
125       if (!flag_isoc99)
126 	mask |= D_EXT89;
127     }
128   if (!c_dialect_objc ())
129     mask |= D_OBJC | D_CXX_OBJC;
130 
131   ridpointers = ggc_cleared_vec_alloc<tree> ((int) RID_MAX);
132   for (i = 0; i < num_c_common_reswords; i++)
133     {
134       /* If a keyword is disabled, do not enter it into the table
135 	 and so create a canonical spelling that isn't a keyword.  */
136       if (c_common_reswords[i].disable & mask)
137 	{
138 	  if (warn_cxx_compat
139 	      && (c_common_reswords[i].disable & D_CXXWARN))
140 	    {
141 	      id = get_identifier (c_common_reswords[i].word);
142 	      C_SET_RID_CODE (id, RID_CXX_COMPAT_WARN);
143 	      C_IS_RESERVED_WORD (id) = 1;
144 	    }
145 	  continue;
146 	}
147 
148       id = get_identifier (c_common_reswords[i].word);
149       C_SET_RID_CODE (id, c_common_reswords[i].rid);
150       C_IS_RESERVED_WORD (id) = 1;
151       ridpointers [(int) c_common_reswords[i].rid] = id;
152     }
153 
154   for (i = 0; i < NUM_INT_N_ENTS; i++)
155     {
156       /* We always create the symbols but they aren't always supported.  */
157       char name[50];
158       sprintf (name, "__int%d", int_n_data[i].bitsize);
159       id = get_identifier (name);
160       C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
161       C_IS_RESERVED_WORD (id) = 1;
162 
163       sprintf (name, "__int%d__", int_n_data[i].bitsize);
164       id = get_identifier (name);
165       C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
166       C_IS_RESERVED_WORD (id) = 1;
167     }
168 }
169 
170 /* A parser structure recording information about the state and
171    context of parsing.  Includes lexer information with up to two
172    tokens of look-ahead; more are not needed for C.  */
173 struct GTY(()) c_parser {
174   /* The look-ahead tokens.  */
175   c_token * GTY((skip)) tokens;
176   /* Buffer for look-ahead tokens.  */
177   c_token tokens_buf[4];
178   /* How many look-ahead tokens are available (0 - 4, or
179      more if parsing from pre-lexed tokens).  */
180   unsigned int tokens_avail;
181   /* Raw look-ahead tokens, used only for checking in Objective-C
182      whether '[[' starts attributes.  */
183   vec<c_token, va_gc> *raw_tokens;
184   /* The number of raw look-ahead tokens that have since been fully
185      lexed.  */
186   unsigned int raw_tokens_used;
187   /* True if a syntax error is being recovered from; false otherwise.
188      c_parser_error sets this flag.  It should clear this flag when
189      enough tokens have been consumed to recover from the error.  */
190   BOOL_BITFIELD error : 1;
191   /* True if we're processing a pragma, and shouldn't automatically
192      consume CPP_PRAGMA_EOL.  */
193   BOOL_BITFIELD in_pragma : 1;
194   /* True if we're parsing the outermost block of an if statement.  */
195   BOOL_BITFIELD in_if_block : 1;
196   /* True if we want to lex a translated, joined string (for an
197      initial #pragma pch_preprocess).  Otherwise the parser is
198      responsible for concatenating strings and translating to the
199      execution character set as needed.  */
200   BOOL_BITFIELD lex_joined_string : 1;
201   /* True if, when the parser is concatenating string literals, it
202      should translate them to the execution character set (false
203      inside attributes).  */
204   BOOL_BITFIELD translate_strings_p : 1;
205 
206   /* Objective-C specific parser/lexer information.  */
207 
208   /* True if we are in a context where the Objective-C "PQ" keywords
209      are considered keywords.  */
210   BOOL_BITFIELD objc_pq_context : 1;
211   /* True if we are parsing a (potential) Objective-C foreach
212      statement.  This is set to true after we parsed 'for (' and while
213      we wait for 'in' or ';' to decide if it's a standard C for loop or an
214      Objective-C foreach loop.  */
215   BOOL_BITFIELD objc_could_be_foreach_context : 1;
216   /* The following flag is needed to contextualize Objective-C lexical
217      analysis.  In some cases (e.g., 'int NSObject;'), it is
218      undesirable to bind an identifier to an Objective-C class, even
219      if a class with that name exists.  */
220   BOOL_BITFIELD objc_need_raw_identifier : 1;
221   /* Nonzero if we're processing a __transaction statement.  The value
222      is 1 | TM_STMT_ATTR_*.  */
223   unsigned int in_transaction : 4;
224   /* True if we are in a context where the Objective-C "Property attribute"
225      keywords are valid.  */
226   BOOL_BITFIELD objc_property_attr_context : 1;
227 
228   /* Whether we have just seen/constructed a string-literal.  Set when
229      returning a string-literal from c_parser_string_literal.  Reset
230      in consume_token.  Useful when we get a parse error and see an
231      unknown token, which could have been a string-literal constant
232      macro.  */
233   BOOL_BITFIELD seen_string_literal : 1;
234 
235   /* Location of the last consumed token.  */
236   location_t last_token_location;
237 };
238 
239 /* Return a pointer to the Nth token in PARSERs tokens_buf.  */
240 
241 c_token *
c_parser_tokens_buf(c_parser * parser,unsigned n)242 c_parser_tokens_buf (c_parser *parser, unsigned n)
243 {
244   return &parser->tokens_buf[n];
245 }
246 
247 /* Return the error state of PARSER.  */
248 
249 bool
c_parser_error(c_parser * parser)250 c_parser_error (c_parser *parser)
251 {
252   return parser->error;
253 }
254 
255 /* Set the error state of PARSER to ERR.  */
256 
257 void
c_parser_set_error(c_parser * parser,bool err)258 c_parser_set_error (c_parser *parser, bool err)
259 {
260   parser->error = err;
261 }
262 
263 
264 /* The actual parser and external interface.  ??? Does this need to be
265    garbage-collected?  */
266 
267 static GTY (()) c_parser *the_parser;
268 
269 /* Read in and lex a single token, storing it in *TOKEN.  If RAW,
270    context-sensitive postprocessing of the token is not done.  */
271 
272 static void
c_lex_one_token(c_parser * parser,c_token * token,bool raw=false)273 c_lex_one_token (c_parser *parser, c_token *token, bool raw = false)
274 {
275   timevar_push (TV_LEX);
276 
277   if (raw || vec_safe_length (parser->raw_tokens) == 0)
278     {
279       token->type = c_lex_with_flags (&token->value, &token->location,
280 				      &token->flags,
281 				      (parser->lex_joined_string
282 				       ? 0 : C_LEX_STRING_NO_JOIN));
283       token->id_kind = C_ID_NONE;
284       token->keyword = RID_MAX;
285       token->pragma_kind = PRAGMA_NONE;
286     }
287   else
288     {
289       /* Use a token previously lexed as a raw look-ahead token, and
290 	 complete the processing on it.  */
291       *token = (*parser->raw_tokens)[parser->raw_tokens_used];
292       ++parser->raw_tokens_used;
293       if (parser->raw_tokens_used == vec_safe_length (parser->raw_tokens))
294 	{
295 	  vec_free (parser->raw_tokens);
296 	  parser->raw_tokens_used = 0;
297 	}
298     }
299 
300   if (raw)
301     goto out;
302 
303   switch (token->type)
304     {
305     case CPP_NAME:
306       {
307 	tree decl;
308 
309 	bool objc_force_identifier = parser->objc_need_raw_identifier;
310 	if (c_dialect_objc ())
311 	  parser->objc_need_raw_identifier = false;
312 
313 	if (C_IS_RESERVED_WORD (token->value))
314 	  {
315 	    enum rid rid_code = C_RID_CODE (token->value);
316 
317 	    if (rid_code == RID_CXX_COMPAT_WARN)
318 	      {
319 		warning_at (token->location,
320 			    OPT_Wc___compat,
321 			    "identifier %qE conflicts with C++ keyword",
322 			    token->value);
323 	      }
324 	    else if (rid_code >= RID_FIRST_ADDR_SPACE
325 		     && rid_code <= RID_LAST_ADDR_SPACE)
326 	      {
327 		addr_space_t as;
328 		as = (addr_space_t) (rid_code - RID_FIRST_ADDR_SPACE);
329 		targetm.addr_space.diagnose_usage (as, token->location);
330 		token->id_kind = C_ID_ADDRSPACE;
331 		token->keyword = rid_code;
332 		break;
333 	      }
334 	    else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code))
335 	      {
336 		/* We found an Objective-C "pq" keyword (in, out,
337 		   inout, bycopy, byref, oneway).  They need special
338 		   care because the interpretation depends on the
339 		   context.  */
340 		if (parser->objc_pq_context)
341 		  {
342 		    token->type = CPP_KEYWORD;
343 		    token->keyword = rid_code;
344 		    break;
345 		  }
346 		else if (parser->objc_could_be_foreach_context
347 			 && rid_code == RID_IN)
348 		  {
349 		    /* We are in Objective-C, inside a (potential)
350 		       foreach context (which means after having
351 		       parsed 'for (', but before having parsed ';'),
352 		       and we found 'in'.  We consider it the keyword
353 		       which terminates the declaration at the
354 		       beginning of a foreach-statement.  Note that
355 		       this means you can't use 'in' for anything else
356 		       in that context; in particular, in Objective-C
357 		       you can't use 'in' as the name of the running
358 		       variable in a C for loop.  We could potentially
359 		       try to add code here to disambiguate, but it
360 		       seems a reasonable limitation.  */
361 		    token->type = CPP_KEYWORD;
362 		    token->keyword = rid_code;
363 		    break;
364 		  }
365 		/* Else, "pq" keywords outside of the "pq" context are
366 		   not keywords, and we fall through to the code for
367 		   normal tokens.  */
368 	      }
369 	    else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code))
370 	      {
371 		/* We found an Objective-C "property attribute"
372 		   keyword (getter, setter, readonly, etc). These are
373 		   only valid in the property context.  */
374 		if (parser->objc_property_attr_context)
375 		  {
376 		    token->type = CPP_KEYWORD;
377 		    token->keyword = rid_code;
378 		    break;
379 		  }
380 		/* Else they are not special keywords.
381 		*/
382 	      }
383 	    else if (c_dialect_objc ()
384 		     && (OBJC_IS_AT_KEYWORD (rid_code)
385 			 || OBJC_IS_CXX_KEYWORD (rid_code)))
386 	      {
387 		/* We found one of the Objective-C "@" keywords (defs,
388 		   selector, synchronized, etc) or one of the
389 		   Objective-C "cxx" keywords (class, private,
390 		   protected, public, try, catch, throw) without a
391 		   preceding '@' sign.  Do nothing and fall through to
392 		   the code for normal tokens (in C++ we would still
393 		   consider the CXX ones keywords, but not in C).  */
394 		;
395 	      }
396 	    else
397 	      {
398 		token->type = CPP_KEYWORD;
399 		token->keyword = rid_code;
400 		break;
401 	      }
402 	  }
403 
404 	decl = lookup_name (token->value);
405 	if (decl)
406 	  {
407 	    if (TREE_CODE (decl) == TYPE_DECL)
408 	      {
409 		token->id_kind = C_ID_TYPENAME;
410 		break;
411 	      }
412 	  }
413 	else if (c_dialect_objc ())
414 	  {
415 	    tree objc_interface_decl = objc_is_class_name (token->value);
416 	    /* Objective-C class names are in the same namespace as
417 	       variables and typedefs, and hence are shadowed by local
418 	       declarations.  */
419 	    if (objc_interface_decl
420                 && (!objc_force_identifier || global_bindings_p ()))
421 	      {
422 		token->value = objc_interface_decl;
423 		token->id_kind = C_ID_CLASSNAME;
424 		break;
425 	      }
426 	  }
427         token->id_kind = C_ID_ID;
428       }
429       break;
430     case CPP_AT_NAME:
431       /* This only happens in Objective-C; it must be a keyword.  */
432       token->type = CPP_KEYWORD;
433       switch (C_RID_CODE (token->value))
434 	{
435 	  /* Replace 'class' with '@class', 'private' with '@private',
436 	     etc.  This prevents confusion with the C++ keyword
437 	     'class', and makes the tokens consistent with other
438 	     Objective-C 'AT' keywords.  For example '@class' is
439 	     reported as RID_AT_CLASS which is consistent with
440 	     '@synchronized', which is reported as
441 	     RID_AT_SYNCHRONIZED.
442 	  */
443 	case RID_CLASS:     token->keyword = RID_AT_CLASS; break;
444 	case RID_PRIVATE:   token->keyword = RID_AT_PRIVATE; break;
445 	case RID_PROTECTED: token->keyword = RID_AT_PROTECTED; break;
446 	case RID_PUBLIC:    token->keyword = RID_AT_PUBLIC; break;
447 	case RID_THROW:     token->keyword = RID_AT_THROW; break;
448 	case RID_TRY:       token->keyword = RID_AT_TRY; break;
449 	case RID_CATCH:     token->keyword = RID_AT_CATCH; break;
450 	case RID_SYNCHRONIZED: token->keyword = RID_AT_SYNCHRONIZED; break;
451 	default:            token->keyword = C_RID_CODE (token->value);
452 	}
453       break;
454     case CPP_COLON:
455     case CPP_COMMA:
456     case CPP_CLOSE_PAREN:
457     case CPP_SEMICOLON:
458       /* These tokens may affect the interpretation of any identifiers
459 	 following, if doing Objective-C.  */
460       if (c_dialect_objc ())
461 	parser->objc_need_raw_identifier = false;
462       break;
463     case CPP_PRAGMA:
464       /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST.  */
465       token->pragma_kind = (enum pragma_kind) TREE_INT_CST_LOW (token->value);
466       token->value = NULL;
467       break;
468     default:
469       break;
470     }
471  out:
472   timevar_pop (TV_LEX);
473 }
474 
475 /* Return a pointer to the next token from PARSER, reading it in if
476    necessary.  */
477 
478 c_token *
c_parser_peek_token(c_parser * parser)479 c_parser_peek_token (c_parser *parser)
480 {
481   if (parser->tokens_avail == 0)
482     {
483       c_lex_one_token (parser, &parser->tokens[0]);
484       parser->tokens_avail = 1;
485     }
486   return &parser->tokens[0];
487 }
488 
489 /* Return a pointer to the next-but-one token from PARSER, reading it
490    in if necessary.  The next token is already read in.  */
491 
492 c_token *
c_parser_peek_2nd_token(c_parser * parser)493 c_parser_peek_2nd_token (c_parser *parser)
494 {
495   if (parser->tokens_avail >= 2)
496     return &parser->tokens[1];
497   gcc_assert (parser->tokens_avail == 1);
498   gcc_assert (parser->tokens[0].type != CPP_EOF);
499   gcc_assert (parser->tokens[0].type != CPP_PRAGMA_EOL);
500   c_lex_one_token (parser, &parser->tokens[1]);
501   parser->tokens_avail = 2;
502   return &parser->tokens[1];
503 }
504 
505 /* Return a pointer to the Nth token from PARSER, reading it
506    in if necessary.  The N-1th token is already read in.  */
507 
508 c_token *
c_parser_peek_nth_token(c_parser * parser,unsigned int n)509 c_parser_peek_nth_token (c_parser *parser, unsigned int n)
510 {
511   /* N is 1-based, not zero-based.  */
512   gcc_assert (n > 0);
513 
514   if (parser->tokens_avail >= n)
515     return &parser->tokens[n - 1];
516   gcc_assert (parser->tokens_avail == n - 1);
517   c_lex_one_token (parser, &parser->tokens[n - 1]);
518   parser->tokens_avail = n;
519   return &parser->tokens[n - 1];
520 }
521 
522 /* Return a pointer to the Nth token from PARSER, reading it in as a
523    raw look-ahead token if necessary.  The N-1th token is already read
524    in.  Raw look-ahead tokens remain available for when the non-raw
525    functions above are called.  */
526 
527 c_token *
c_parser_peek_nth_token_raw(c_parser * parser,unsigned int n)528 c_parser_peek_nth_token_raw (c_parser *parser, unsigned int n)
529 {
530   /* N is 1-based, not zero-based.  */
531   gcc_assert (n > 0);
532 
533   if (parser->tokens_avail >= n)
534     return &parser->tokens[n - 1];
535   unsigned int raw_len = vec_safe_length (parser->raw_tokens);
536   unsigned int raw_avail
537     = parser->tokens_avail + raw_len - parser->raw_tokens_used;
538   gcc_assert (raw_avail >= n - 1);
539   if (raw_avail >= n)
540     return &(*parser->raw_tokens)[parser->raw_tokens_used
541 				  + n - 1 - parser->tokens_avail];
542   vec_safe_reserve (parser->raw_tokens, 1);
543   parser->raw_tokens->quick_grow (raw_len + 1);
544   c_lex_one_token (parser, &(*parser->raw_tokens)[raw_len], true);
545   return &(*parser->raw_tokens)[raw_len];
546 }
547 
548 bool
c_keyword_starts_typename(enum rid keyword)549 c_keyword_starts_typename (enum rid keyword)
550 {
551   switch (keyword)
552     {
553     case RID_UNSIGNED:
554     case RID_LONG:
555     case RID_SHORT:
556     case RID_SIGNED:
557     case RID_COMPLEX:
558     case RID_INT:
559     case RID_CHAR:
560     case RID_FLOAT:
561     case RID_DOUBLE:
562     case RID_VOID:
563     case RID_DFLOAT32:
564     case RID_DFLOAT64:
565     case RID_DFLOAT128:
566     CASE_RID_FLOATN_NX:
567     case RID_BOOL:
568     case RID_ENUM:
569     case RID_STRUCT:
570     case RID_UNION:
571     case RID_TYPEOF:
572     case RID_CONST:
573     case RID_ATOMIC:
574     case RID_VOLATILE:
575     case RID_RESTRICT:
576     case RID_ATTRIBUTE:
577     case RID_FRACT:
578     case RID_ACCUM:
579     case RID_SAT:
580     case RID_AUTO_TYPE:
581     case RID_ALIGNAS:
582       return true;
583     default:
584       if (keyword >= RID_FIRST_INT_N
585 	  && keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
586 	  && int_n_enabled_p[keyword - RID_FIRST_INT_N])
587 	return true;
588       return false;
589     }
590 }
591 
592 /* Return true if TOKEN can start a type name,
593    false otherwise.  */
594 bool
c_token_starts_typename(c_token * token)595 c_token_starts_typename (c_token *token)
596 {
597   switch (token->type)
598     {
599     case CPP_NAME:
600       switch (token->id_kind)
601 	{
602 	case C_ID_ID:
603 	  return false;
604 	case C_ID_ADDRSPACE:
605 	  return true;
606 	case C_ID_TYPENAME:
607 	  return true;
608 	case C_ID_CLASSNAME:
609 	  gcc_assert (c_dialect_objc ());
610 	  return true;
611 	default:
612 	  gcc_unreachable ();
613 	}
614     case CPP_KEYWORD:
615       return c_keyword_starts_typename (token->keyword);
616     case CPP_LESS:
617       if (c_dialect_objc ())
618 	return true;
619       return false;
620     default:
621       return false;
622     }
623 }
624 
625 /* Return true if the next token from PARSER can start a type name,
626    false otherwise.  LA specifies how to do lookahead in order to
627    detect unknown type names.  If unsure, pick CLA_PREFER_ID.  */
628 
629 static inline bool
c_parser_next_tokens_start_typename(c_parser * parser,enum c_lookahead_kind la)630 c_parser_next_tokens_start_typename (c_parser *parser, enum c_lookahead_kind la)
631 {
632   c_token *token = c_parser_peek_token (parser);
633   if (c_token_starts_typename (token))
634     return true;
635 
636   /* Try a bit harder to detect an unknown typename.  */
637   if (la != cla_prefer_id
638       && token->type == CPP_NAME
639       && token->id_kind == C_ID_ID
640 
641       /* Do not try too hard when we could have "object in array".  */
642       && !parser->objc_could_be_foreach_context
643 
644       && (la == cla_prefer_type
645 	  || c_parser_peek_2nd_token (parser)->type == CPP_NAME
646 	  || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
647 
648       /* Only unknown identifiers.  */
649       && !lookup_name (token->value))
650     return true;
651 
652   return false;
653 }
654 
655 /* Return true if TOKEN is a type qualifier, false otherwise.  */
656 static bool
c_token_is_qualifier(c_token * token)657 c_token_is_qualifier (c_token *token)
658 {
659   switch (token->type)
660     {
661     case CPP_NAME:
662       switch (token->id_kind)
663 	{
664 	case C_ID_ADDRSPACE:
665 	  return true;
666 	default:
667 	  return false;
668 	}
669     case CPP_KEYWORD:
670       switch (token->keyword)
671 	{
672 	case RID_CONST:
673 	case RID_VOLATILE:
674 	case RID_RESTRICT:
675 	case RID_ATTRIBUTE:
676 	case RID_ATOMIC:
677 	  return true;
678 	default:
679 	  return false;
680 	}
681     case CPP_LESS:
682       return false;
683     default:
684       gcc_unreachable ();
685     }
686 }
687 
688 /* Return true if the next token from PARSER is a type qualifier,
689    false otherwise.  */
690 static inline bool
c_parser_next_token_is_qualifier(c_parser * parser)691 c_parser_next_token_is_qualifier (c_parser *parser)
692 {
693   c_token *token = c_parser_peek_token (parser);
694   return c_token_is_qualifier (token);
695 }
696 
697 /* Return true if TOKEN can start declaration specifiers (not
698    including standard attributes), false otherwise.  */
699 static bool
c_token_starts_declspecs(c_token * token)700 c_token_starts_declspecs (c_token *token)
701 {
702   switch (token->type)
703     {
704     case CPP_NAME:
705       switch (token->id_kind)
706 	{
707 	case C_ID_ID:
708 	  return false;
709 	case C_ID_ADDRSPACE:
710 	  return true;
711 	case C_ID_TYPENAME:
712 	  return true;
713 	case C_ID_CLASSNAME:
714 	  gcc_assert (c_dialect_objc ());
715 	  return true;
716 	default:
717 	  gcc_unreachable ();
718 	}
719     case CPP_KEYWORD:
720       switch (token->keyword)
721 	{
722 	case RID_STATIC:
723 	case RID_EXTERN:
724 	case RID_REGISTER:
725 	case RID_TYPEDEF:
726 	case RID_INLINE:
727 	case RID_NORETURN:
728 	case RID_AUTO:
729 	case RID_THREAD:
730 	case RID_UNSIGNED:
731 	case RID_LONG:
732 	case RID_SHORT:
733 	case RID_SIGNED:
734 	case RID_COMPLEX:
735 	case RID_INT:
736 	case RID_CHAR:
737 	case RID_FLOAT:
738 	case RID_DOUBLE:
739 	case RID_VOID:
740 	case RID_DFLOAT32:
741 	case RID_DFLOAT64:
742 	case RID_DFLOAT128:
743 	CASE_RID_FLOATN_NX:
744 	case RID_BOOL:
745 	case RID_ENUM:
746 	case RID_STRUCT:
747 	case RID_UNION:
748 	case RID_TYPEOF:
749 	case RID_CONST:
750 	case RID_VOLATILE:
751 	case RID_RESTRICT:
752 	case RID_ATTRIBUTE:
753 	case RID_FRACT:
754 	case RID_ACCUM:
755 	case RID_SAT:
756 	case RID_ALIGNAS:
757 	case RID_ATOMIC:
758 	case RID_AUTO_TYPE:
759 	  return true;
760 	default:
761 	  if (token->keyword >= RID_FIRST_INT_N
762 	      && token->keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
763 	      && int_n_enabled_p[token->keyword - RID_FIRST_INT_N])
764 	    return true;
765 	  return false;
766 	}
767     case CPP_LESS:
768       if (c_dialect_objc ())
769 	return true;
770       return false;
771     default:
772       return false;
773     }
774 }
775 
776 
777 /* Return true if TOKEN can start declaration specifiers (not
778    including standard attributes) or a static assertion, false
779    otherwise.  */
780 static bool
c_token_starts_declaration(c_token * token)781 c_token_starts_declaration (c_token *token)
782 {
783   if (c_token_starts_declspecs (token)
784       || token->keyword == RID_STATIC_ASSERT)
785     return true;
786   else
787     return false;
788 }
789 
790 /* Return true if the next token from PARSER can start declaration
791    specifiers (not including standard attributes), false
792    otherwise.  */
793 bool
c_parser_next_token_starts_declspecs(c_parser * parser)794 c_parser_next_token_starts_declspecs (c_parser *parser)
795 {
796   c_token *token = c_parser_peek_token (parser);
797 
798   /* In Objective-C, a classname normally starts a declspecs unless it
799      is immediately followed by a dot.  In that case, it is the
800      Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
801      setter/getter on the class.  c_token_starts_declspecs() can't
802      differentiate between the two cases because it only checks the
803      current token, so we have a special check here.  */
804   if (c_dialect_objc ()
805       && token->type == CPP_NAME
806       && token->id_kind == C_ID_CLASSNAME
807       && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
808     return false;
809 
810   return c_token_starts_declspecs (token);
811 }
812 
813 /* Return true if the next tokens from PARSER can start declaration
814    specifiers (not including standard attributes) or a static
815    assertion, false otherwise.  */
816 bool
c_parser_next_tokens_start_declaration(c_parser * parser)817 c_parser_next_tokens_start_declaration (c_parser *parser)
818 {
819   c_token *token = c_parser_peek_token (parser);
820 
821   /* Same as above.  */
822   if (c_dialect_objc ()
823       && token->type == CPP_NAME
824       && token->id_kind == C_ID_CLASSNAME
825       && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
826     return false;
827 
828   /* Labels do not start declarations.  */
829   if (token->type == CPP_NAME
830       && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
831     return false;
832 
833   if (c_token_starts_declaration (token))
834     return true;
835 
836   if (c_parser_next_tokens_start_typename (parser, cla_nonabstract_decl))
837     return true;
838 
839   return false;
840 }
841 
842 /* Consume the next token from PARSER.  */
843 
844 void
c_parser_consume_token(c_parser * parser)845 c_parser_consume_token (c_parser *parser)
846 {
847   gcc_assert (parser->tokens_avail >= 1);
848   gcc_assert (parser->tokens[0].type != CPP_EOF);
849   gcc_assert (!parser->in_pragma || parser->tokens[0].type != CPP_PRAGMA_EOL);
850   gcc_assert (parser->error || parser->tokens[0].type != CPP_PRAGMA);
851   parser->last_token_location = parser->tokens[0].location;
852   if (parser->tokens != &parser->tokens_buf[0])
853     parser->tokens++;
854   else if (parser->tokens_avail >= 2)
855     {
856       parser->tokens[0] = parser->tokens[1];
857       if (parser->tokens_avail >= 3)
858         {
859           parser->tokens[1] = parser->tokens[2];
860           if (parser->tokens_avail >= 4)
861             parser->tokens[2] = parser->tokens[3];
862         }
863     }
864   parser->tokens_avail--;
865   parser->seen_string_literal = false;
866 }
867 
868 /* Expect the current token to be a #pragma.  Consume it and remember
869    that we've begun parsing a pragma.  */
870 
871 static void
c_parser_consume_pragma(c_parser * parser)872 c_parser_consume_pragma (c_parser *parser)
873 {
874   gcc_assert (!parser->in_pragma);
875   gcc_assert (parser->tokens_avail >= 1);
876   gcc_assert (parser->tokens[0].type == CPP_PRAGMA);
877   if (parser->tokens != &parser->tokens_buf[0])
878     parser->tokens++;
879   else if (parser->tokens_avail >= 2)
880     {
881       parser->tokens[0] = parser->tokens[1];
882       if (parser->tokens_avail >= 3)
883 	parser->tokens[1] = parser->tokens[2];
884     }
885   parser->tokens_avail--;
886   parser->in_pragma = true;
887 }
888 
889 /* Update the global input_location from TOKEN.  */
890 static inline void
c_parser_set_source_position_from_token(c_token * token)891 c_parser_set_source_position_from_token (c_token *token)
892 {
893   if (token->type != CPP_EOF)
894     {
895       input_location = token->location;
896     }
897 }
898 
899 /* Helper function for c_parser_error.
900    Having peeked a token of kind TOK1_KIND that might signify
901    a conflict marker, peek successor tokens to determine
902    if we actually do have a conflict marker.
903    Specifically, we consider a run of 7 '<', '=' or '>' characters
904    at the start of a line as a conflict marker.
905    These come through the lexer as three pairs and a single,
906    e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<').
907    If it returns true, *OUT_LOC is written to with the location/range
908    of the marker.  */
909 
910 static bool
c_parser_peek_conflict_marker(c_parser * parser,enum cpp_ttype tok1_kind,location_t * out_loc)911 c_parser_peek_conflict_marker (c_parser *parser, enum cpp_ttype tok1_kind,
912 			       location_t *out_loc)
913 {
914   c_token *token2 = c_parser_peek_2nd_token (parser);
915   if (token2->type != tok1_kind)
916     return false;
917   c_token *token3 = c_parser_peek_nth_token (parser, 3);
918   if (token3->type != tok1_kind)
919     return false;
920   c_token *token4 = c_parser_peek_nth_token (parser, 4);
921   if (token4->type != conflict_marker_get_final_tok_kind (tok1_kind))
922     return false;
923 
924   /* It must be at the start of the line.  */
925   location_t start_loc = c_parser_peek_token (parser)->location;
926   if (LOCATION_COLUMN (start_loc) != 1)
927     return false;
928 
929   /* We have a conflict marker.  Construct a location of the form:
930        <<<<<<<
931        ^~~~~~~
932      with start == caret, finishing at the end of the marker.  */
933   location_t finish_loc = get_finish (token4->location);
934   *out_loc = make_location (start_loc, start_loc, finish_loc);
935 
936   return true;
937 }
938 
939 /* Issue a diagnostic of the form
940       FILE:LINE: MESSAGE before TOKEN
941    where TOKEN is the next token in the input stream of PARSER.
942    MESSAGE (specified by the caller) is usually of the form "expected
943    OTHER-TOKEN".
944 
945    Use RICHLOC as the location of the diagnostic.
946 
947    Do not issue a diagnostic if still recovering from an error.
948 
949    Return true iff an error was actually emitted.
950 
951    ??? This is taken from the C++ parser, but building up messages in
952    this way is not i18n-friendly and some other approach should be
953    used.  */
954 
955 static bool
c_parser_error_richloc(c_parser * parser,const char * gmsgid,rich_location * richloc)956 c_parser_error_richloc (c_parser *parser, const char *gmsgid,
957 			rich_location *richloc)
958 {
959   c_token *token = c_parser_peek_token (parser);
960   if (parser->error)
961     return false;
962   parser->error = true;
963   if (!gmsgid)
964     return false;
965 
966   /* If this is actually a conflict marker, report it as such.  */
967   if (token->type == CPP_LSHIFT
968       || token->type == CPP_RSHIFT
969       || token->type == CPP_EQ_EQ)
970     {
971       location_t loc;
972       if (c_parser_peek_conflict_marker (parser, token->type, &loc))
973 	{
974 	  error_at (loc, "version control conflict marker in file");
975 	  return true;
976 	}
977     }
978 
979   /* If we were parsing a string-literal and there is an unknown name
980      token right after, then check to see if that could also have been
981      a literal string by checking the name against a list of known
982      standard string literal constants defined in header files. If
983      there is one, then add that as an hint to the error message. */
984   auto_diagnostic_group d;
985   name_hint h;
986   if (parser->seen_string_literal && token->type == CPP_NAME)
987     {
988       tree name = token->value;
989       const char *token_name = IDENTIFIER_POINTER (name);
990       const char *header_hint
991 	= get_c_stdlib_header_for_string_macro_name (token_name);
992       if (header_hint != NULL)
993 	h = name_hint (NULL, new suggest_missing_header (token->location,
994 							 token_name,
995 							 header_hint));
996     }
997 
998   c_parse_error (gmsgid,
999 		 /* Because c_parse_error does not understand
1000 		    CPP_KEYWORD, keywords are treated like
1001 		    identifiers.  */
1002 		 (token->type == CPP_KEYWORD ? CPP_NAME : token->type),
1003 		 /* ??? The C parser does not save the cpp flags of a
1004 		    token, we need to pass 0 here and we will not get
1005 		    the source spelling of some tokens but rather the
1006 		    canonical spelling.  */
1007 		 token->value, /*flags=*/0, richloc);
1008   return true;
1009 }
1010 
1011 /* As c_parser_error_richloc, but issue the message at the
1012    location of PARSER's next token, or at input_location
1013    if the next token is EOF.  */
1014 
1015 bool
c_parser_error(c_parser * parser,const char * gmsgid)1016 c_parser_error (c_parser *parser, const char *gmsgid)
1017 {
1018   c_token *token = c_parser_peek_token (parser);
1019   c_parser_set_source_position_from_token (token);
1020   rich_location richloc (line_table, input_location);
1021   return c_parser_error_richloc (parser, gmsgid, &richloc);
1022 }
1023 
1024 /* Some tokens naturally come in pairs e.g.'(' and ')'.
1025    This class is for tracking such a matching pair of symbols.
1026    In particular, it tracks the location of the first token,
1027    so that if the second token is missing, we can highlight the
1028    location of the first token when notifying the user about the
1029    problem.  */
1030 
1031 template <typename traits_t>
1032 class token_pair
1033 {
1034  public:
1035   /* token_pair's ctor.  */
token_pair()1036   token_pair () : m_open_loc (UNKNOWN_LOCATION) {}
1037 
1038   /* If the next token is the opening symbol for this pair, consume it and
1039      return true.
1040      Otherwise, issue an error and return false.
1041      In either case, record the location of the opening token.  */
1042 
require_open(c_parser * parser)1043   bool require_open (c_parser *parser)
1044   {
1045     c_token *token = c_parser_peek_token (parser);
1046     if (token)
1047       m_open_loc = token->location;
1048 
1049     return c_parser_require (parser, traits_t::open_token_type,
1050 			     traits_t::open_gmsgid);
1051   }
1052 
1053   /* Consume the next token from PARSER, recording its location as
1054      that of the opening token within the pair.  */
1055 
consume_open(c_parser * parser)1056   void consume_open (c_parser *parser)
1057   {
1058     c_token *token = c_parser_peek_token (parser);
1059     gcc_assert (token->type == traits_t::open_token_type);
1060     m_open_loc = token->location;
1061     c_parser_consume_token (parser);
1062   }
1063 
1064   /* If the next token is the closing symbol for this pair, consume it
1065      and return true.
1066      Otherwise, issue an error, highlighting the location of the
1067      corresponding opening token, and return false.  */
1068 
require_close(c_parser * parser) const1069   bool require_close (c_parser *parser) const
1070   {
1071     return c_parser_require (parser, traits_t::close_token_type,
1072 			     traits_t::close_gmsgid, m_open_loc);
1073   }
1074 
1075   /* Like token_pair::require_close, except that tokens will be skipped
1076      until the desired token is found.  An error message is still produced
1077      if the next token is not as expected.  */
1078 
skip_until_found_close(c_parser * parser) const1079   void skip_until_found_close (c_parser *parser) const
1080   {
1081     c_parser_skip_until_found (parser, traits_t::close_token_type,
1082 			       traits_t::close_gmsgid, m_open_loc);
1083   }
1084 
1085  private:
1086   location_t m_open_loc;
1087 };
1088 
1089 /* Traits for token_pair<T> for tracking matching pairs of parentheses.  */
1090 
1091 struct matching_paren_traits
1092 {
1093   static const enum cpp_ttype open_token_type = CPP_OPEN_PAREN;
1094   static const char * const open_gmsgid;
1095   static const enum cpp_ttype close_token_type = CPP_CLOSE_PAREN;
1096   static const char * const close_gmsgid;
1097 };
1098 
1099 const char * const matching_paren_traits::open_gmsgid = "expected %<(%>";
1100 const char * const matching_paren_traits::close_gmsgid = "expected %<)%>";
1101 
1102 /* "matching_parens" is a token_pair<T> class for tracking matching
1103    pairs of parentheses.  */
1104 
1105 typedef token_pair<matching_paren_traits> matching_parens;
1106 
1107 /* Traits for token_pair<T> for tracking matching pairs of braces.  */
1108 
1109 struct matching_brace_traits
1110 {
1111   static const enum cpp_ttype open_token_type = CPP_OPEN_BRACE;
1112   static const char * const open_gmsgid;
1113   static const enum cpp_ttype close_token_type = CPP_CLOSE_BRACE;
1114   static const char * const close_gmsgid;
1115 };
1116 
1117 const char * const matching_brace_traits::open_gmsgid = "expected %<{%>";
1118 const char * const matching_brace_traits::close_gmsgid = "expected %<}%>";
1119 
1120 /* "matching_braces" is a token_pair<T> class for tracking matching
1121    pairs of braces.  */
1122 
1123 typedef token_pair<matching_brace_traits> matching_braces;
1124 
1125 /* Get a description of the matching symbol to TYPE e.g. "(" for
1126    CPP_CLOSE_PAREN.  */
1127 
1128 static const char *
get_matching_symbol(enum cpp_ttype type)1129 get_matching_symbol (enum cpp_ttype type)
1130 {
1131   switch (type)
1132     {
1133     default:
1134       gcc_unreachable ();
1135     case CPP_CLOSE_PAREN:
1136       return "(";
1137     case CPP_CLOSE_BRACE:
1138       return "{";
1139     }
1140 }
1141 
1142 /* If the next token is of the indicated TYPE, consume it.  Otherwise,
1143    issue the error MSGID.  If MSGID is NULL then a message has already
1144    been produced and no message will be produced this time.  Returns
1145    true if found, false otherwise.
1146 
1147    If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1148    within any error as the location of an "opening" token matching
1149    the close token TYPE (e.g. the location of the '(' when TYPE is
1150    CPP_CLOSE_PAREN).
1151 
1152    If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly
1153    one type (e.g. "expected %<)%>") and thus it may be reasonable to
1154    attempt to generate a fix-it hint for the problem.
1155    Otherwise msgid describes multiple token types (e.g.
1156    "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to
1157    generate a fix-it hint.  */
1158 
1159 bool
c_parser_require(c_parser * parser,enum cpp_ttype type,const char * msgid,location_t matching_location,bool type_is_unique)1160 c_parser_require (c_parser *parser,
1161 		  enum cpp_ttype type,
1162 		  const char *msgid,
1163 		  location_t matching_location,
1164 		  bool type_is_unique)
1165 {
1166   if (c_parser_next_token_is (parser, type))
1167     {
1168       c_parser_consume_token (parser);
1169       return true;
1170     }
1171   else
1172     {
1173       location_t next_token_loc = c_parser_peek_token (parser)->location;
1174       gcc_rich_location richloc (next_token_loc);
1175 
1176       /* Potentially supply a fix-it hint, suggesting to add the
1177 	 missing token immediately after the *previous* token.
1178 	 This may move the primary location within richloc.  */
1179       if (!parser->error && type_is_unique)
1180 	maybe_suggest_missing_token_insertion (&richloc, type,
1181 					       parser->last_token_location);
1182 
1183       /* If matching_location != UNKNOWN_LOCATION, highlight it.
1184 	 Attempt to consolidate diagnostics by printing it as a
1185 	 secondary range within the main diagnostic.  */
1186       bool added_matching_location = false;
1187       if (matching_location != UNKNOWN_LOCATION)
1188 	added_matching_location
1189 	  = richloc.add_location_if_nearby (matching_location);
1190 
1191       if (c_parser_error_richloc (parser, msgid, &richloc))
1192 	/* If we weren't able to consolidate matching_location, then
1193 	   print it as a secondary diagnostic.  */
1194 	if (matching_location != UNKNOWN_LOCATION && !added_matching_location)
1195 	  inform (matching_location, "to match this %qs",
1196 		  get_matching_symbol (type));
1197 
1198       return false;
1199     }
1200 }
1201 
1202 /* If the next token is the indicated keyword, consume it.  Otherwise,
1203    issue the error MSGID.  Returns true if found, false otherwise.  */
1204 
1205 static bool
c_parser_require_keyword(c_parser * parser,enum rid keyword,const char * msgid)1206 c_parser_require_keyword (c_parser *parser,
1207 			  enum rid keyword,
1208 			  const char *msgid)
1209 {
1210   if (c_parser_next_token_is_keyword (parser, keyword))
1211     {
1212       c_parser_consume_token (parser);
1213       return true;
1214     }
1215   else
1216     {
1217       c_parser_error (parser, msgid);
1218       return false;
1219     }
1220 }
1221 
1222 /* Like c_parser_require, except that tokens will be skipped until the
1223    desired token is found.  An error message is still produced if the
1224    next token is not as expected.  If MSGID is NULL then a message has
1225    already been produced and no message will be produced this
1226    time.
1227 
1228    If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1229    within any error as the location of an "opening" token matching
1230    the close token TYPE (e.g. the location of the '(' when TYPE is
1231    CPP_CLOSE_PAREN).  */
1232 
1233 void
c_parser_skip_until_found(c_parser * parser,enum cpp_ttype type,const char * msgid,location_t matching_location)1234 c_parser_skip_until_found (c_parser *parser,
1235 			   enum cpp_ttype type,
1236 			   const char *msgid,
1237 			   location_t matching_location)
1238 {
1239   unsigned nesting_depth = 0;
1240 
1241   if (c_parser_require (parser, type, msgid, matching_location))
1242     return;
1243 
1244   /* Skip tokens until the desired token is found.  */
1245   while (true)
1246     {
1247       /* Peek at the next token.  */
1248       c_token *token = c_parser_peek_token (parser);
1249       /* If we've reached the token we want, consume it and stop.  */
1250       if (token->type == type && !nesting_depth)
1251 	{
1252 	  c_parser_consume_token (parser);
1253 	  break;
1254 	}
1255 
1256       /* If we've run out of tokens, stop.  */
1257       if (token->type == CPP_EOF)
1258 	return;
1259       if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1260 	return;
1261       if (token->type == CPP_OPEN_BRACE
1262 	  || token->type == CPP_OPEN_PAREN
1263 	  || token->type == CPP_OPEN_SQUARE)
1264 	++nesting_depth;
1265       else if (token->type == CPP_CLOSE_BRACE
1266 	       || token->type == CPP_CLOSE_PAREN
1267 	       || token->type == CPP_CLOSE_SQUARE)
1268 	{
1269 	  if (nesting_depth-- == 0)
1270 	    break;
1271 	}
1272       /* Consume this token.  */
1273       c_parser_consume_token (parser);
1274     }
1275   parser->error = false;
1276 }
1277 
1278 /* Skip tokens until the end of a parameter is found, but do not
1279    consume the comma, semicolon or closing delimiter.  */
1280 
1281 static void
c_parser_skip_to_end_of_parameter(c_parser * parser)1282 c_parser_skip_to_end_of_parameter (c_parser *parser)
1283 {
1284   unsigned nesting_depth = 0;
1285 
1286   while (true)
1287     {
1288       c_token *token = c_parser_peek_token (parser);
1289       if ((token->type == CPP_COMMA || token->type == CPP_SEMICOLON)
1290 	  && !nesting_depth)
1291 	break;
1292       /* If we've run out of tokens, stop.  */
1293       if (token->type == CPP_EOF)
1294 	return;
1295       if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1296 	return;
1297       if (token->type == CPP_OPEN_BRACE
1298 	  || token->type == CPP_OPEN_PAREN
1299 	  || token->type == CPP_OPEN_SQUARE)
1300 	++nesting_depth;
1301       else if (token->type == CPP_CLOSE_BRACE
1302 	       || token->type == CPP_CLOSE_PAREN
1303 	       || token->type == CPP_CLOSE_SQUARE)
1304 	{
1305 	  if (nesting_depth-- == 0)
1306 	    break;
1307 	}
1308       /* Consume this token.  */
1309       c_parser_consume_token (parser);
1310     }
1311   parser->error = false;
1312 }
1313 
1314 /* Expect to be at the end of the pragma directive and consume an
1315    end of line marker.  */
1316 
1317 static void
c_parser_skip_to_pragma_eol(c_parser * parser,bool error_if_not_eol=true)1318 c_parser_skip_to_pragma_eol (c_parser *parser, bool error_if_not_eol = true)
1319 {
1320   gcc_assert (parser->in_pragma);
1321   parser->in_pragma = false;
1322 
1323   if (error_if_not_eol && c_parser_peek_token (parser)->type != CPP_PRAGMA_EOL)
1324     c_parser_error (parser, "expected end of line");
1325 
1326   cpp_ttype token_type;
1327   do
1328     {
1329       c_token *token = c_parser_peek_token (parser);
1330       token_type = token->type;
1331       if (token_type == CPP_EOF)
1332 	break;
1333       c_parser_consume_token (parser);
1334     }
1335   while (token_type != CPP_PRAGMA_EOL);
1336 
1337   parser->error = false;
1338 }
1339 
1340 /* Skip tokens until we have consumed an entire block, or until we
1341    have consumed a non-nested ';'.  */
1342 
1343 static void
c_parser_skip_to_end_of_block_or_statement(c_parser * parser)1344 c_parser_skip_to_end_of_block_or_statement (c_parser *parser)
1345 {
1346   unsigned nesting_depth = 0;
1347   bool save_error = parser->error;
1348 
1349   while (true)
1350     {
1351       c_token *token;
1352 
1353       /* Peek at the next token.  */
1354       token = c_parser_peek_token (parser);
1355 
1356       switch (token->type)
1357 	{
1358 	case CPP_EOF:
1359 	  return;
1360 
1361 	case CPP_PRAGMA_EOL:
1362 	  if (parser->in_pragma)
1363 	    return;
1364 	  break;
1365 
1366 	case CPP_SEMICOLON:
1367 	  /* If the next token is a ';', we have reached the
1368 	     end of the statement.  */
1369 	  if (!nesting_depth)
1370 	    {
1371 	      /* Consume the ';'.  */
1372 	      c_parser_consume_token (parser);
1373 	      goto finished;
1374 	    }
1375 	  break;
1376 
1377 	case CPP_CLOSE_BRACE:
1378 	  /* If the next token is a non-nested '}', then we have
1379 	     reached the end of the current block.  */
1380 	  if (nesting_depth == 0 || --nesting_depth == 0)
1381 	    {
1382 	      c_parser_consume_token (parser);
1383 	      goto finished;
1384 	    }
1385 	  break;
1386 
1387 	case CPP_OPEN_BRACE:
1388 	  /* If it the next token is a '{', then we are entering a new
1389 	     block.  Consume the entire block.  */
1390 	  ++nesting_depth;
1391 	  break;
1392 
1393 	case CPP_PRAGMA:
1394 	  /* If we see a pragma, consume the whole thing at once.  We
1395 	     have some safeguards against consuming pragmas willy-nilly.
1396 	     Normally, we'd expect to be here with parser->error set,
1397 	     which disables these safeguards.  But it's possible to get
1398 	     here for secondary error recovery, after parser->error has
1399 	     been cleared.  */
1400 	  c_parser_consume_pragma (parser);
1401 	  c_parser_skip_to_pragma_eol (parser);
1402 	  parser->error = save_error;
1403 	  continue;
1404 
1405 	default:
1406 	  break;
1407 	}
1408 
1409       c_parser_consume_token (parser);
1410     }
1411 
1412  finished:
1413   parser->error = false;
1414 }
1415 
1416 /* CPP's options (initialized by c-opts.cc).  */
1417 extern cpp_options *cpp_opts;
1418 
1419 /* Save the warning flags which are controlled by __extension__.  */
1420 
1421 static inline int
disable_extension_diagnostics(void)1422 disable_extension_diagnostics (void)
1423 {
1424   int ret = (pedantic
1425 	     | (warn_pointer_arith << 1)
1426 	     | (warn_traditional << 2)
1427 	     | (flag_iso << 3)
1428 	     | (warn_long_long << 4)
1429 	     | (warn_cxx_compat << 5)
1430 	     | (warn_overlength_strings << 6)
1431 	     /* warn_c90_c99_compat has three states: -1/0/1, so we must
1432 		play tricks to properly restore it.  */
1433 	     | ((warn_c90_c99_compat == 1) << 7)
1434 	     | ((warn_c90_c99_compat == -1) << 8)
1435 	     /* Similarly for warn_c99_c11_compat.  */
1436 	     | ((warn_c99_c11_compat == 1) << 9)
1437 	     | ((warn_c99_c11_compat == -1) << 10)
1438 	     /* Similarly for warn_c11_c2x_compat.  */
1439 	     | ((warn_c11_c2x_compat == 1) << 11)
1440 	     | ((warn_c11_c2x_compat == -1) << 12)
1441 	     );
1442   cpp_opts->cpp_pedantic = pedantic = 0;
1443   warn_pointer_arith = 0;
1444   cpp_opts->cpp_warn_traditional = warn_traditional = 0;
1445   flag_iso = 0;
1446   cpp_opts->cpp_warn_long_long = warn_long_long = 0;
1447   warn_cxx_compat = 0;
1448   warn_overlength_strings = 0;
1449   warn_c90_c99_compat = 0;
1450   warn_c99_c11_compat = 0;
1451   warn_c11_c2x_compat = 0;
1452   return ret;
1453 }
1454 
1455 /* Restore the warning flags which are controlled by __extension__.
1456    FLAGS is the return value from disable_extension_diagnostics.  */
1457 
1458 static inline void
restore_extension_diagnostics(int flags)1459 restore_extension_diagnostics (int flags)
1460 {
1461   cpp_opts->cpp_pedantic = pedantic = flags & 1;
1462   warn_pointer_arith = (flags >> 1) & 1;
1463   cpp_opts->cpp_warn_traditional = warn_traditional = (flags >> 2) & 1;
1464   flag_iso = (flags >> 3) & 1;
1465   cpp_opts->cpp_warn_long_long = warn_long_long = (flags >> 4) & 1;
1466   warn_cxx_compat = (flags >> 5) & 1;
1467   warn_overlength_strings = (flags >> 6) & 1;
1468   /* See above for why is this needed.  */
1469   warn_c90_c99_compat = (flags >> 7) & 1 ? 1 : ((flags >> 8) & 1 ? -1 : 0);
1470   warn_c99_c11_compat = (flags >> 9) & 1 ? 1 : ((flags >> 10) & 1 ? -1 : 0);
1471   warn_c11_c2x_compat = (flags >> 11) & 1 ? 1 : ((flags >> 12) & 1 ? -1 : 0);
1472 }
1473 
1474 /* Helper data structure for parsing #pragma acc routine.  */
1475 struct oacc_routine_data {
1476   bool error_seen; /* Set if error has been reported.  */
1477   bool fndecl_seen; /* Set if one fn decl/definition has been seen already.  */
1478   tree clauses;
1479   location_t loc;
1480 };
1481 
1482 /* Used for parsing objc foreach statements.  */
1483 static tree objc_foreach_break_label, objc_foreach_continue_label;
1484 
1485 static bool c_parser_nth_token_starts_std_attributes (c_parser *,
1486 						      unsigned int);
1487 static tree c_parser_std_attribute_specifier_sequence (c_parser *);
1488 static void c_parser_external_declaration (c_parser *);
1489 static void c_parser_asm_definition (c_parser *);
1490 static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
1491 					   bool, bool, tree * = NULL,
1492 					   vec<c_token> * = NULL,
1493 					   bool have_attrs = false,
1494 					   tree attrs = NULL,
1495 					   struct oacc_routine_data * = NULL,
1496 					   bool * = NULL);
1497 static void c_parser_static_assert_declaration_no_semi (c_parser *);
1498 static void c_parser_static_assert_declaration (c_parser *);
1499 static struct c_typespec c_parser_enum_specifier (c_parser *);
1500 static struct c_typespec c_parser_struct_or_union_specifier (c_parser *);
1501 static tree c_parser_struct_declaration (c_parser *);
1502 static struct c_typespec c_parser_typeof_specifier (c_parser *);
1503 static tree c_parser_alignas_specifier (c_parser *);
1504 static struct c_declarator *c_parser_direct_declarator (c_parser *, bool,
1505 							c_dtr_syn, bool *);
1506 static struct c_declarator *c_parser_direct_declarator_inner (c_parser *,
1507 							      bool,
1508 							      struct c_declarator *);
1509 static struct c_arg_info *c_parser_parms_declarator (c_parser *, bool, tree,
1510 						     bool);
1511 static struct c_arg_info *c_parser_parms_list_declarator (c_parser *, tree,
1512 							  tree, bool);
1513 static struct c_parm *c_parser_parameter_declaration (c_parser *, tree, bool);
1514 static tree c_parser_simple_asm_expr (c_parser *);
1515 static tree c_parser_gnu_attributes (c_parser *);
1516 static struct c_expr c_parser_initializer (c_parser *, tree);
1517 static struct c_expr c_parser_braced_init (c_parser *, tree, bool,
1518 					   struct obstack *);
1519 static void c_parser_initelt (c_parser *, struct obstack *);
1520 static void c_parser_initval (c_parser *, struct c_expr *,
1521 			      struct obstack *);
1522 static tree c_parser_compound_statement (c_parser *, location_t * = NULL);
1523 static location_t c_parser_compound_statement_nostart (c_parser *);
1524 static void c_parser_label (c_parser *, tree);
1525 static void c_parser_statement (c_parser *, bool *, location_t * = NULL);
1526 static void c_parser_statement_after_labels (c_parser *, bool *,
1527 					     vec<tree> * = NULL);
1528 static tree c_parser_c99_block_statement (c_parser *, bool *,
1529 					  location_t * = NULL);
1530 static void c_parser_if_statement (c_parser *, bool *, vec<tree> *);
1531 static void c_parser_switch_statement (c_parser *, bool *);
1532 static void c_parser_while_statement (c_parser *, bool, unsigned short, bool *);
1533 static void c_parser_do_statement (c_parser *, bool, unsigned short);
1534 static void c_parser_for_statement (c_parser *, bool, unsigned short, bool *);
1535 static tree c_parser_asm_statement (c_parser *);
1536 static tree c_parser_asm_operands (c_parser *);
1537 static tree c_parser_asm_goto_operands (c_parser *);
1538 static tree c_parser_asm_clobbers (c_parser *);
1539 static struct c_expr c_parser_expr_no_commas (c_parser *, struct c_expr *,
1540 					      tree = NULL_TREE);
1541 static struct c_expr c_parser_conditional_expression (c_parser *,
1542 						      struct c_expr *, tree);
1543 static struct c_expr c_parser_binary_expression (c_parser *, struct c_expr *,
1544 						 tree);
1545 static struct c_expr c_parser_cast_expression (c_parser *, struct c_expr *);
1546 static struct c_expr c_parser_unary_expression (c_parser *);
1547 static struct c_expr c_parser_sizeof_expression (c_parser *);
1548 static struct c_expr c_parser_alignof_expression (c_parser *);
1549 static struct c_expr c_parser_postfix_expression (c_parser *);
1550 static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *,
1551 								   struct c_type_name *,
1552 								   location_t);
1553 static struct c_expr c_parser_postfix_expression_after_primary (c_parser *,
1554 								location_t loc,
1555 								struct c_expr);
1556 static tree c_parser_transaction (c_parser *, enum rid);
1557 static struct c_expr c_parser_transaction_expression (c_parser *, enum rid);
1558 static tree c_parser_transaction_cancel (c_parser *);
1559 static struct c_expr c_parser_expression (c_parser *);
1560 static struct c_expr c_parser_expression_conv (c_parser *);
1561 static vec<tree, va_gc> *c_parser_expr_list (c_parser *, bool, bool,
1562 					     vec<tree, va_gc> **, location_t *,
1563 					     tree *, vec<location_t> *,
1564 					     unsigned int * = NULL);
1565 static struct c_expr c_parser_has_attribute_expression (c_parser *);
1566 
1567 static void c_parser_oacc_declare (c_parser *);
1568 static void c_parser_oacc_enter_exit_data (c_parser *, bool);
1569 static void c_parser_oacc_update (c_parser *);
1570 static void c_parser_omp_construct (c_parser *, bool *);
1571 static void c_parser_omp_threadprivate (c_parser *);
1572 static void c_parser_omp_barrier (c_parser *);
1573 static void c_parser_omp_depobj (c_parser *);
1574 static void c_parser_omp_flush (c_parser *);
1575 static tree c_parser_omp_for_loop (location_t, c_parser *, enum tree_code,
1576 				   tree, tree *, bool *);
1577 static void c_parser_omp_taskwait (c_parser *);
1578 static void c_parser_omp_taskyield (c_parser *);
1579 static void c_parser_omp_cancel (c_parser *);
1580 static void c_parser_omp_nothing (c_parser *);
1581 
1582 enum pragma_context { pragma_external, pragma_struct, pragma_param,
1583 		      pragma_stmt, pragma_compound };
1584 static bool c_parser_pragma (c_parser *, enum pragma_context, bool *);
1585 static bool c_parser_omp_cancellation_point (c_parser *, enum pragma_context);
1586 static bool c_parser_omp_target (c_parser *, enum pragma_context, bool *);
1587 static void c_parser_omp_end_declare_target (c_parser *);
1588 static bool c_parser_omp_declare (c_parser *, enum pragma_context);
1589 static void c_parser_omp_requires (c_parser *);
1590 static bool c_parser_omp_error (c_parser *, enum pragma_context);
1591 static bool c_parser_omp_ordered (c_parser *, enum pragma_context, bool *);
1592 static void c_parser_oacc_routine (c_parser *, enum pragma_context);
1593 
1594 /* These Objective-C parser functions are only ever called when
1595    compiling Objective-C.  */
1596 static void c_parser_objc_class_definition (c_parser *, tree);
1597 static void c_parser_objc_class_instance_variables (c_parser *);
1598 static void c_parser_objc_class_declaration (c_parser *);
1599 static void c_parser_objc_alias_declaration (c_parser *);
1600 static void c_parser_objc_protocol_definition (c_parser *, tree);
1601 static bool c_parser_objc_method_type (c_parser *);
1602 static void c_parser_objc_method_definition (c_parser *);
1603 static void c_parser_objc_methodprotolist (c_parser *);
1604 static void c_parser_objc_methodproto (c_parser *);
1605 static tree c_parser_objc_method_decl (c_parser *, bool, tree *, tree *);
1606 static tree c_parser_objc_type_name (c_parser *);
1607 static tree c_parser_objc_protocol_refs (c_parser *);
1608 static void c_parser_objc_try_catch_finally_statement (c_parser *);
1609 static void c_parser_objc_synchronized_statement (c_parser *);
1610 static tree c_parser_objc_selector (c_parser *);
1611 static tree c_parser_objc_selector_arg (c_parser *);
1612 static tree c_parser_objc_receiver (c_parser *);
1613 static tree c_parser_objc_message_args (c_parser *);
1614 static tree c_parser_objc_keywordexpr (c_parser *);
1615 static void c_parser_objc_at_property_declaration (c_parser *);
1616 static void c_parser_objc_at_synthesize_declaration (c_parser *);
1617 static void c_parser_objc_at_dynamic_declaration (c_parser *);
1618 static bool c_parser_objc_diagnose_bad_element_prefix
1619   (c_parser *, struct c_declspecs *);
1620 static location_t c_parser_parse_rtl_body (c_parser *, char *);
1621 
1622 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
1623 
1624    translation-unit:
1625      external-declarations
1626 
1627    external-declarations:
1628      external-declaration
1629      external-declarations external-declaration
1630 
1631    GNU extensions:
1632 
1633    translation-unit:
1634      empty
1635 */
1636 
1637 static void
c_parser_translation_unit(c_parser * parser)1638 c_parser_translation_unit (c_parser *parser)
1639 {
1640   if (c_parser_next_token_is (parser, CPP_EOF))
1641     {
1642       pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1643 	       "ISO C forbids an empty translation unit");
1644     }
1645   else
1646     {
1647       void *obstack_position = obstack_alloc (&parser_obstack, 0);
1648       mark_valid_location_for_stdc_pragma (false);
1649       do
1650 	{
1651 	  ggc_collect ();
1652 	  c_parser_external_declaration (parser);
1653 	  obstack_free (&parser_obstack, obstack_position);
1654 	}
1655       while (c_parser_next_token_is_not (parser, CPP_EOF));
1656     }
1657 
1658   unsigned int i;
1659   tree decl;
1660   FOR_EACH_VEC_ELT (incomplete_record_decls, i, decl)
1661     if (DECL_SIZE (decl) == NULL_TREE && TREE_TYPE (decl) != error_mark_node)
1662       error ("storage size of %q+D isn%'t known", decl);
1663 
1664   if (current_omp_declare_target_attribute)
1665     {
1666       if (!errorcount)
1667         error ("%<#pragma omp declare target%> without corresponding "
1668 	       "%<#pragma omp end declare target%>");
1669       current_omp_declare_target_attribute = 0;
1670     }
1671 }
1672 
1673 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
1674 
1675    external-declaration:
1676      function-definition
1677      declaration
1678 
1679    GNU extensions:
1680 
1681    external-declaration:
1682      asm-definition
1683      ;
1684      __extension__ external-declaration
1685 
1686    Objective-C:
1687 
1688    external-declaration:
1689      objc-class-definition
1690      objc-class-declaration
1691      objc-alias-declaration
1692      objc-protocol-definition
1693      objc-method-definition
1694      @end
1695 */
1696 
1697 static void
c_parser_external_declaration(c_parser * parser)1698 c_parser_external_declaration (c_parser *parser)
1699 {
1700   int ext;
1701   switch (c_parser_peek_token (parser)->type)
1702     {
1703     case CPP_KEYWORD:
1704       switch (c_parser_peek_token (parser)->keyword)
1705 	{
1706 	case RID_EXTENSION:
1707 	  ext = disable_extension_diagnostics ();
1708 	  c_parser_consume_token (parser);
1709 	  c_parser_external_declaration (parser);
1710 	  restore_extension_diagnostics (ext);
1711 	  break;
1712 	case RID_ASM:
1713 	  c_parser_asm_definition (parser);
1714 	  break;
1715 	case RID_AT_INTERFACE:
1716 	case RID_AT_IMPLEMENTATION:
1717 	  gcc_assert (c_dialect_objc ());
1718 	  c_parser_objc_class_definition (parser, NULL_TREE);
1719 	  break;
1720 	case RID_AT_CLASS:
1721 	  gcc_assert (c_dialect_objc ());
1722 	  c_parser_objc_class_declaration (parser);
1723 	  break;
1724 	case RID_AT_ALIAS:
1725 	  gcc_assert (c_dialect_objc ());
1726 	  c_parser_objc_alias_declaration (parser);
1727 	  break;
1728 	case RID_AT_PROTOCOL:
1729 	  gcc_assert (c_dialect_objc ());
1730 	  c_parser_objc_protocol_definition (parser, NULL_TREE);
1731 	  break;
1732 	case RID_AT_PROPERTY:
1733 	  gcc_assert (c_dialect_objc ());
1734 	  c_parser_objc_at_property_declaration (parser);
1735 	  break;
1736 	case RID_AT_SYNTHESIZE:
1737 	  gcc_assert (c_dialect_objc ());
1738 	  c_parser_objc_at_synthesize_declaration (parser);
1739 	  break;
1740 	case RID_AT_DYNAMIC:
1741 	  gcc_assert (c_dialect_objc ());
1742 	  c_parser_objc_at_dynamic_declaration (parser);
1743 	  break;
1744 	case RID_AT_END:
1745 	  gcc_assert (c_dialect_objc ());
1746 	  c_parser_consume_token (parser);
1747 	  objc_finish_implementation ();
1748 	  break;
1749 	default:
1750 	  goto decl_or_fndef;
1751 	}
1752       break;
1753     case CPP_SEMICOLON:
1754       pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1755 	       "ISO C does not allow extra %<;%> outside of a function");
1756       c_parser_consume_token (parser);
1757       break;
1758     case CPP_PRAGMA:
1759       mark_valid_location_for_stdc_pragma (true);
1760       c_parser_pragma (parser, pragma_external, NULL);
1761       mark_valid_location_for_stdc_pragma (false);
1762       break;
1763     case CPP_PLUS:
1764     case CPP_MINUS:
1765       if (c_dialect_objc ())
1766 	{
1767 	  c_parser_objc_method_definition (parser);
1768 	  break;
1769 	}
1770       /* Else fall through, and yield a syntax error trying to parse
1771 	 as a declaration or function definition.  */
1772       /* FALLTHRU */
1773     default:
1774     decl_or_fndef:
1775       /* A declaration or a function definition (or, in Objective-C,
1776 	 an @interface or @protocol with prefix attributes).  We can
1777 	 only tell which after parsing the declaration specifiers, if
1778 	 any, and the first declarator.  */
1779       c_parser_declaration_or_fndef (parser, true, true, true, false, true);
1780       break;
1781     }
1782 }
1783 
1784 static void c_finish_omp_declare_simd (c_parser *, tree, tree, vec<c_token> *);
1785 static void c_finish_oacc_routine (struct oacc_routine_data *, tree, bool);
1786 
1787 /* Build and add a DEBUG_BEGIN_STMT statement with location LOC.  */
1788 
1789 static void
add_debug_begin_stmt(location_t loc)1790 add_debug_begin_stmt (location_t loc)
1791 {
1792   /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721.  */
1793   if (!MAY_HAVE_DEBUG_MARKER_STMTS || !building_stmt_list_p ())
1794     return;
1795 
1796   tree stmt = build0 (DEBUG_BEGIN_STMT, void_type_node);
1797   SET_EXPR_LOCATION (stmt, loc);
1798   add_stmt (stmt);
1799 }
1800 
1801 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
1802    6.7, 6.9.1, C11 6.7, 6.9.1).  If FNDEF_OK is true, a function definition
1803    is accepted; otherwise (old-style parameter declarations) only other
1804    declarations are accepted.  If STATIC_ASSERT_OK is true, a static
1805    assertion is accepted; otherwise (old-style parameter declarations)
1806    it is not.  If NESTED is true, we are inside a function or parsing
1807    old-style parameter declarations; any functions encountered are
1808    nested functions and declaration specifiers are required; otherwise
1809    we are at top level and functions are normal functions and
1810    declaration specifiers may be optional.  If EMPTY_OK is true, empty
1811    declarations are OK (subject to all other constraints); otherwise
1812    (old-style parameter declarations) they are diagnosed.  If
1813    START_ATTR_OK is true, the declaration specifiers may start with
1814    attributes (GNU or standard); otherwise they may not.
1815    OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
1816    declaration when parsing an Objective-C foreach statement.
1817    FALLTHRU_ATTR_P is used to signal whether this function parsed
1818    "__attribute__((fallthrough));".  ATTRS are any standard attributes
1819    parsed in the caller (in contexts where such attributes had to be
1820    parsed to determine whether what follows is a declaration or a
1821    statement); HAVE_ATTRS says whether there were any such attributes
1822    (even empty).
1823 
1824    declaration:
1825      declaration-specifiers init-declarator-list[opt] ;
1826      static_assert-declaration
1827 
1828    function-definition:
1829      declaration-specifiers[opt] declarator declaration-list[opt]
1830        compound-statement
1831 
1832    declaration-list:
1833      declaration
1834      declaration-list declaration
1835 
1836    init-declarator-list:
1837      init-declarator
1838      init-declarator-list , init-declarator
1839 
1840    init-declarator:
1841      declarator simple-asm-expr[opt] gnu-attributes[opt]
1842      declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
1843 
1844    GNU extensions:
1845 
1846    nested-function-definition:
1847      declaration-specifiers declarator declaration-list[opt]
1848        compound-statement
1849 
1850    attribute ;
1851 
1852    Objective-C:
1853      gnu-attributes objc-class-definition
1854      gnu-attributes objc-category-definition
1855      gnu-attributes objc-protocol-definition
1856 
1857    The simple-asm-expr and gnu-attributes are GNU extensions.
1858 
1859    This function does not handle __extension__; that is handled in its
1860    callers.  ??? Following the old parser, __extension__ may start
1861    external declarations, declarations in functions and declarations
1862    at the start of "for" loops, but not old-style parameter
1863    declarations.
1864 
1865    C99 requires declaration specifiers in a function definition; the
1866    absence is diagnosed through the diagnosis of implicit int.  In GNU
1867    C we also allow but diagnose declarations without declaration
1868    specifiers, but only at top level (elsewhere they conflict with
1869    other syntax).
1870 
1871    In Objective-C, declarations of the looping variable in a foreach
1872    statement are exceptionally terminated by 'in' (for example, 'for
1873    (NSObject *object in array) { ... }').
1874 
1875    OpenMP:
1876 
1877    declaration:
1878      threadprivate-directive
1879 
1880    GIMPLE:
1881 
1882    gimple-function-definition:
1883      declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
1884        declaration-list[opt] compound-statement
1885 
1886    rtl-function-definition:
1887      declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
1888        declaration-list[opt] compound-statement  */
1889 
1890 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)1891 c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
1892 			       bool static_assert_ok, bool empty_ok,
1893 			       bool nested, bool start_attr_ok,
1894 			       tree *objc_foreach_object_declaration
1895 			       /* = NULL */,
1896 			       vec<c_token> *omp_declare_simd_clauses
1897 			       /* = NULL */,
1898 			       bool have_attrs /* = false */,
1899 			       tree attrs /* = NULL_TREE */,
1900 			       struct oacc_routine_data *oacc_routine_data
1901 			       /* = NULL */,
1902 			       bool *fallthru_attr_p /* = NULL */)
1903 {
1904   struct c_declspecs *specs;
1905   tree prefix_attrs;
1906   tree all_prefix_attrs;
1907   bool diagnosed_no_specs = false;
1908   location_t here = c_parser_peek_token (parser)->location;
1909 
1910   add_debug_begin_stmt (c_parser_peek_token (parser)->location);
1911 
1912   if (static_assert_ok
1913       && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
1914     {
1915       c_parser_static_assert_declaration (parser);
1916       return;
1917     }
1918   specs = build_null_declspecs ();
1919 
1920   /* Handle any standard attributes parsed in the caller.  */
1921   if (have_attrs)
1922     {
1923       declspecs_add_attrs (here, specs, attrs);
1924       specs->non_std_attrs_seen_p = false;
1925     }
1926 
1927   /* Try to detect an unknown type name when we have "A B" or "A *B".  */
1928   if (c_parser_peek_token (parser)->type == CPP_NAME
1929       && c_parser_peek_token (parser)->id_kind == C_ID_ID
1930       && (c_parser_peek_2nd_token (parser)->type == CPP_NAME
1931           || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
1932       && (!nested || !lookup_name (c_parser_peek_token (parser)->value)))
1933     {
1934       tree name = c_parser_peek_token (parser)->value;
1935 
1936       /* Issue a warning about NAME being an unknown type name, perhaps
1937 	 with some kind of hint.
1938 	 If the user forgot a "struct" etc, suggest inserting
1939 	 it.  Otherwise, attempt to look for misspellings.  */
1940       gcc_rich_location richloc (here);
1941       if (tag_exists_p (RECORD_TYPE, name))
1942 	{
1943 	  /* This is not C++ with its implicit typedef.  */
1944 	  richloc.add_fixit_insert_before ("struct ");
1945 	  error_at (&richloc,
1946 		    "unknown type name %qE;"
1947 		    " use %<struct%> keyword to refer to the type",
1948 		    name);
1949 	}
1950       else if (tag_exists_p (UNION_TYPE, name))
1951 	{
1952 	  richloc.add_fixit_insert_before ("union ");
1953 	  error_at (&richloc,
1954 		    "unknown type name %qE;"
1955 		    " use %<union%> keyword to refer to the type",
1956 		    name);
1957 	}
1958       else if (tag_exists_p (ENUMERAL_TYPE, name))
1959 	{
1960 	  richloc.add_fixit_insert_before ("enum ");
1961 	  error_at (&richloc,
1962 		    "unknown type name %qE;"
1963 		    " use %<enum%> keyword to refer to the type",
1964 		    name);
1965 	}
1966       else
1967 	{
1968 	  auto_diagnostic_group d;
1969 	  name_hint hint = lookup_name_fuzzy (name, FUZZY_LOOKUP_TYPENAME,
1970 					      here);
1971 	  if (const char *suggestion = hint.suggestion ())
1972 	    {
1973 	      richloc.add_fixit_replace (suggestion);
1974 	      error_at (&richloc,
1975 			"unknown type name %qE; did you mean %qs?",
1976 			name, suggestion);
1977 	    }
1978 	  else
1979 	    error_at (here, "unknown type name %qE", name);
1980 	}
1981 
1982       /* Parse declspecs normally to get a correct pointer type, but avoid
1983          a further "fails to be a type name" error.  Refuse nested functions
1984          since it is not how the user likely wants us to recover.  */
1985       c_parser_peek_token (parser)->type = CPP_KEYWORD;
1986       c_parser_peek_token (parser)->keyword = RID_VOID;
1987       c_parser_peek_token (parser)->value = error_mark_node;
1988       fndef_ok = !nested;
1989     }
1990 
1991   /* When there are standard attributes at the start of the
1992      declaration (to apply to the entity being declared), an
1993      init-declarator-list or function definition must be present.  */
1994   if (c_parser_nth_token_starts_std_attributes (parser, 1))
1995     have_attrs = true;
1996 
1997   c_parser_declspecs (parser, specs, true, true, start_attr_ok,
1998 		      true, true, start_attr_ok, true, cla_nonabstract_decl);
1999   if (parser->error)
2000     {
2001       c_parser_skip_to_end_of_block_or_statement (parser);
2002       return;
2003     }
2004   if (nested && !specs->declspecs_seen_p)
2005     {
2006       c_parser_error (parser, "expected declaration specifiers");
2007       c_parser_skip_to_end_of_block_or_statement (parser);
2008       return;
2009     }
2010 
2011   finish_declspecs (specs);
2012   bool auto_type_p = specs->typespec_word == cts_auto_type;
2013   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2014     {
2015       if (auto_type_p)
2016 	error_at (here, "%<__auto_type%> in empty declaration");
2017       else if (specs->typespec_kind == ctsk_none
2018 	       && attribute_fallthrough_p (specs->attrs))
2019 	{
2020 	  if (fallthru_attr_p != NULL)
2021 	    *fallthru_attr_p = true;
2022 	  if (nested)
2023 	    {
2024 	      tree fn = build_call_expr_internal_loc (here, IFN_FALLTHROUGH,
2025 						      void_type_node, 0);
2026 	      add_stmt (fn);
2027 	    }
2028 	  else
2029 	    pedwarn (here, OPT_Wattributes,
2030 		     "%<fallthrough%> attribute at top level");
2031 	}
2032       else if (empty_ok && !(have_attrs
2033 			     && specs->non_std_attrs_seen_p))
2034 	shadow_tag (specs);
2035       else
2036 	{
2037 	  shadow_tag_warned (specs, 1);
2038 	  pedwarn (here, 0, "empty declaration");
2039 	}
2040       c_parser_consume_token (parser);
2041       if (oacc_routine_data)
2042 	c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2043       return;
2044     }
2045 
2046   /* Provide better error recovery.  Note that a type name here is usually
2047      better diagnosed as a redeclaration.  */
2048   if (empty_ok
2049       && specs->typespec_kind == ctsk_tagdef
2050       && c_parser_next_token_starts_declspecs (parser)
2051       && !c_parser_next_token_is (parser, CPP_NAME))
2052     {
2053       c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
2054       parser->error = false;
2055       shadow_tag_warned (specs, 1);
2056       return;
2057     }
2058   else if (c_dialect_objc () && !auto_type_p)
2059     {
2060       /* Prefix attributes are an error on method decls.  */
2061       switch (c_parser_peek_token (parser)->type)
2062 	{
2063 	  case CPP_PLUS:
2064 	  case CPP_MINUS:
2065 	    if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2066 	      return;
2067 	    if (specs->attrs)
2068 	      {
2069 		warning_at (c_parser_peek_token (parser)->location,
2070 			    OPT_Wattributes,
2071 	       		    "prefix attributes are ignored for methods");
2072 		specs->attrs = NULL_TREE;
2073 	      }
2074 	    if (fndef_ok)
2075 	      c_parser_objc_method_definition (parser);
2076 	    else
2077 	      c_parser_objc_methodproto (parser);
2078 	    return;
2079 	    break;
2080 	  default:
2081 	    break;
2082 	}
2083       /* This is where we parse 'attributes @interface ...',
2084 	 'attributes @implementation ...', 'attributes @protocol ...'
2085 	 (where attributes could be, for example, __attribute__
2086 	 ((deprecated)).
2087       */
2088       switch (c_parser_peek_token (parser)->keyword)
2089 	{
2090 	case RID_AT_INTERFACE:
2091 	  {
2092 	    if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2093 	      return;
2094 	    c_parser_objc_class_definition (parser, specs->attrs);
2095 	    return;
2096 	  }
2097 	  break;
2098 	case RID_AT_IMPLEMENTATION:
2099 	  {
2100 	    if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2101 	      return;
2102 	    if (specs->attrs)
2103 	      {
2104 		warning_at (c_parser_peek_token (parser)->location,
2105 			OPT_Wattributes,
2106 			"prefix attributes are ignored for implementations");
2107 		specs->attrs = NULL_TREE;
2108 	      }
2109 	    c_parser_objc_class_definition (parser, NULL_TREE);
2110 	    return;
2111 	  }
2112 	  break;
2113 	case RID_AT_PROTOCOL:
2114 	  {
2115 	    if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2116 	      return;
2117 	    c_parser_objc_protocol_definition (parser, specs->attrs);
2118 	    return;
2119 	  }
2120 	  break;
2121 	case RID_AT_ALIAS:
2122 	case RID_AT_CLASS:
2123 	case RID_AT_END:
2124 	case RID_AT_PROPERTY:
2125 	  if (specs->attrs)
2126 	    {
2127 	      c_parser_error (parser, "unexpected attribute");
2128 	      specs->attrs = NULL;
2129 	    }
2130 	  break;
2131 	default:
2132 	  break;
2133 	}
2134     }
2135   else if (attribute_fallthrough_p (specs->attrs))
2136     warning_at (here, OPT_Wattributes,
2137 		"%<fallthrough%> attribute not followed by %<;%>");
2138 
2139   pending_xref_error ();
2140   prefix_attrs = specs->attrs;
2141   all_prefix_attrs = prefix_attrs;
2142   specs->attrs = NULL_TREE;
2143   while (true)
2144     {
2145       struct c_declarator *declarator;
2146       bool dummy = false;
2147       timevar_id_t tv;
2148       tree fnbody = NULL_TREE;
2149       /* Declaring either one or more declarators (in which case we
2150 	 should diagnose if there were no declaration specifiers) or a
2151 	 function definition (in which case the diagnostic for
2152 	 implicit int suffices).  */
2153       declarator = c_parser_declarator (parser,
2154 					specs->typespec_kind != ctsk_none,
2155 					C_DTR_NORMAL, &dummy);
2156       if (declarator == NULL)
2157 	{
2158 	  if (omp_declare_simd_clauses)
2159 	    c_finish_omp_declare_simd (parser, NULL_TREE, NULL_TREE,
2160 				       omp_declare_simd_clauses);
2161 	  if (oacc_routine_data)
2162 	    c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2163 	  c_parser_skip_to_end_of_block_or_statement (parser);
2164 	  return;
2165 	}
2166       if (auto_type_p && declarator->kind != cdk_id)
2167 	{
2168 	  error_at (here,
2169 		    "%<__auto_type%> requires a plain identifier"
2170 		    " as declarator");
2171 	  c_parser_skip_to_end_of_block_or_statement (parser);
2172 	  return;
2173 	}
2174       if (c_parser_next_token_is (parser, CPP_EQ)
2175 	  || c_parser_next_token_is (parser, CPP_COMMA)
2176 	  || c_parser_next_token_is (parser, CPP_SEMICOLON)
2177 	  || c_parser_next_token_is_keyword (parser, RID_ASM)
2178 	  || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)
2179 	  || c_parser_next_token_is_keyword (parser, RID_IN))
2180 	{
2181 	  tree asm_name = NULL_TREE;
2182 	  tree postfix_attrs = NULL_TREE;
2183 	  if (!diagnosed_no_specs && !specs->declspecs_seen_p)
2184 	    {
2185 	      diagnosed_no_specs = true;
2186 	      pedwarn (here, 0, "data definition has no type or storage class");
2187 	    }
2188 	  /* Having seen a data definition, there cannot now be a
2189 	     function definition.  */
2190 	  fndef_ok = false;
2191 	  if (c_parser_next_token_is_keyword (parser, RID_ASM))
2192 	    asm_name = c_parser_simple_asm_expr (parser);
2193 	  if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2194 	    {
2195 	      postfix_attrs = c_parser_gnu_attributes (parser);
2196 	      if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
2197 		{
2198 		  /* This means there is an attribute specifier after
2199 		     the declarator in a function definition.  Provide
2200 		     some more information for the user.  */
2201 		  error_at (here, "attributes should be specified before the "
2202 			    "declarator in a function definition");
2203 		  c_parser_skip_to_end_of_block_or_statement (parser);
2204 		  return;
2205 		}
2206 	    }
2207 	  if (c_parser_next_token_is (parser, CPP_EQ))
2208 	    {
2209 	      tree d;
2210 	      struct c_expr init;
2211 	      location_t init_loc;
2212 	      c_parser_consume_token (parser);
2213 	      if (auto_type_p)
2214 		{
2215 		  init_loc = c_parser_peek_token (parser)->location;
2216 		  rich_location richloc (line_table, init_loc);
2217 		  start_init (NULL_TREE, asm_name, global_bindings_p (), &richloc);
2218 		  /* A parameter is initialized, which is invalid.  Don't
2219 		     attempt to instrument the initializer.  */
2220 		  int flag_sanitize_save = flag_sanitize;
2221 		  if (nested && !empty_ok)
2222 		    flag_sanitize = 0;
2223 		  init = c_parser_expr_no_commas (parser, NULL);
2224 		  flag_sanitize = flag_sanitize_save;
2225 		  if (TREE_CODE (init.value) == COMPONENT_REF
2226 		      && DECL_C_BIT_FIELD (TREE_OPERAND (init.value, 1)))
2227 		    error_at (here,
2228 			      "%<__auto_type%> used with a bit-field"
2229 			      " initializer");
2230 		  init = convert_lvalue_to_rvalue (init_loc, init, true, true);
2231 		  tree init_type = TREE_TYPE (init.value);
2232 		  bool vm_type = variably_modified_type_p (init_type,
2233 							   NULL_TREE);
2234 		  if (vm_type)
2235 		    init.value = save_expr (init.value);
2236 		  finish_init ();
2237 		  specs->typespec_kind = ctsk_typeof;
2238 		  specs->locations[cdw_typedef] = init_loc;
2239 		  specs->typedef_p = true;
2240 		  specs->type = init_type;
2241 		  if (vm_type)
2242 		    {
2243 		      bool maybe_const = true;
2244 		      tree type_expr = c_fully_fold (init.value, false,
2245 						     &maybe_const);
2246 		      specs->expr_const_operands &= maybe_const;
2247 		      if (specs->expr)
2248 			specs->expr = build2 (COMPOUND_EXPR,
2249 					      TREE_TYPE (type_expr),
2250 					      specs->expr, type_expr);
2251 		      else
2252 			specs->expr = type_expr;
2253 		    }
2254 		  d = start_decl (declarator, specs, true,
2255 				  chainon (postfix_attrs, all_prefix_attrs));
2256 		  if (!d)
2257 		    d = error_mark_node;
2258 		  if (omp_declare_simd_clauses)
2259 		    c_finish_omp_declare_simd (parser, d, NULL_TREE,
2260 					       omp_declare_simd_clauses);
2261 		}
2262 	      else
2263 		{
2264 		  /* The declaration of the variable is in effect while
2265 		     its initializer is parsed.  */
2266 		  d = start_decl (declarator, specs, true,
2267 				  chainon (postfix_attrs, all_prefix_attrs));
2268 		  if (!d)
2269 		    d = error_mark_node;
2270 		  if (omp_declare_simd_clauses)
2271 		    c_finish_omp_declare_simd (parser, d, NULL_TREE,
2272 					       omp_declare_simd_clauses);
2273 		  init_loc = c_parser_peek_token (parser)->location;
2274 		  rich_location richloc (line_table, init_loc);
2275 		  start_init (d, asm_name, global_bindings_p (), &richloc);
2276 		  /* A parameter is initialized, which is invalid.  Don't
2277 		     attempt to instrument the initializer.  */
2278 		  int flag_sanitize_save = flag_sanitize;
2279 		  if (TREE_CODE (d) == PARM_DECL)
2280 		    flag_sanitize = 0;
2281 		  init = c_parser_initializer (parser, d);
2282 		  flag_sanitize = flag_sanitize_save;
2283 		  finish_init ();
2284 		}
2285 	      if (oacc_routine_data)
2286 		c_finish_oacc_routine (oacc_routine_data, d, false);
2287 	      if (d != error_mark_node)
2288 		{
2289 		  maybe_warn_string_init (init_loc, TREE_TYPE (d), init);
2290 		  finish_decl (d, init_loc, init.value,
2291 			       init.original_type, asm_name);
2292 		}
2293 	    }
2294 	  else
2295 	    {
2296 	      if (auto_type_p)
2297 		{
2298 		  error_at (here,
2299 			    "%<__auto_type%> requires an initialized "
2300 			    "data declaration");
2301 		  c_parser_skip_to_end_of_block_or_statement (parser);
2302 		  return;
2303 		}
2304 
2305 	      location_t lastloc = UNKNOWN_LOCATION;
2306 	      tree attrs = chainon (postfix_attrs, all_prefix_attrs);
2307 	      tree d = start_decl (declarator, specs, false, attrs, &lastloc);
2308 	      if (d && TREE_CODE (d) == FUNCTION_DECL)
2309 		{
2310 		  /* Find the innermost declarator that is neither cdk_id
2311 		     nor cdk_attrs.  */
2312 		  const struct c_declarator *decl = declarator;
2313 		  const struct c_declarator *last_non_id_attrs = NULL;
2314 
2315 		  while (decl)
2316 		    switch (decl->kind)
2317 		      {
2318 		      case cdk_array:
2319 		      case cdk_function:
2320 		      case cdk_pointer:
2321 			last_non_id_attrs = decl;
2322 			decl = decl->declarator;
2323 			break;
2324 
2325 		      case cdk_attrs:
2326 			decl = decl->declarator;
2327 			break;
2328 
2329 		      case cdk_id:
2330 			decl = 0;
2331 			break;
2332 
2333 		      default:
2334 			gcc_unreachable ();
2335 		      }
2336 
2337 		  /* If it exists and is cdk_function declaration whose
2338 		     arguments have not been set yet, use its arguments.  */
2339 		  if (last_non_id_attrs
2340 		      && last_non_id_attrs->kind == cdk_function)
2341 		    {
2342 		      tree parms = last_non_id_attrs->u.arg_info->parms;
2343 		      if (DECL_ARGUMENTS (d) == NULL_TREE
2344 			  && DECL_INITIAL (d) == NULL_TREE)
2345 			DECL_ARGUMENTS (d) = parms;
2346 
2347 		      warn_parm_array_mismatch (lastloc, d, parms);
2348 		    }
2349 		}
2350 	      if (omp_declare_simd_clauses)
2351 		{
2352 		  tree parms = NULL_TREE;
2353 		  if (d && TREE_CODE (d) == FUNCTION_DECL)
2354 		    {
2355 		      struct c_declarator *ce = declarator;
2356 		      while (ce != NULL)
2357 			if (ce->kind == cdk_function)
2358 			  {
2359 			    parms = ce->u.arg_info->parms;
2360 			    break;
2361 			  }
2362 			else
2363 			  ce = ce->declarator;
2364 		    }
2365 		  if (parms)
2366 		    temp_store_parm_decls (d, parms);
2367 		  c_finish_omp_declare_simd (parser, d, parms,
2368 					     omp_declare_simd_clauses);
2369 		  if (parms)
2370 		    temp_pop_parm_decls ();
2371 		}
2372 	      if (oacc_routine_data)
2373 		c_finish_oacc_routine (oacc_routine_data, d, false);
2374 	      if (d)
2375 		finish_decl (d, UNKNOWN_LOCATION, NULL_TREE,
2376 			     NULL_TREE, asm_name);
2377 
2378 	      if (c_parser_next_token_is_keyword (parser, RID_IN))
2379 		{
2380 		  if (d)
2381 		    *objc_foreach_object_declaration = d;
2382 		  else
2383 		    *objc_foreach_object_declaration = error_mark_node;
2384 		}
2385 	    }
2386 	  if (c_parser_next_token_is (parser, CPP_COMMA))
2387 	    {
2388 	      if (auto_type_p)
2389 		{
2390 		  error_at (here,
2391 			    "%<__auto_type%> may only be used with"
2392 			    " a single declarator");
2393 		  c_parser_skip_to_end_of_block_or_statement (parser);
2394 		  return;
2395 		}
2396 	      c_parser_consume_token (parser);
2397 	      if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2398 		all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
2399 					    prefix_attrs);
2400 	      else
2401 		all_prefix_attrs = prefix_attrs;
2402 	      continue;
2403 	    }
2404 	  else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2405 	    {
2406 	      c_parser_consume_token (parser);
2407 	      return;
2408 	    }
2409 	  else if (c_parser_next_token_is_keyword (parser, RID_IN))
2410 	    {
2411 	      /* This can only happen in Objective-C: we found the
2412 		 'in' that terminates the declaration inside an
2413 		 Objective-C foreach statement.  Do not consume the
2414 		 token, so that the caller can use it to determine
2415 		 that this indeed is a foreach context.  */
2416 	      return;
2417 	    }
2418 	  else
2419 	    {
2420 	      c_parser_error (parser, "expected %<,%> or %<;%>");
2421 	      c_parser_skip_to_end_of_block_or_statement (parser);
2422 	      return;
2423 	    }
2424 	}
2425       else if (auto_type_p)
2426 	{
2427 	  error_at (here,
2428 		    "%<__auto_type%> requires an initialized data declaration");
2429 	  c_parser_skip_to_end_of_block_or_statement (parser);
2430 	  return;
2431 	}
2432       else if (!fndef_ok)
2433 	{
2434 	  c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, "
2435 			  "%<asm%> or %<__attribute__%>");
2436 	  c_parser_skip_to_end_of_block_or_statement (parser);
2437 	  return;
2438 	}
2439       /* Function definition (nested or otherwise).  */
2440       if (nested)
2441 	{
2442 	  pedwarn (here, OPT_Wpedantic, "ISO C forbids nested functions");
2443 	  c_push_function_context ();
2444 	}
2445       if (!start_function (specs, declarator, all_prefix_attrs))
2446 	{
2447 	  /* At this point we've consumed:
2448 	       declaration-specifiers declarator
2449 	     and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2450 	     RID_ASM, RID_ATTRIBUTE, or RID_IN,
2451 	     but the
2452 	       declaration-specifiers declarator
2453 	     aren't grokkable as a function definition, so we have
2454 	     an error.  */
2455 	  gcc_assert (!c_parser_next_token_is (parser, CPP_SEMICOLON));
2456 	  if (c_parser_next_token_starts_declspecs (parser))
2457 	    {
2458 	      /* If we have
2459 		   declaration-specifiers declarator decl-specs
2460 		 then assume we have a missing semicolon, which would
2461 		 give us:
2462 		   declaration-specifiers declarator  decl-specs
2463 						    ^
2464 						    ;
2465 		   <~~~~~~~~~ declaration ~~~~~~~~~~>
2466 		 Use c_parser_require to get an error with a fix-it hint.  */
2467 	      c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>");
2468 	      parser->error = false;
2469 	    }
2470 	  else
2471 	    {
2472 	      /* This can appear in many cases looking nothing like a
2473 		 function definition, so we don't give a more specific
2474 		 error suggesting there was one.  */
2475 	      c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2476 			      "or %<__attribute__%>");
2477 	    }
2478 	  if (nested)
2479 	    c_pop_function_context ();
2480 	  break;
2481 	}
2482 
2483       if (DECL_DECLARED_INLINE_P (current_function_decl))
2484         tv = TV_PARSE_INLINE;
2485       else
2486         tv = TV_PARSE_FUNC;
2487       auto_timevar at (g_timer, tv);
2488 
2489       /* Parse old-style parameter declarations.  ??? Attributes are
2490 	 not allowed to start declaration specifiers here because of a
2491 	 syntax conflict between a function declaration with attribute
2492 	 suffix and a function definition with an attribute prefix on
2493 	 first old-style parameter declaration.  Following the old
2494 	 parser, they are not accepted on subsequent old-style
2495 	 parameter declarations either.  However, there is no
2496 	 ambiguity after the first declaration, nor indeed on the
2497 	 first as long as we don't allow postfix attributes after a
2498 	 declarator with a nonempty identifier list in a definition;
2499 	 and postfix attributes have never been accepted here in
2500 	 function definitions either.  */
2501       int save_debug_nonbind_markers_p = debug_nonbind_markers_p;
2502       debug_nonbind_markers_p = 0;
2503       while (c_parser_next_token_is_not (parser, CPP_EOF)
2504 	     && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE))
2505 	c_parser_declaration_or_fndef (parser, false, false, false,
2506 				       true, false);
2507       debug_nonbind_markers_p = save_debug_nonbind_markers_p;
2508       store_parm_decls ();
2509       if (omp_declare_simd_clauses)
2510 	c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE,
2511 				   omp_declare_simd_clauses);
2512       if (oacc_routine_data)
2513 	c_finish_oacc_routine (oacc_routine_data, current_function_decl, true);
2514       location_t startloc = c_parser_peek_token (parser)->location;
2515       DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
2516 	= startloc;
2517       location_t endloc = startloc;
2518 
2519       /* If the definition was marked with __RTL, use the RTL parser now,
2520 	 consuming the function body.  */
2521       if (specs->declspec_il == cdil_rtl)
2522 	{
2523 	  endloc = c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass);
2524 
2525 	  /* Normally, store_parm_decls sets next_is_function_body,
2526 	     anticipating a function body.  We need a push_scope/pop_scope
2527 	     pair to flush out this state, or subsequent function parsing
2528 	     will go wrong.  */
2529 	  push_scope ();
2530 	  pop_scope ();
2531 
2532 	  finish_function (endloc);
2533 	  return;
2534 	}
2535       /* If the definition was marked with __GIMPLE then parse the
2536          function body as GIMPLE.  */
2537       else if (specs->declspec_il != cdil_none)
2538 	{
2539 	  bool saved = in_late_binary_op;
2540 	  in_late_binary_op = true;
2541 	  c_parser_parse_gimple_body (parser, specs->gimple_or_rtl_pass,
2542 				      specs->declspec_il,
2543 				      specs->entry_bb_count);
2544 	  in_late_binary_op = saved;
2545 	}
2546       else
2547 	fnbody = c_parser_compound_statement (parser, &endloc);
2548       tree fndecl = current_function_decl;
2549       if (nested)
2550 	{
2551 	  tree decl = current_function_decl;
2552 	  /* Mark nested functions as needing static-chain initially.
2553 	     lower_nested_functions will recompute it but the
2554 	     DECL_STATIC_CHAIN flag is also used before that happens,
2555 	     by initializer_constant_valid_p.  See gcc.dg/nested-fn-2.c.  */
2556 	  DECL_STATIC_CHAIN (decl) = 1;
2557 	  add_stmt (fnbody);
2558 	  finish_function (endloc);
2559 	  c_pop_function_context ();
2560 	  add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));
2561 	}
2562       else
2563 	{
2564 	  if (fnbody)
2565 	    add_stmt (fnbody);
2566 	  finish_function (endloc);
2567 	}
2568       /* Get rid of the empty stmt list for GIMPLE/RTL.  */
2569       if (specs->declspec_il != cdil_none)
2570 	DECL_SAVED_TREE (fndecl) = NULL_TREE;
2571 
2572       break;
2573     }
2574 }
2575 
2576 /* Parse an asm-definition (asm() outside a function body).  This is a
2577    GNU extension.
2578 
2579    asm-definition:
2580      simple-asm-expr ;
2581 */
2582 
2583 static void
c_parser_asm_definition(c_parser * parser)2584 c_parser_asm_definition (c_parser *parser)
2585 {
2586   tree asm_str = c_parser_simple_asm_expr (parser);
2587   if (asm_str)
2588     symtab->finalize_toplevel_asm (asm_str);
2589   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
2590 }
2591 
2592 /* Parse a static assertion (C11 6.7.10).
2593 
2594    static_assert-declaration:
2595      static_assert-declaration-no-semi ;
2596 */
2597 
2598 static void
c_parser_static_assert_declaration(c_parser * parser)2599 c_parser_static_assert_declaration (c_parser *parser)
2600 {
2601   c_parser_static_assert_declaration_no_semi (parser);
2602   if (parser->error
2603       || !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
2604     c_parser_skip_to_end_of_block_or_statement (parser);
2605 }
2606 
2607 /* Parse a static assertion (C11 6.7.10), without the trailing
2608    semicolon.
2609 
2610    static_assert-declaration-no-semi:
2611      _Static_assert ( constant-expression , string-literal )
2612 
2613    C2X:
2614    static_assert-declaration-no-semi:
2615      _Static_assert ( constant-expression )
2616 */
2617 
2618 static void
c_parser_static_assert_declaration_no_semi(c_parser * parser)2619 c_parser_static_assert_declaration_no_semi (c_parser *parser)
2620 {
2621   location_t assert_loc, value_loc;
2622   tree value;
2623   tree string = NULL_TREE;
2624 
2625   gcc_assert (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT));
2626   assert_loc = c_parser_peek_token (parser)->location;
2627   if (flag_isoc99)
2628     pedwarn_c99 (assert_loc, OPT_Wpedantic,
2629 		 "ISO C99 does not support %<_Static_assert%>");
2630   else
2631     pedwarn_c99 (assert_loc, OPT_Wpedantic,
2632 		 "ISO C90 does not support %<_Static_assert%>");
2633   c_parser_consume_token (parser);
2634   matching_parens parens;
2635   if (!parens.require_open (parser))
2636     return;
2637   location_t value_tok_loc = c_parser_peek_token (parser)->location;
2638   value = c_parser_expr_no_commas (parser, NULL).value;
2639   value_loc = EXPR_LOC_OR_LOC (value, value_tok_loc);
2640   if (c_parser_next_token_is (parser, CPP_COMMA))
2641     {
2642       c_parser_consume_token (parser);
2643       switch (c_parser_peek_token (parser)->type)
2644 	{
2645 	case CPP_STRING:
2646 	case CPP_STRING16:
2647 	case CPP_STRING32:
2648 	case CPP_WSTRING:
2649 	case CPP_UTF8STRING:
2650 	  string = c_parser_string_literal (parser, false, true).value;
2651 	  break;
2652 	default:
2653 	  c_parser_error (parser, "expected string literal");
2654 	  return;
2655 	}
2656     }
2657   else if (flag_isoc11)
2658     /* If pedantic for pre-C11, the use of _Static_assert itself will
2659        have been diagnosed, so do not also diagnose the use of this
2660        new C2X feature of _Static_assert.  */
2661     pedwarn_c11 (assert_loc, OPT_Wpedantic,
2662 		 "ISO C11 does not support omitting the string in "
2663 		 "%<_Static_assert%>");
2664   parens.require_close (parser);
2665 
2666   if (!INTEGRAL_TYPE_P (TREE_TYPE (value)))
2667     {
2668       error_at (value_loc, "expression in static assertion is not an integer");
2669       return;
2670     }
2671   if (TREE_CODE (value) != INTEGER_CST)
2672     {
2673       value = c_fully_fold (value, false, NULL);
2674       /* Strip no-op conversions.  */
2675       STRIP_TYPE_NOPS (value);
2676       if (TREE_CODE (value) == INTEGER_CST)
2677 	pedwarn (value_loc, OPT_Wpedantic, "expression in static assertion "
2678 		 "is not an integer constant expression");
2679     }
2680   if (TREE_CODE (value) != INTEGER_CST)
2681     {
2682       error_at (value_loc, "expression in static assertion is not constant");
2683       return;
2684     }
2685   constant_expression_warning (value);
2686   if (integer_zerop (value))
2687     {
2688       if (string)
2689 	error_at (assert_loc, "static assertion failed: %E", string);
2690       else
2691 	error_at (assert_loc, "static assertion failed");
2692     }
2693 }
2694 
2695 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
2696    6.7, C11 6.7), adding them to SPECS (which may already include some).
2697    Storage class specifiers are accepted iff SCSPEC_OK; type
2698    specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
2699    accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start
2700    iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK.  In
2701    addition to the syntax shown, standard attributes are accepted at
2702    the start iff START_STD_ATTR_OK and at the end iff END_STD_ATTR_OK;
2703    unlike gnu-attributes, they are not accepted in the middle of the
2704    list.  (This combines various different syntax productions in the C
2705    standard, and in some cases gnu-attributes and standard attributes
2706    at the start may already have been parsed before this function is
2707    called.)
2708 
2709    declaration-specifiers:
2710      storage-class-specifier declaration-specifiers[opt]
2711      type-specifier declaration-specifiers[opt]
2712      type-qualifier declaration-specifiers[opt]
2713      function-specifier declaration-specifiers[opt]
2714      alignment-specifier declaration-specifiers[opt]
2715 
2716    Function specifiers (inline) are from C99, and are currently
2717    handled as storage class specifiers, as is __thread.  Alignment
2718    specifiers are from C11.
2719 
2720    C90 6.5.1, C99 6.7.1, C11 6.7.1:
2721    storage-class-specifier:
2722      typedef
2723      extern
2724      static
2725      auto
2726      register
2727      _Thread_local
2728 
2729    (_Thread_local is new in C11.)
2730 
2731    C99 6.7.4, C11 6.7.4:
2732    function-specifier:
2733      inline
2734      _Noreturn
2735 
2736    (_Noreturn is new in C11.)
2737 
2738    C90 6.5.2, C99 6.7.2, C11 6.7.2:
2739    type-specifier:
2740      void
2741      char
2742      short
2743      int
2744      long
2745      float
2746      double
2747      signed
2748      unsigned
2749      _Bool
2750      _Complex
2751      [_Imaginary removed in C99 TC2]
2752      struct-or-union-specifier
2753      enum-specifier
2754      typedef-name
2755      atomic-type-specifier
2756 
2757    (_Bool and _Complex are new in C99.)
2758    (atomic-type-specifier is new in C11.)
2759 
2760    C90 6.5.3, C99 6.7.3, C11 6.7.3:
2761 
2762    type-qualifier:
2763      const
2764      restrict
2765      volatile
2766      address-space-qualifier
2767      _Atomic
2768 
2769    (restrict is new in C99.)
2770    (_Atomic is new in C11.)
2771 
2772    GNU extensions:
2773 
2774    declaration-specifiers:
2775      gnu-attributes declaration-specifiers[opt]
2776 
2777    type-qualifier:
2778      address-space
2779 
2780    address-space:
2781      identifier recognized by the target
2782 
2783    storage-class-specifier:
2784      __thread
2785 
2786    type-specifier:
2787      typeof-specifier
2788      __auto_type
2789      __intN
2790      _Decimal32
2791      _Decimal64
2792      _Decimal128
2793      _Fract
2794      _Accum
2795      _Sat
2796 
2797   (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
2798    http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
2799 
2800    atomic-type-specifier
2801     _Atomic ( type-name )
2802 
2803    Objective-C:
2804 
2805    type-specifier:
2806      class-name objc-protocol-refs[opt]
2807      typedef-name objc-protocol-refs
2808      objc-protocol-refs
2809 */
2810 
2811 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)2812 c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
2813 		    bool scspec_ok, bool typespec_ok, bool start_attr_ok,
2814 		    bool alignspec_ok, bool auto_type_ok,
2815 		    bool start_std_attr_ok, bool end_std_attr_ok,
2816 		    enum c_lookahead_kind la)
2817 {
2818   bool attrs_ok = start_attr_ok;
2819   bool seen_type = specs->typespec_kind != ctsk_none;
2820 
2821   if (!typespec_ok)
2822     gcc_assert (la == cla_prefer_id);
2823 
2824   if (start_std_attr_ok
2825       && c_parser_nth_token_starts_std_attributes (parser, 1))
2826     {
2827       gcc_assert (!specs->non_std_attrs_seen_p);
2828       location_t loc = c_parser_peek_token (parser)->location;
2829       tree attrs = c_parser_std_attribute_specifier_sequence (parser);
2830       declspecs_add_attrs (loc, specs, attrs);
2831       specs->non_std_attrs_seen_p = false;
2832     }
2833 
2834   while (c_parser_next_token_is (parser, CPP_NAME)
2835 	 || c_parser_next_token_is (parser, CPP_KEYWORD)
2836 	 || (c_dialect_objc () && c_parser_next_token_is (parser, CPP_LESS)))
2837     {
2838       struct c_typespec t;
2839       tree attrs;
2840       tree align;
2841       location_t loc = c_parser_peek_token (parser)->location;
2842 
2843       /* If we cannot accept a type, exit if the next token must start
2844 	 one.  Also, if we already have seen a tagged definition,
2845 	 a typename would be an error anyway and likely the user
2846 	 has simply forgotten a semicolon, so we exit.  */
2847       if ((!typespec_ok || specs->typespec_kind == ctsk_tagdef)
2848 	  && c_parser_next_tokens_start_typename (parser, la)
2849 	  && !c_parser_next_token_is_qualifier (parser)
2850 	  && !c_parser_next_token_is_keyword (parser, RID_ALIGNAS))
2851 	break;
2852 
2853       if (c_parser_next_token_is (parser, CPP_NAME))
2854 	{
2855 	  c_token *name_token = c_parser_peek_token (parser);
2856 	  tree value = name_token->value;
2857 	  c_id_kind kind = name_token->id_kind;
2858 
2859 	  if (kind == C_ID_ADDRSPACE)
2860 	    {
2861 	      addr_space_t as
2862 		= name_token->keyword - RID_FIRST_ADDR_SPACE;
2863 	      declspecs_add_addrspace (name_token->location, specs, as);
2864 	      c_parser_consume_token (parser);
2865 	      attrs_ok = true;
2866 	      continue;
2867 	    }
2868 
2869 	  gcc_assert (!c_parser_next_token_is_qualifier (parser));
2870 
2871 	  /* If we cannot accept a type, and the next token must start one,
2872 	     exit.  Do the same if we already have seen a tagged definition,
2873 	     since it would be an error anyway and likely the user has simply
2874 	     forgotten a semicolon.  */
2875 	  if (seen_type || !c_parser_next_tokens_start_typename (parser, la))
2876 	    break;
2877 
2878 	  /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
2879 	     a C_ID_CLASSNAME.  */
2880 	  c_parser_consume_token (parser);
2881 	  seen_type = true;
2882 	  attrs_ok = true;
2883 	  if (kind == C_ID_ID)
2884 	    {
2885 	      error_at (loc, "unknown type name %qE", value);
2886 	      t.kind = ctsk_typedef;
2887 	      t.spec = error_mark_node;
2888 	    }
2889 	  else if (kind == C_ID_TYPENAME
2890 	           && (!c_dialect_objc ()
2891 	               || c_parser_next_token_is_not (parser, CPP_LESS)))
2892 	    {
2893 	      t.kind = ctsk_typedef;
2894 	      /* For a typedef name, record the meaning, not the name.
2895 		 In case of 'foo foo, bar;'.  */
2896 	      t.spec = lookup_name (value);
2897 	    }
2898 	  else
2899 	    {
2900 	      tree proto = NULL_TREE;
2901 	      gcc_assert (c_dialect_objc ());
2902 	      t.kind = ctsk_objc;
2903 	      if (c_parser_next_token_is (parser, CPP_LESS))
2904 		proto = c_parser_objc_protocol_refs (parser);
2905 	      t.spec = objc_get_protocol_qualified_type (value, proto);
2906 	    }
2907 	  t.expr = NULL_TREE;
2908 	  t.expr_const_operands = true;
2909 	  declspecs_add_type (name_token->location, specs, t);
2910 	  continue;
2911 	}
2912       if (c_parser_next_token_is (parser, CPP_LESS))
2913 	{
2914 	  /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
2915 	     nisse@lysator.liu.se.  */
2916 	  tree proto;
2917 	  gcc_assert (c_dialect_objc ());
2918 	  if (!typespec_ok || seen_type)
2919 	    break;
2920 	  proto = c_parser_objc_protocol_refs (parser);
2921 	  t.kind = ctsk_objc;
2922 	  t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto);
2923 	  t.expr = NULL_TREE;
2924 	  t.expr_const_operands = true;
2925 	  declspecs_add_type (loc, specs, t);
2926 	  continue;
2927 	}
2928       gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD));
2929       switch (c_parser_peek_token (parser)->keyword)
2930 	{
2931 	case RID_STATIC:
2932 	case RID_EXTERN:
2933 	case RID_REGISTER:
2934 	case RID_TYPEDEF:
2935 	case RID_INLINE:
2936 	case RID_NORETURN:
2937 	case RID_AUTO:
2938 	case RID_THREAD:
2939 	  if (!scspec_ok)
2940 	    goto out;
2941 	  attrs_ok = true;
2942 	  /* TODO: Distinguish between function specifiers (inline, noreturn)
2943 	     and storage class specifiers, either here or in
2944 	     declspecs_add_scspec.  */
2945 	  declspecs_add_scspec (loc, specs,
2946 				c_parser_peek_token (parser)->value);
2947 	  c_parser_consume_token (parser);
2948 	  break;
2949 	case RID_AUTO_TYPE:
2950 	  if (!auto_type_ok)
2951 	    goto out;
2952 	  /* Fall through.  */
2953 	case RID_UNSIGNED:
2954 	case RID_LONG:
2955 	case RID_SHORT:
2956 	case RID_SIGNED:
2957 	case RID_COMPLEX:
2958 	case RID_INT:
2959 	case RID_CHAR:
2960 	case RID_FLOAT:
2961 	case RID_DOUBLE:
2962 	case RID_VOID:
2963 	case RID_DFLOAT32:
2964 	case RID_DFLOAT64:
2965 	case RID_DFLOAT128:
2966 	CASE_RID_FLOATN_NX:
2967 	case RID_BOOL:
2968 	case RID_FRACT:
2969 	case RID_ACCUM:
2970 	case RID_SAT:
2971 	case RID_INT_N_0:
2972 	case RID_INT_N_1:
2973 	case RID_INT_N_2:
2974 	case RID_INT_N_3:
2975 	  if (!typespec_ok)
2976 	    goto out;
2977 	  attrs_ok = true;
2978 	  seen_type = true;
2979 	  if (c_dialect_objc ())
2980 	    parser->objc_need_raw_identifier = true;
2981 	  t.kind = ctsk_resword;
2982 	  t.spec = c_parser_peek_token (parser)->value;
2983 	  t.expr = NULL_TREE;
2984 	  t.expr_const_operands = true;
2985 	  declspecs_add_type (loc, specs, t);
2986 	  c_parser_consume_token (parser);
2987 	  break;
2988 	case RID_ENUM:
2989 	  if (!typespec_ok)
2990 	    goto out;
2991 	  attrs_ok = true;
2992 	  seen_type = true;
2993 	  t = c_parser_enum_specifier (parser);
2994           invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
2995 	  declspecs_add_type (loc, specs, t);
2996 	  break;
2997 	case RID_STRUCT:
2998 	case RID_UNION:
2999 	  if (!typespec_ok)
3000 	    goto out;
3001 	  attrs_ok = true;
3002 	  seen_type = true;
3003 	  t = c_parser_struct_or_union_specifier (parser);
3004           invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
3005 	  declspecs_add_type (loc, specs, t);
3006 	  break;
3007 	case RID_TYPEOF:
3008 	  /* ??? The old parser rejected typeof after other type
3009 	     specifiers, but is a syntax error the best way of
3010 	     handling this?  */
3011 	  if (!typespec_ok || seen_type)
3012 	    goto out;
3013 	  attrs_ok = true;
3014 	  seen_type = true;
3015 	  t = c_parser_typeof_specifier (parser);
3016 	  declspecs_add_type (loc, specs, t);
3017 	  break;
3018 	case RID_ATOMIC:
3019 	  /* C parser handling of Objective-C constructs needs
3020 	     checking for correct lvalue-to-rvalue conversions, and
3021 	     the code in build_modify_expr handling various
3022 	     Objective-C cases, and that in build_unary_op handling
3023 	     Objective-C cases for increment / decrement, also needs
3024 	     updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
3025 	     and objc_types_are_equivalent may also need updates.  */
3026 	  if (c_dialect_objc ())
3027 	    sorry ("%<_Atomic%> in Objective-C");
3028 	  if (flag_isoc99)
3029 	    pedwarn_c99 (loc, OPT_Wpedantic,
3030 			 "ISO C99 does not support the %<_Atomic%> qualifier");
3031 	  else
3032 	    pedwarn_c99 (loc, OPT_Wpedantic,
3033 			 "ISO C90 does not support the %<_Atomic%> qualifier");
3034 	  attrs_ok = true;
3035 	  tree value;
3036 	  value = c_parser_peek_token (parser)->value;
3037 	  c_parser_consume_token (parser);
3038 	  if (typespec_ok && c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3039 	    {
3040 	      /* _Atomic ( type-name ).  */
3041 	      seen_type = true;
3042 	      c_parser_consume_token (parser);
3043 	      struct c_type_name *type = c_parser_type_name (parser);
3044 	      t.kind = ctsk_typeof;
3045 	      t.spec = error_mark_node;
3046 	      t.expr = NULL_TREE;
3047 	      t.expr_const_operands = true;
3048 	      if (type != NULL)
3049 		t.spec = groktypename (type, &t.expr,
3050 				       &t.expr_const_operands);
3051 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3052 					 "expected %<)%>");
3053 	      if (t.spec != error_mark_node)
3054 		{
3055 		  if (TREE_CODE (t.spec) == ARRAY_TYPE)
3056 		    error_at (loc, "%<_Atomic%>-qualified array type");
3057 		  else if (TREE_CODE (t.spec) == FUNCTION_TYPE)
3058 		    error_at (loc, "%<_Atomic%>-qualified function type");
3059 		  else if (TYPE_QUALS (t.spec) != TYPE_UNQUALIFIED)
3060 		    error_at (loc, "%<_Atomic%> applied to a qualified type");
3061 		  else
3062 		    t.spec = c_build_qualified_type (t.spec, TYPE_QUAL_ATOMIC);
3063 		}
3064 	      declspecs_add_type (loc, specs, t);
3065 	    }
3066 	  else
3067 	    declspecs_add_qual (loc, specs, value);
3068 	  break;
3069 	case RID_CONST:
3070 	case RID_VOLATILE:
3071 	case RID_RESTRICT:
3072 	  attrs_ok = true;
3073 	  declspecs_add_qual (loc, specs, c_parser_peek_token (parser)->value);
3074 	  c_parser_consume_token (parser);
3075 	  break;
3076 	case RID_ATTRIBUTE:
3077 	  if (!attrs_ok)
3078 	    goto out;
3079 	  attrs = c_parser_gnu_attributes (parser);
3080 	  declspecs_add_attrs (loc, specs, attrs);
3081 	  break;
3082 	case RID_ALIGNAS:
3083 	  if (!alignspec_ok)
3084 	    goto out;
3085 	  align = c_parser_alignas_specifier (parser);
3086 	  declspecs_add_alignas (loc, specs, align);
3087 	  break;
3088 	case RID_GIMPLE:
3089 	  if (! flag_gimple)
3090 	    error_at (loc, "%<__GIMPLE%> only valid with %<-fgimple%>");
3091 	  c_parser_consume_token (parser);
3092 	  specs->declspec_il = cdil_gimple;
3093 	  specs->locations[cdw_gimple] = loc;
3094 	  c_parser_gimple_or_rtl_pass_list (parser, specs);
3095 	  break;
3096 	case RID_RTL:
3097 	  c_parser_consume_token (parser);
3098 	  specs->declspec_il = cdil_rtl;
3099 	  specs->locations[cdw_rtl] = loc;
3100 	  c_parser_gimple_or_rtl_pass_list (parser, specs);
3101 	  break;
3102 	default:
3103 	  goto out;
3104 	}
3105     }
3106  out:
3107   if (end_std_attr_ok
3108       && c_parser_nth_token_starts_std_attributes (parser, 1))
3109     specs->postfix_attrs = c_parser_std_attribute_specifier_sequence (parser);
3110 }
3111 
3112 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
3113 
3114    enum-specifier:
3115      enum gnu-attributes[opt] identifier[opt] { enumerator-list }
3116        gnu-attributes[opt]
3117      enum gnu-attributes[opt] identifier[opt] { enumerator-list , }
3118        gnu-attributes[opt]
3119      enum gnu-attributes[opt] identifier
3120 
3121    The form with trailing comma is new in C99.  The forms with
3122    gnu-attributes are GNU extensions.  In GNU C, we accept any expression
3123    without commas in the syntax (assignment expressions, not just
3124    conditional expressions); assignment expressions will be diagnosed
3125    as non-constant.
3126 
3127    enumerator-list:
3128      enumerator
3129      enumerator-list , enumerator
3130 
3131    enumerator:
3132      enumeration-constant attribute-specifier-sequence[opt]
3133      enumeration-constant attribute-specifier-sequence[opt]
3134        = constant-expression
3135 
3136    GNU Extensions:
3137 
3138    enumerator:
3139      enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3140      enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3141        = constant-expression
3142 
3143 */
3144 
3145 static struct c_typespec
c_parser_enum_specifier(c_parser * parser)3146 c_parser_enum_specifier (c_parser *parser)
3147 {
3148   struct c_typespec ret;
3149   bool have_std_attrs;
3150   tree std_attrs = NULL_TREE;
3151   tree attrs;
3152   tree ident = NULL_TREE;
3153   location_t enum_loc;
3154   location_t ident_loc = UNKNOWN_LOCATION;  /* Quiet warning.  */
3155   gcc_assert (c_parser_next_token_is_keyword (parser, RID_ENUM));
3156   c_parser_consume_token (parser);
3157   have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3158   if (have_std_attrs)
3159     std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3160   attrs = c_parser_gnu_attributes (parser);
3161   enum_loc = c_parser_peek_token (parser)->location;
3162   /* Set the location in case we create a decl now.  */
3163   c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3164   if (c_parser_next_token_is (parser, CPP_NAME))
3165     {
3166       ident = c_parser_peek_token (parser)->value;
3167       ident_loc = c_parser_peek_token (parser)->location;
3168       enum_loc = ident_loc;
3169       c_parser_consume_token (parser);
3170     }
3171   if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3172     {
3173       /* Parse an enum definition.  */
3174       struct c_enum_contents the_enum;
3175       tree type;
3176       tree postfix_attrs;
3177       /* We chain the enumerators in reverse order, then put them in
3178 	 forward order at the end.  */
3179       tree values;
3180       timevar_push (TV_PARSE_ENUM);
3181       type = start_enum (enum_loc, &the_enum, ident);
3182       values = NULL_TREE;
3183       c_parser_consume_token (parser);
3184       while (true)
3185 	{
3186 	  tree enum_id;
3187 	  tree enum_value;
3188 	  tree enum_decl;
3189 	  bool seen_comma;
3190 	  c_token *token;
3191 	  location_t comma_loc = UNKNOWN_LOCATION;  /* Quiet warning.  */
3192 	  location_t decl_loc, value_loc;
3193 	  if (c_parser_next_token_is_not (parser, CPP_NAME))
3194 	    {
3195 	      /* Give a nicer error for "enum {}".  */
3196 	      if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3197 		  && !parser->error)
3198 		{
3199 		  error_at (c_parser_peek_token (parser)->location,
3200 			    "empty enum is invalid");
3201 		  parser->error = true;
3202 		}
3203 	      else
3204 		c_parser_error (parser, "expected identifier");
3205 	      c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3206 	      values = error_mark_node;
3207 	      break;
3208 	    }
3209 	  token = c_parser_peek_token (parser);
3210 	  enum_id = token->value;
3211 	  /* Set the location in case we create a decl now.  */
3212 	  c_parser_set_source_position_from_token (token);
3213 	  decl_loc = value_loc = token->location;
3214 	  c_parser_consume_token (parser);
3215 	  /* Parse any specified attributes.  */
3216 	  tree std_attrs = NULL_TREE;
3217 	  if (c_parser_nth_token_starts_std_attributes (parser, 1))
3218 	    std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3219 	  tree enum_attrs = chainon (std_attrs,
3220 				     c_parser_gnu_attributes (parser));
3221 	  if (c_parser_next_token_is (parser, CPP_EQ))
3222 	    {
3223 	      c_parser_consume_token (parser);
3224 	      value_loc = c_parser_peek_token (parser)->location;
3225 	      enum_value = c_parser_expr_no_commas (parser, NULL).value;
3226 	    }
3227 	  else
3228 	    enum_value = NULL_TREE;
3229 	  enum_decl = build_enumerator (decl_loc, value_loc,
3230 					&the_enum, enum_id, enum_value);
3231 	  if (enum_attrs)
3232 	    decl_attributes (&TREE_PURPOSE (enum_decl), enum_attrs, 0);
3233 	  TREE_CHAIN (enum_decl) = values;
3234 	  values = enum_decl;
3235 	  seen_comma = false;
3236 	  if (c_parser_next_token_is (parser, CPP_COMMA))
3237 	    {
3238 	      comma_loc = c_parser_peek_token (parser)->location;
3239 	      seen_comma = true;
3240 	      c_parser_consume_token (parser);
3241 	    }
3242 	  if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3243 	    {
3244 	      if (seen_comma)
3245 		pedwarn_c90 (comma_loc, OPT_Wpedantic,
3246 			     "comma at end of enumerator list");
3247 	      c_parser_consume_token (parser);
3248 	      break;
3249 	    }
3250 	  if (!seen_comma)
3251 	    {
3252 	      c_parser_error (parser, "expected %<,%> or %<}%>");
3253 	      c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3254 	      values = error_mark_node;
3255 	      break;
3256 	    }
3257 	}
3258       postfix_attrs = c_parser_gnu_attributes (parser);
3259       ret.spec = finish_enum (type, nreverse (values),
3260 			      chainon (std_attrs,
3261 				       chainon (attrs, postfix_attrs)));
3262       ret.kind = ctsk_tagdef;
3263       ret.expr = NULL_TREE;
3264       ret.expr_const_operands = true;
3265       timevar_pop (TV_PARSE_ENUM);
3266       return ret;
3267     }
3268   else if (!ident)
3269     {
3270       c_parser_error (parser, "expected %<{%>");
3271       ret.spec = error_mark_node;
3272       ret.kind = ctsk_tagref;
3273       ret.expr = NULL_TREE;
3274       ret.expr_const_operands = true;
3275       return ret;
3276     }
3277   /* Attributes may only appear when the members are defined or in
3278      certain forward declarations (treat enum forward declarations in
3279      GNU C analogously to struct and union forward declarations in
3280      standard C).  */
3281   if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3282     c_parser_error (parser, "expected %<;%>");
3283   ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident, have_std_attrs,
3284 			 std_attrs);
3285   /* In ISO C, enumerated types can be referred to only if already
3286      defined.  */
3287   if (pedantic && !COMPLETE_TYPE_P (ret.spec))
3288     {
3289       gcc_assert (ident);
3290       pedwarn (enum_loc, OPT_Wpedantic,
3291 	       "ISO C forbids forward references to %<enum%> types");
3292     }
3293   return ret;
3294 }
3295 
3296 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3297 
3298    struct-or-union-specifier:
3299      struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3300        identifier[opt] { struct-contents } gnu-attributes[opt]
3301      struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3302        identifier
3303 
3304    struct-contents:
3305      struct-declaration-list
3306 
3307    struct-declaration-list:
3308      struct-declaration ;
3309      struct-declaration-list struct-declaration ;
3310 
3311    GNU extensions:
3312 
3313    struct-contents:
3314      empty
3315      struct-declaration
3316      struct-declaration-list struct-declaration
3317 
3318    struct-declaration-list:
3319      struct-declaration-list ;
3320      ;
3321 
3322    (Note that in the syntax here, unlike that in ISO C, the semicolons
3323    are included here rather than in struct-declaration, in order to
3324    describe the syntax with extra semicolons and missing semicolon at
3325    end.)
3326 
3327    Objective-C:
3328 
3329    struct-declaration-list:
3330      @defs ( class-name )
3331 
3332    (Note this does not include a trailing semicolon, but can be
3333    followed by further declarations, and gets a pedwarn-if-pedantic
3334    when followed by a semicolon.)  */
3335 
3336 static struct c_typespec
c_parser_struct_or_union_specifier(c_parser * parser)3337 c_parser_struct_or_union_specifier (c_parser *parser)
3338 {
3339   struct c_typespec ret;
3340   bool have_std_attrs;
3341   tree std_attrs = NULL_TREE;
3342   tree attrs;
3343   tree ident = NULL_TREE;
3344   location_t struct_loc;
3345   location_t ident_loc = UNKNOWN_LOCATION;
3346   enum tree_code code;
3347   switch (c_parser_peek_token (parser)->keyword)
3348     {
3349     case RID_STRUCT:
3350       code = RECORD_TYPE;
3351       break;
3352     case RID_UNION:
3353       code = UNION_TYPE;
3354       break;
3355     default:
3356       gcc_unreachable ();
3357     }
3358   struct_loc = c_parser_peek_token (parser)->location;
3359   c_parser_consume_token (parser);
3360   have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3361   if (have_std_attrs)
3362     std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3363   attrs = c_parser_gnu_attributes (parser);
3364 
3365   /* Set the location in case we create a decl now.  */
3366   c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3367 
3368   if (c_parser_next_token_is (parser, CPP_NAME))
3369     {
3370       ident = c_parser_peek_token (parser)->value;
3371       ident_loc = c_parser_peek_token (parser)->location;
3372       struct_loc = ident_loc;
3373       c_parser_consume_token (parser);
3374     }
3375   if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3376     {
3377       /* Parse a struct or union definition.  Start the scope of the
3378 	 tag before parsing components.  */
3379       class c_struct_parse_info *struct_info;
3380       tree type = start_struct (struct_loc, code, ident, &struct_info);
3381       tree postfix_attrs;
3382       /* We chain the components in reverse order, then put them in
3383 	 forward order at the end.  Each struct-declaration may
3384 	 declare multiple components (comma-separated), so we must use
3385 	 chainon to join them, although when parsing each
3386 	 struct-declaration we can use TREE_CHAIN directly.
3387 
3388 	 The theory behind all this is that there will be more
3389 	 semicolon separated fields than comma separated fields, and
3390 	 so we'll be minimizing the number of node traversals required
3391 	 by chainon.  */
3392       tree contents;
3393       timevar_push (TV_PARSE_STRUCT);
3394       contents = NULL_TREE;
3395       c_parser_consume_token (parser);
3396       /* Handle the Objective-C @defs construct,
3397 	 e.g. foo(sizeof(struct{ @defs(ClassName) }));.  */
3398       if (c_parser_next_token_is_keyword (parser, RID_AT_DEFS))
3399 	{
3400 	  tree name;
3401 	  gcc_assert (c_dialect_objc ());
3402 	  c_parser_consume_token (parser);
3403 	  matching_parens parens;
3404 	  if (!parens.require_open (parser))
3405 	    goto end_at_defs;
3406 	  if (c_parser_next_token_is (parser, CPP_NAME)
3407 	      && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)
3408 	    {
3409 	      name = c_parser_peek_token (parser)->value;
3410 	      c_parser_consume_token (parser);
3411 	    }
3412 	  else
3413 	    {
3414 	      c_parser_error (parser, "expected class name");
3415 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
3416 	      goto end_at_defs;
3417 	    }
3418 	  parens.skip_until_found_close (parser);
3419 	  contents = nreverse (objc_get_class_ivars (name));
3420 	}
3421     end_at_defs:
3422       /* Parse the struct-declarations and semicolons.  Problems with
3423 	 semicolons are diagnosed here; empty structures are diagnosed
3424 	 elsewhere.  */
3425       while (true)
3426 	{
3427 	  tree decls;
3428 	  /* Parse any stray semicolon.  */
3429 	  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3430 	    {
3431 	      location_t semicolon_loc
3432 		= c_parser_peek_token (parser)->location;
3433 	      gcc_rich_location richloc (semicolon_loc);
3434 	      richloc.add_fixit_remove ();
3435 	      pedwarn (&richloc, OPT_Wpedantic,
3436 		       "extra semicolon in struct or union specified");
3437 	      c_parser_consume_token (parser);
3438 	      continue;
3439 	    }
3440 	  /* Stop if at the end of the struct or union contents.  */
3441 	  if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3442 	    {
3443 	      c_parser_consume_token (parser);
3444 	      break;
3445 	    }
3446 	  /* Accept #pragmas at struct scope.  */
3447 	  if (c_parser_next_token_is (parser, CPP_PRAGMA))
3448 	    {
3449 	      c_parser_pragma (parser, pragma_struct, NULL);
3450 	      continue;
3451 	    }
3452 	  /* Parse some comma-separated declarations, but not the
3453 	     trailing semicolon if any.  */
3454 	  decls = c_parser_struct_declaration (parser);
3455 	  contents = chainon (decls, contents);
3456 	  /* If no semicolon follows, either we have a parse error or
3457 	     are at the end of the struct or union and should
3458 	     pedwarn.  */
3459 	  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3460 	    c_parser_consume_token (parser);
3461 	  else
3462 	    {
3463 	      if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3464 		pedwarn (c_parser_peek_token (parser)->location, 0,
3465 			 "no semicolon at end of struct or union");
3466 	      else if (parser->error
3467 		       || !c_parser_next_token_starts_declspecs (parser))
3468 		{
3469 		  c_parser_error (parser, "expected %<;%>");
3470 		  c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3471 		  break;
3472 		}
3473 
3474 	      /* If we come here, we have already emitted an error
3475 		 for an expected `;', identifier or `(', and we also
3476 	         recovered already.  Go on with the next field. */
3477 	    }
3478 	}
3479       postfix_attrs = c_parser_gnu_attributes (parser);
3480       ret.spec = finish_struct (struct_loc, type, nreverse (contents),
3481 				chainon (std_attrs,
3482 					 chainon (attrs, postfix_attrs)),
3483 				struct_info);
3484       ret.kind = ctsk_tagdef;
3485       ret.expr = NULL_TREE;
3486       ret.expr_const_operands = true;
3487       timevar_pop (TV_PARSE_STRUCT);
3488       return ret;
3489     }
3490   else if (!ident)
3491     {
3492       c_parser_error (parser, "expected %<{%>");
3493       ret.spec = error_mark_node;
3494       ret.kind = ctsk_tagref;
3495       ret.expr = NULL_TREE;
3496       ret.expr_const_operands = true;
3497       return ret;
3498     }
3499   /* Attributes may only appear when the members are defined or in
3500      certain forward declarations.  */
3501   if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3502     c_parser_error (parser, "expected %<;%>");
3503   /* ??? Existing practice is that GNU attributes are ignored after
3504      the struct or union keyword when not defining the members.  */
3505   ret = parser_xref_tag (ident_loc, code, ident, have_std_attrs, std_attrs);
3506   return ret;
3507 }
3508 
3509 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
3510    *without* the trailing semicolon.
3511 
3512    struct-declaration:
3513      attribute-specifier-sequence[opt] specifier-qualifier-list
3514        attribute-specifier-sequence[opt] struct-declarator-list
3515      static_assert-declaration-no-semi
3516 
3517    specifier-qualifier-list:
3518      type-specifier specifier-qualifier-list[opt]
3519      type-qualifier specifier-qualifier-list[opt]
3520      alignment-specifier specifier-qualifier-list[opt]
3521      gnu-attributes specifier-qualifier-list[opt]
3522 
3523    struct-declarator-list:
3524      struct-declarator
3525      struct-declarator-list , gnu-attributes[opt] struct-declarator
3526 
3527    struct-declarator:
3528      declarator gnu-attributes[opt]
3529      declarator[opt] : constant-expression gnu-attributes[opt]
3530 
3531    GNU extensions:
3532 
3533    struct-declaration:
3534      __extension__ struct-declaration
3535      specifier-qualifier-list
3536 
3537    Unlike the ISO C syntax, semicolons are handled elsewhere.  The use
3538    of gnu-attributes where shown is a GNU extension.  In GNU C, we accept
3539    any expression without commas in the syntax (assignment
3540    expressions, not just conditional expressions); assignment
3541    expressions will be diagnosed as non-constant.  */
3542 
3543 static tree
c_parser_struct_declaration(c_parser * parser)3544 c_parser_struct_declaration (c_parser *parser)
3545 {
3546   struct c_declspecs *specs;
3547   tree prefix_attrs;
3548   tree all_prefix_attrs;
3549   tree decls;
3550   location_t decl_loc;
3551   if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
3552     {
3553       int ext;
3554       tree decl;
3555       ext = disable_extension_diagnostics ();
3556       c_parser_consume_token (parser);
3557       decl = c_parser_struct_declaration (parser);
3558       restore_extension_diagnostics (ext);
3559       return decl;
3560     }
3561   if (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
3562     {
3563       c_parser_static_assert_declaration_no_semi (parser);
3564       return NULL_TREE;
3565     }
3566   specs = build_null_declspecs ();
3567   decl_loc = c_parser_peek_token (parser)->location;
3568   /* Strictly by the standard, we shouldn't allow _Alignas here,
3569      but it appears to have been intended to allow it there, so
3570      we're keeping it as it is until WG14 reaches a conclusion
3571      of N1731.
3572      <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf>  */
3573   c_parser_declspecs (parser, specs, false, true, true,
3574 		      true, false, true, true, cla_nonabstract_decl);
3575   if (parser->error)
3576     return NULL_TREE;
3577   if (!specs->declspecs_seen_p)
3578     {
3579       c_parser_error (parser, "expected specifier-qualifier-list");
3580       return NULL_TREE;
3581     }
3582   finish_declspecs (specs);
3583   if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3584       || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3585     {
3586       tree ret;
3587       if (specs->typespec_kind == ctsk_none)
3588 	{
3589 	  pedwarn (decl_loc, OPT_Wpedantic,
3590 		   "ISO C forbids member declarations with no members");
3591 	  shadow_tag_warned (specs, pedantic);
3592 	  ret = NULL_TREE;
3593 	}
3594       else
3595 	{
3596 	  /* Support for unnamed structs or unions as members of
3597 	     structs or unions (which is [a] useful and [b] supports
3598 	     MS P-SDK).  */
3599 	  tree attrs = NULL;
3600 
3601 	  ret = grokfield (c_parser_peek_token (parser)->location,
3602 			   build_id_declarator (NULL_TREE), specs,
3603 			   NULL_TREE, &attrs);
3604 	  if (ret)
3605 	    decl_attributes (&ret, attrs, 0);
3606 	}
3607       return ret;
3608     }
3609 
3610   /* Provide better error recovery.  Note that a type name here is valid,
3611      and will be treated as a field name.  */
3612   if (specs->typespec_kind == ctsk_tagdef
3613       && TREE_CODE (specs->type) != ENUMERAL_TYPE
3614       && c_parser_next_token_starts_declspecs (parser)
3615       && !c_parser_next_token_is (parser, CPP_NAME))
3616     {
3617       c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
3618       parser->error = false;
3619       return NULL_TREE;
3620     }
3621 
3622   pending_xref_error ();
3623   prefix_attrs = specs->attrs;
3624   all_prefix_attrs = prefix_attrs;
3625   specs->attrs = NULL_TREE;
3626   decls = NULL_TREE;
3627   while (true)
3628     {
3629       /* Declaring one or more declarators or un-named bit-fields.  */
3630       struct c_declarator *declarator;
3631       bool dummy = false;
3632       if (c_parser_next_token_is (parser, CPP_COLON))
3633 	declarator = build_id_declarator (NULL_TREE);
3634       else
3635 	declarator = c_parser_declarator (parser,
3636 					  specs->typespec_kind != ctsk_none,
3637 					  C_DTR_NORMAL, &dummy);
3638       if (declarator == NULL)
3639 	{
3640 	  c_parser_skip_to_end_of_block_or_statement (parser);
3641 	  break;
3642 	}
3643       if (c_parser_next_token_is (parser, CPP_COLON)
3644 	  || c_parser_next_token_is (parser, CPP_COMMA)
3645 	  || c_parser_next_token_is (parser, CPP_SEMICOLON)
3646 	  || c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3647 	  || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3648 	{
3649 	  tree postfix_attrs = NULL_TREE;
3650 	  tree width = NULL_TREE;
3651 	  tree d;
3652 	  if (c_parser_next_token_is (parser, CPP_COLON))
3653 	    {
3654 	      c_parser_consume_token (parser);
3655 	      width = c_parser_expr_no_commas (parser, NULL).value;
3656 	    }
3657 	  if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3658 	    postfix_attrs = c_parser_gnu_attributes (parser);
3659 	  d = grokfield (c_parser_peek_token (parser)->location,
3660 			 declarator, specs, width, &all_prefix_attrs);
3661 	  decl_attributes (&d, chainon (postfix_attrs,
3662 					all_prefix_attrs), 0);
3663 	  DECL_CHAIN (d) = decls;
3664 	  decls = d;
3665 	  if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3666 	    all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
3667 					prefix_attrs);
3668 	  else
3669 	    all_prefix_attrs = prefix_attrs;
3670 	  if (c_parser_next_token_is (parser, CPP_COMMA))
3671 	    c_parser_consume_token (parser);
3672 	  else if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3673 		   || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3674 	    {
3675 	      /* Semicolon consumed in caller.  */
3676 	      break;
3677 	    }
3678 	  else
3679 	    {
3680 	      c_parser_error (parser, "expected %<,%>, %<;%> or %<}%>");
3681 	      break;
3682 	    }
3683 	}
3684       else
3685 	{
3686 	  c_parser_error (parser,
3687 			  "expected %<:%>, %<,%>, %<;%>, %<}%> or "
3688 			  "%<__attribute__%>");
3689 	  break;
3690 	}
3691     }
3692   return decls;
3693 }
3694 
3695 /* Parse a typeof specifier (a GNU extension).
3696 
3697    typeof-specifier:
3698      typeof ( expression )
3699      typeof ( type-name )
3700 */
3701 
3702 static struct c_typespec
c_parser_typeof_specifier(c_parser * parser)3703 c_parser_typeof_specifier (c_parser *parser)
3704 {
3705   struct c_typespec ret;
3706   ret.kind = ctsk_typeof;
3707   ret.spec = error_mark_node;
3708   ret.expr = NULL_TREE;
3709   ret.expr_const_operands = true;
3710   gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF));
3711   c_parser_consume_token (parser);
3712   c_inhibit_evaluation_warnings++;
3713   in_typeof++;
3714   matching_parens parens;
3715   if (!parens.require_open (parser))
3716     {
3717       c_inhibit_evaluation_warnings--;
3718       in_typeof--;
3719       return ret;
3720     }
3721   if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
3722     {
3723       struct c_type_name *type = c_parser_type_name (parser);
3724       c_inhibit_evaluation_warnings--;
3725       in_typeof--;
3726       if (type != NULL)
3727 	{
3728 	  ret.spec = groktypename (type, &ret.expr, &ret.expr_const_operands);
3729 	  pop_maybe_used (variably_modified_type_p (ret.spec, NULL_TREE));
3730 	}
3731     }
3732   else
3733     {
3734       bool was_vm;
3735       location_t here = c_parser_peek_token (parser)->location;
3736       struct c_expr expr = c_parser_expression (parser);
3737       c_inhibit_evaluation_warnings--;
3738       in_typeof--;
3739       if (TREE_CODE (expr.value) == COMPONENT_REF
3740 	  && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
3741 	error_at (here, "%<typeof%> applied to a bit-field");
3742       mark_exp_read (expr.value);
3743       ret.spec = TREE_TYPE (expr.value);
3744       was_vm = variably_modified_type_p (ret.spec, NULL_TREE);
3745       /* This is returned with the type so that when the type is
3746 	 evaluated, this can be evaluated.  */
3747       if (was_vm)
3748 	ret.expr = c_fully_fold (expr.value, false, &ret.expr_const_operands);
3749       pop_maybe_used (was_vm);
3750     }
3751   parens.skip_until_found_close (parser);
3752   return ret;
3753 }
3754 
3755 /* Parse an alignment-specifier.
3756 
3757    C11 6.7.5:
3758 
3759    alignment-specifier:
3760      _Alignas ( type-name )
3761      _Alignas ( constant-expression )
3762 */
3763 
3764 static tree
c_parser_alignas_specifier(c_parser * parser)3765 c_parser_alignas_specifier (c_parser * parser)
3766 {
3767   tree ret = error_mark_node;
3768   location_t loc = c_parser_peek_token (parser)->location;
3769   gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNAS));
3770   c_parser_consume_token (parser);
3771   if (flag_isoc99)
3772     pedwarn_c99 (loc, OPT_Wpedantic,
3773 		 "ISO C99 does not support %<_Alignas%>");
3774   else
3775     pedwarn_c99 (loc, OPT_Wpedantic,
3776 		 "ISO C90 does not support %<_Alignas%>");
3777   matching_parens parens;
3778   if (!parens.require_open (parser))
3779     return ret;
3780   if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
3781     {
3782       struct c_type_name *type = c_parser_type_name (parser);
3783       if (type != NULL)
3784 	ret = c_sizeof_or_alignof_type (loc, groktypename (type, NULL, NULL),
3785 					false, true, 1);
3786     }
3787   else
3788     ret = c_parser_expr_no_commas (parser, NULL).value;
3789   parens.skip_until_found_close (parser);
3790   return ret;
3791 }
3792 
3793 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
3794    6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7).  If TYPE_SEEN_P then
3795    a typedef name may be redeclared; otherwise it may not.  KIND
3796    indicates which kind of declarator is wanted.  Returns a valid
3797    declarator except in the case of a syntax error in which case NULL is
3798    returned.  *SEEN_ID is set to true if an identifier being declared is
3799    seen; this is used to diagnose bad forms of abstract array declarators
3800    and to determine whether an identifier list is syntactically permitted.
3801 
3802    declarator:
3803      pointer[opt] direct-declarator
3804 
3805    direct-declarator:
3806      identifier
3807      ( gnu-attributes[opt] declarator )
3808      direct-declarator array-declarator
3809      direct-declarator ( parameter-type-list )
3810      direct-declarator ( identifier-list[opt] )
3811 
3812    pointer:
3813      * type-qualifier-list[opt]
3814      * type-qualifier-list[opt] pointer
3815 
3816    type-qualifier-list:
3817      type-qualifier
3818      gnu-attributes
3819      type-qualifier-list type-qualifier
3820      type-qualifier-list gnu-attributes
3821 
3822    array-declarator:
3823      [ type-qualifier-list[opt] assignment-expression[opt] ]
3824      [ static type-qualifier-list[opt] assignment-expression ]
3825      [ type-qualifier-list static assignment-expression ]
3826      [ type-qualifier-list[opt] * ]
3827 
3828    parameter-type-list:
3829      parameter-list
3830      parameter-list , ...
3831 
3832    parameter-list:
3833      parameter-declaration
3834      parameter-list , parameter-declaration
3835 
3836    parameter-declaration:
3837      declaration-specifiers declarator gnu-attributes[opt]
3838      declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
3839 
3840    identifier-list:
3841      identifier
3842      identifier-list , identifier
3843 
3844    abstract-declarator:
3845      pointer
3846      pointer[opt] direct-abstract-declarator
3847 
3848    direct-abstract-declarator:
3849      ( gnu-attributes[opt] abstract-declarator )
3850      direct-abstract-declarator[opt] array-declarator
3851      direct-abstract-declarator[opt] ( parameter-type-list[opt] )
3852 
3853    GNU extensions:
3854 
3855    direct-declarator:
3856      direct-declarator ( parameter-forward-declarations
3857 			 parameter-type-list[opt] )
3858 
3859    direct-abstract-declarator:
3860      direct-abstract-declarator[opt] ( parameter-forward-declarations
3861 				       parameter-type-list[opt] )
3862 
3863    parameter-forward-declarations:
3864      parameter-list ;
3865      parameter-forward-declarations parameter-list ;
3866 
3867    The uses of gnu-attributes shown above are GNU extensions.
3868 
3869    Some forms of array declarator are not included in C99 in the
3870    syntax for abstract declarators; these are disallowed elsewhere.
3871    This may be a defect (DR#289).
3872 
3873    This function also accepts an omitted abstract declarator as being
3874    an abstract declarator, although not part of the formal syntax.  */
3875 
3876 struct c_declarator *
c_parser_declarator(c_parser * parser,bool type_seen_p,c_dtr_syn kind,bool * seen_id)3877 c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
3878 		     bool *seen_id)
3879 {
3880   /* Parse any initial pointer part.  */
3881   if (c_parser_next_token_is (parser, CPP_MULT))
3882     {
3883       struct c_declspecs *quals_attrs = build_null_declspecs ();
3884       struct c_declarator *inner;
3885       c_parser_consume_token (parser);
3886       c_parser_declspecs (parser, quals_attrs, false, false, true,
3887 			  false, false, true, false, cla_prefer_id);
3888       inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
3889       if (inner == NULL)
3890 	return NULL;
3891       else
3892 	return make_pointer_declarator (quals_attrs, inner);
3893     }
3894   /* Now we have a direct declarator, direct abstract declarator or
3895      nothing (which counts as a direct abstract declarator here).  */
3896   return c_parser_direct_declarator (parser, type_seen_p, kind, seen_id);
3897 }
3898 
3899 /* Parse a direct declarator or direct abstract declarator; arguments
3900    as c_parser_declarator.  */
3901 
3902 static struct c_declarator *
c_parser_direct_declarator(c_parser * parser,bool type_seen_p,c_dtr_syn kind,bool * seen_id)3903 c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
3904 			    bool *seen_id)
3905 {
3906   /* The direct declarator must start with an identifier (possibly
3907      omitted) or a parenthesized declarator (possibly abstract).  In
3908      an ordinary declarator, initial parentheses must start a
3909      parenthesized declarator.  In an abstract declarator or parameter
3910      declarator, they could start a parenthesized declarator or a
3911      parameter list.  To tell which, the open parenthesis and any
3912      following gnu-attributes must be read.  If a declaration
3913      specifier or standard attributes follow, then it is a parameter
3914      list; if the specifier is a typedef name, there might be an
3915      ambiguity about redeclaring it, which is resolved in the
3916      direction of treating it as a typedef name.  If a close
3917      parenthesis follows, it is also an empty parameter list, as the
3918      syntax does not permit empty abstract declarators.  Otherwise, it
3919      is a parenthesized declarator (in which case the analysis may be
3920      repeated inside it, recursively).
3921 
3922      ??? There is an ambiguity in a parameter declaration "int
3923      (__attribute__((foo)) x)", where x is not a typedef name: it
3924      could be an abstract declarator for a function, or declare x with
3925      parentheses.  The proper resolution of this ambiguity needs
3926      documenting.  At present we follow an accident of the old
3927      parser's implementation, whereby the first parameter must have
3928      some declaration specifiers other than just gnu-attributes.  Thus as
3929      a parameter declaration it is treated as a parenthesized
3930      parameter named x, and as an abstract declarator it is
3931      rejected.
3932 
3933      ??? Also following the old parser, gnu-attributes inside an empty
3934      parameter list are ignored, making it a list not yielding a
3935      prototype, rather than giving an error or making it have one
3936      parameter with implicit type int.
3937 
3938      ??? Also following the old parser, typedef names may be
3939      redeclared in declarators, but not Objective-C class names.  */
3940 
3941   if (kind != C_DTR_ABSTRACT
3942       && c_parser_next_token_is (parser, CPP_NAME)
3943       && ((type_seen_p
3944 	   && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
3945 	       || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
3946 	  || c_parser_peek_token (parser)->id_kind == C_ID_ID))
3947     {
3948       struct c_declarator *inner
3949 	= build_id_declarator (c_parser_peek_token (parser)->value);
3950       *seen_id = true;
3951       inner->id_loc = c_parser_peek_token (parser)->location;
3952       c_parser_consume_token (parser);
3953       if (c_parser_nth_token_starts_std_attributes (parser, 1))
3954 	inner->u.id.attrs = c_parser_std_attribute_specifier_sequence (parser);
3955       return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3956     }
3957 
3958   if (kind != C_DTR_NORMAL
3959       && c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
3960       && !c_parser_nth_token_starts_std_attributes (parser, 1))
3961     {
3962       struct c_declarator *inner = build_id_declarator (NULL_TREE);
3963       inner->id_loc = c_parser_peek_token (parser)->location;
3964       return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3965     }
3966 
3967   /* Either we are at the end of an abstract declarator, or we have
3968      parentheses.  */
3969 
3970   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3971     {
3972       tree attrs;
3973       struct c_declarator *inner;
3974       c_parser_consume_token (parser);
3975       bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
3976 							    RID_ATTRIBUTE);
3977       attrs = c_parser_gnu_attributes (parser);
3978       if (kind != C_DTR_NORMAL
3979 	  && (c_parser_next_token_starts_declspecs (parser)
3980 	      || (!have_gnu_attrs
3981 		  && c_parser_nth_token_starts_std_attributes (parser, 1))
3982 	      || c_parser_next_token_is (parser, CPP_CLOSE_PAREN)))
3983 	{
3984 	  struct c_arg_info *args
3985 	    = c_parser_parms_declarator (parser, kind == C_DTR_NORMAL,
3986 					 attrs, have_gnu_attrs);
3987 	  if (args == NULL)
3988 	    return NULL;
3989 	  else
3990 	    {
3991 	      inner = build_id_declarator (NULL_TREE);
3992 	      if (!(args->types
3993 		    && args->types != error_mark_node
3994 		    && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
3995 		  && c_parser_nth_token_starts_std_attributes (parser, 1))
3996 		{
3997 		  tree std_attrs
3998 		    = c_parser_std_attribute_specifier_sequence (parser);
3999 		  if (std_attrs)
4000 		    inner = build_attrs_declarator (std_attrs, inner);
4001 		}
4002 	      inner = build_function_declarator (args, inner);
4003 	      return c_parser_direct_declarator_inner (parser, *seen_id,
4004 						       inner);
4005 	    }
4006 	}
4007       /* A parenthesized declarator.  */
4008       inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
4009       if (inner != NULL && attrs != NULL)
4010 	inner = build_attrs_declarator (attrs, inner);
4011       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4012 	{
4013 	  c_parser_consume_token (parser);
4014 	  if (inner == NULL)
4015 	    return NULL;
4016 	  else
4017 	    return c_parser_direct_declarator_inner (parser, *seen_id, inner);
4018 	}
4019       else
4020 	{
4021 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4022 				     "expected %<)%>");
4023 	  return NULL;
4024 	}
4025     }
4026   else
4027     {
4028       if (kind == C_DTR_NORMAL)
4029 	{
4030 	  c_parser_error (parser, "expected identifier or %<(%>");
4031 	  return NULL;
4032 	}
4033       else
4034 	return build_id_declarator (NULL_TREE);
4035     }
4036 }
4037 
4038 /* Parse part of a direct declarator or direct abstract declarator,
4039    given that some (in INNER) has already been parsed; ID_PRESENT is
4040    true if an identifier is present, false for an abstract
4041    declarator.  */
4042 
4043 static struct c_declarator *
c_parser_direct_declarator_inner(c_parser * parser,bool id_present,struct c_declarator * inner)4044 c_parser_direct_declarator_inner (c_parser *parser, bool id_present,
4045 				  struct c_declarator *inner)
4046 {
4047   /* Parse a sequence of array declarators and parameter lists.  */
4048   if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
4049       && !c_parser_nth_token_starts_std_attributes (parser, 1))
4050     {
4051       location_t brace_loc = c_parser_peek_token (parser)->location;
4052       struct c_declarator *declarator;
4053       struct c_declspecs *quals_attrs = build_null_declspecs ();
4054       bool static_seen;
4055       bool star_seen;
4056       struct c_expr dimen;
4057       dimen.value = NULL_TREE;
4058       dimen.original_code = ERROR_MARK;
4059       dimen.original_type = NULL_TREE;
4060       c_parser_consume_token (parser);
4061       c_parser_declspecs (parser, quals_attrs, false, false, true,
4062 			  false, false, false, false, cla_prefer_id);
4063       static_seen = c_parser_next_token_is_keyword (parser, RID_STATIC);
4064       if (static_seen)
4065 	c_parser_consume_token (parser);
4066       if (static_seen && !quals_attrs->declspecs_seen_p)
4067 	c_parser_declspecs (parser, quals_attrs, false, false, true,
4068 			    false, false, false, false, cla_prefer_id);
4069       if (!quals_attrs->declspecs_seen_p)
4070 	quals_attrs = NULL;
4071       /* If "static" is present, there must be an array dimension.
4072 	 Otherwise, there may be a dimension, "*", or no
4073 	 dimension.  */
4074       if (static_seen)
4075 	{
4076 	  star_seen = false;
4077 	  dimen = c_parser_expr_no_commas (parser, NULL);
4078 	}
4079       else
4080 	{
4081 	  if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4082 	    {
4083 	      dimen.value = NULL_TREE;
4084 	      star_seen = false;
4085 	    }
4086 	  else if (c_parser_next_token_is (parser, CPP_MULT))
4087 	    {
4088 	      if (c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_SQUARE)
4089 		{
4090 		  dimen.value = NULL_TREE;
4091 		  star_seen = true;
4092 		  c_parser_consume_token (parser);
4093 		}
4094 	      else
4095 		{
4096 		  star_seen = false;
4097 		  dimen = c_parser_expr_no_commas (parser, NULL);
4098 		}
4099 	    }
4100 	  else
4101 	    {
4102 	      star_seen = false;
4103 	      dimen = c_parser_expr_no_commas (parser, NULL);
4104 	    }
4105 	}
4106       if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4107 	c_parser_consume_token (parser);
4108       else
4109 	{
4110 	  c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
4111 				     "expected %<]%>");
4112 	  return NULL;
4113 	}
4114       if (dimen.value)
4115 	dimen = convert_lvalue_to_rvalue (brace_loc, dimen, true, true);
4116       declarator = build_array_declarator (brace_loc, dimen.value, quals_attrs,
4117 					   static_seen, star_seen);
4118       if (declarator == NULL)
4119 	return NULL;
4120       if (c_parser_nth_token_starts_std_attributes (parser, 1))
4121 	{
4122 	  tree std_attrs
4123 	    = c_parser_std_attribute_specifier_sequence (parser);
4124 	  if (std_attrs)
4125 	    inner = build_attrs_declarator (std_attrs, inner);
4126 	}
4127       inner = set_array_declarator_inner (declarator, inner);
4128       return c_parser_direct_declarator_inner (parser, id_present, inner);
4129     }
4130   else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
4131     {
4132       tree attrs;
4133       struct c_arg_info *args;
4134       c_parser_consume_token (parser);
4135       bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
4136 							    RID_ATTRIBUTE);
4137       attrs = c_parser_gnu_attributes (parser);
4138       args = c_parser_parms_declarator (parser, id_present, attrs,
4139 					have_gnu_attrs);
4140       if (args == NULL)
4141 	return NULL;
4142       else
4143 	{
4144 	  if (!(args->types
4145 		&& args->types != error_mark_node
4146 		&& TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
4147 	      && c_parser_nth_token_starts_std_attributes (parser, 1))
4148 	    {
4149 	      tree std_attrs
4150 		= c_parser_std_attribute_specifier_sequence (parser);
4151 	      if (std_attrs)
4152 		inner = build_attrs_declarator (std_attrs, inner);
4153 	    }
4154 	  inner = build_function_declarator (args, inner);
4155 	  return c_parser_direct_declarator_inner (parser, id_present, inner);
4156 	}
4157     }
4158   return inner;
4159 }
4160 
4161 /* Parse a parameter list or identifier list, including the closing
4162    parenthesis but not the opening one.  ATTRS are the gnu-attributes
4163    at the start of the list.  ID_LIST_OK is true if an identifier list
4164    is acceptable; such a list must not have attributes at the start.
4165    HAVE_GNU_ATTRS says whether any gnu-attributes (including empty
4166    attributes) were present (in which case standard attributes cannot
4167    occur).  */
4168 
4169 static struct c_arg_info *
c_parser_parms_declarator(c_parser * parser,bool id_list_ok,tree attrs,bool have_gnu_attrs)4170 c_parser_parms_declarator (c_parser *parser, bool id_list_ok, tree attrs,
4171 			   bool have_gnu_attrs)
4172 {
4173   push_scope ();
4174   declare_parm_level ();
4175   /* If the list starts with an identifier, it is an identifier list.
4176      Otherwise, it is either a prototype list or an empty list.  */
4177   if (id_list_ok
4178       && !attrs
4179       && c_parser_next_token_is (parser, CPP_NAME)
4180       && c_parser_peek_token (parser)->id_kind == C_ID_ID
4181 
4182       /* Look ahead to detect typos in type names.  */
4183       && c_parser_peek_2nd_token (parser)->type != CPP_NAME
4184       && c_parser_peek_2nd_token (parser)->type != CPP_MULT
4185       && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
4186       && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_SQUARE
4187       && c_parser_peek_2nd_token (parser)->type != CPP_KEYWORD)
4188     {
4189       tree list = NULL_TREE, *nextp = &list;
4190       while (c_parser_next_token_is (parser, CPP_NAME)
4191 	     && c_parser_peek_token (parser)->id_kind == C_ID_ID)
4192 	{
4193 	  *nextp = build_tree_list (NULL_TREE,
4194 				    c_parser_peek_token (parser)->value);
4195 	  nextp = & TREE_CHAIN (*nextp);
4196 	  c_parser_consume_token (parser);
4197 	  if (c_parser_next_token_is_not (parser, CPP_COMMA))
4198 	    break;
4199 	  c_parser_consume_token (parser);
4200 	  if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4201 	    {
4202 	      c_parser_error (parser, "expected identifier");
4203 	      break;
4204 	    }
4205 	}
4206       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4207 	{
4208 	  struct c_arg_info *ret = build_arg_info ();
4209 	  ret->types = list;
4210 	  c_parser_consume_token (parser);
4211 	  pop_scope ();
4212 	  return ret;
4213 	}
4214       else
4215 	{
4216 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4217 				     "expected %<)%>");
4218 	  pop_scope ();
4219 	  return NULL;
4220 	}
4221     }
4222   else
4223     {
4224       struct c_arg_info *ret
4225 	= c_parser_parms_list_declarator (parser, attrs, NULL, have_gnu_attrs);
4226       pop_scope ();
4227       return ret;
4228     }
4229 }
4230 
4231 /* Parse a parameter list (possibly empty), including the closing
4232    parenthesis but not the opening one.  ATTRS are the gnu-attributes
4233    at the start of the list; if HAVE_GNU_ATTRS, there were some such
4234    attributes (possibly empty, in which case ATTRS is NULL_TREE),
4235    which means standard attributes cannot start the list.  EXPR is
4236    NULL or an expression that needs to be evaluated for the side
4237    effects of array size expressions in the parameters.  */
4238 
4239 static struct c_arg_info *
c_parser_parms_list_declarator(c_parser * parser,tree attrs,tree expr,bool have_gnu_attrs)4240 c_parser_parms_list_declarator (c_parser *parser, tree attrs, tree expr,
4241 				bool have_gnu_attrs)
4242 {
4243   bool bad_parm = false;
4244 
4245   /* ??? Following the old parser, forward parameter declarations may
4246      use abstract declarators, and if no real parameter declarations
4247      follow the forward declarations then this is not diagnosed.  Also
4248      note as above that gnu-attributes are ignored as the only contents of
4249      the parentheses, or as the only contents after forward
4250      declarations.  */
4251   if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4252     {
4253       struct c_arg_info *ret = build_arg_info ();
4254       c_parser_consume_token (parser);
4255       return ret;
4256     }
4257   if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4258     {
4259       struct c_arg_info *ret = build_arg_info ();
4260 
4261       if (flag_allow_parameterless_variadic_functions)
4262         {
4263           /* F (...) is allowed.  */
4264           ret->types = NULL_TREE;
4265         }
4266       else
4267         {
4268           /* Suppress -Wold-style-definition for this case.  */
4269           ret->types = error_mark_node;
4270           error_at (c_parser_peek_token (parser)->location,
4271                     "ISO C requires a named argument before %<...%>");
4272         }
4273       c_parser_consume_token (parser);
4274       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4275 	{
4276 	  c_parser_consume_token (parser);
4277 	  return ret;
4278 	}
4279       else
4280 	{
4281 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4282 				     "expected %<)%>");
4283 	  return NULL;
4284 	}
4285     }
4286   /* Nonempty list of parameters, either terminated with semicolon
4287      (forward declarations; recurse) or with close parenthesis (normal
4288      function) or with ", ... )" (variadic function).  */
4289   while (true)
4290     {
4291       /* Parse a parameter.  */
4292       struct c_parm *parm = c_parser_parameter_declaration (parser, attrs,
4293 							    have_gnu_attrs);
4294       attrs = NULL_TREE;
4295       have_gnu_attrs = false;
4296       if (parm == NULL)
4297 	bad_parm = true;
4298       else
4299 	push_parm_decl (parm, &expr);
4300       if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4301 	{
4302 	  tree new_attrs;
4303 	  c_parser_consume_token (parser);
4304 	  mark_forward_parm_decls ();
4305 	  bool new_have_gnu_attrs
4306 	    = c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE);
4307 	  new_attrs = c_parser_gnu_attributes (parser);
4308 	  return c_parser_parms_list_declarator (parser, new_attrs, expr,
4309 						 new_have_gnu_attrs);
4310 	}
4311       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4312 	{
4313 	  c_parser_consume_token (parser);
4314 	  if (bad_parm)
4315 	    return NULL;
4316 	  else
4317 	    return get_parm_info (false, expr);
4318 	}
4319       if (!c_parser_require (parser, CPP_COMMA,
4320 			     "expected %<;%>, %<,%> or %<)%>",
4321 			     UNKNOWN_LOCATION, false))
4322 	{
4323 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4324 	  return NULL;
4325 	}
4326       if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4327 	{
4328 	  c_parser_consume_token (parser);
4329 	  if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4330 	    {
4331 	      c_parser_consume_token (parser);
4332 	      if (bad_parm)
4333 		return NULL;
4334 	      else
4335 		return get_parm_info (true, expr);
4336 	    }
4337 	  else
4338 	    {
4339 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4340 					 "expected %<)%>");
4341 	      return NULL;
4342 	    }
4343 	}
4344     }
4345 }
4346 
4347 /* Parse a parameter declaration.  ATTRS are the gnu-attributes at the
4348    start of the declaration if it is the first parameter;
4349    HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even
4350    empty) there.  */
4351 
4352 static struct c_parm *
c_parser_parameter_declaration(c_parser * parser,tree attrs,bool have_gnu_attrs)4353 c_parser_parameter_declaration (c_parser *parser, tree attrs,
4354 				bool have_gnu_attrs)
4355 {
4356   struct c_declspecs *specs;
4357   struct c_declarator *declarator;
4358   tree prefix_attrs;
4359   tree postfix_attrs = NULL_TREE;
4360   bool dummy = false;
4361 
4362   /* Accept #pragmas between parameter declarations.  */
4363   while (c_parser_next_token_is (parser, CPP_PRAGMA))
4364     c_parser_pragma (parser, pragma_param, NULL);
4365 
4366   if (!c_parser_next_token_starts_declspecs (parser)
4367       && !c_parser_nth_token_starts_std_attributes (parser, 1))
4368     {
4369       c_token *token = c_parser_peek_token (parser);
4370       if (parser->error)
4371 	return NULL;
4372       c_parser_set_source_position_from_token (token);
4373       if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
4374 	{
4375 	  auto_diagnostic_group d;
4376 	  name_hint hint = lookup_name_fuzzy (token->value,
4377 					      FUZZY_LOOKUP_TYPENAME,
4378 					      token->location);
4379 	  if (const char *suggestion = hint.suggestion ())
4380 	    {
4381 	      gcc_rich_location richloc (token->location);
4382 	      richloc.add_fixit_replace (suggestion);
4383 	      error_at (&richloc,
4384 			"unknown type name %qE; did you mean %qs?",
4385 			token->value, suggestion);
4386 	    }
4387 	  else
4388 	    error_at (token->location, "unknown type name %qE", token->value);
4389 	  parser->error = true;
4390 	}
4391       /* ??? In some Objective-C cases '...' isn't applicable so there
4392 	 should be a different message.  */
4393       else
4394 	c_parser_error (parser,
4395 			"expected declaration specifiers or %<...%>");
4396       c_parser_skip_to_end_of_parameter (parser);
4397       return NULL;
4398     }
4399 
4400   location_t start_loc = c_parser_peek_token (parser)->location;
4401 
4402   specs = build_null_declspecs ();
4403   if (attrs)
4404     {
4405       declspecs_add_attrs (input_location, specs, attrs);
4406       attrs = NULL_TREE;
4407     }
4408   c_parser_declspecs (parser, specs, true, true, true, true, false,
4409 		      !have_gnu_attrs, true, cla_nonabstract_decl);
4410   finish_declspecs (specs);
4411   pending_xref_error ();
4412   prefix_attrs = specs->attrs;
4413   specs->attrs = NULL_TREE;
4414   declarator = c_parser_declarator (parser,
4415 				    specs->typespec_kind != ctsk_none,
4416 				    C_DTR_PARM, &dummy);
4417   if (declarator == NULL)
4418     {
4419       c_parser_skip_until_found (parser, CPP_COMMA, NULL);
4420       return NULL;
4421     }
4422   if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4423     postfix_attrs = c_parser_gnu_attributes (parser);
4424 
4425   /* Generate a location for the parameter, ranging from the start of the
4426      initial token to the end of the final token.
4427 
4428      If we have a identifier, then use it for the caret location, e.g.
4429 
4430        extern int callee (int one, int (*two)(int, int), float three);
4431                                    ~~~~~~^~~~~~~~~~~~~~
4432 
4433      otherwise, reuse the start location for the caret location e.g.:
4434 
4435        extern int callee (int one, int (*)(int, int), float three);
4436                                    ^~~~~~~~~~~~~~~~~
4437   */
4438   location_t end_loc = parser->last_token_location;
4439 
4440   /* Find any cdk_id declarator; determine if we have an identifier.  */
4441   c_declarator *id_declarator = declarator;
4442   while (id_declarator && id_declarator->kind != cdk_id)
4443     id_declarator = id_declarator->declarator;
4444   location_t caret_loc = (id_declarator->u.id.id
4445 			  ? id_declarator->id_loc
4446 			  : start_loc);
4447   location_t param_loc = make_location (caret_loc, start_loc, end_loc);
4448 
4449   return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
4450 		       declarator, param_loc);
4451 }
4452 
4453 /* Parse a string literal in an asm expression.  It should not be
4454    translated, and wide string literals are an error although
4455    permitted by the syntax.  This is a GNU extension.
4456 
4457    asm-string-literal:
4458      string-literal
4459 */
4460 
4461 static tree
c_parser_asm_string_literal(c_parser * parser)4462 c_parser_asm_string_literal (c_parser *parser)
4463 {
4464   tree str;
4465   int save_flag = warn_overlength_strings;
4466   warn_overlength_strings = 0;
4467   str = c_parser_string_literal (parser, false, false).value;
4468   warn_overlength_strings = save_flag;
4469   return str;
4470 }
4471 
4472 /* Parse a simple asm expression.  This is used in restricted
4473    contexts, where a full expression with inputs and outputs does not
4474    make sense.  This is a GNU extension.
4475 
4476    simple-asm-expr:
4477      asm ( asm-string-literal )
4478 */
4479 
4480 static tree
c_parser_simple_asm_expr(c_parser * parser)4481 c_parser_simple_asm_expr (c_parser *parser)
4482 {
4483   tree str;
4484   gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
4485   c_parser_consume_token (parser);
4486   matching_parens parens;
4487   if (!parens.require_open (parser))
4488     return NULL_TREE;
4489   str = c_parser_asm_string_literal (parser);
4490   if (!parens.require_close (parser))
4491     {
4492       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4493       return NULL_TREE;
4494     }
4495   return str;
4496 }
4497 
4498 static tree
c_parser_gnu_attribute_any_word(c_parser * parser)4499 c_parser_gnu_attribute_any_word (c_parser *parser)
4500 {
4501   tree attr_name = NULL_TREE;
4502 
4503   if (c_parser_next_token_is (parser, CPP_KEYWORD))
4504     {
4505       /* ??? See comment above about what keywords are accepted here.  */
4506       bool ok;
4507       switch (c_parser_peek_token (parser)->keyword)
4508 	{
4509 	case RID_STATIC:
4510 	case RID_UNSIGNED:
4511 	case RID_LONG:
4512 	case RID_CONST:
4513 	case RID_EXTERN:
4514 	case RID_REGISTER:
4515 	case RID_TYPEDEF:
4516 	case RID_SHORT:
4517 	case RID_INLINE:
4518 	case RID_NORETURN:
4519 	case RID_VOLATILE:
4520 	case RID_SIGNED:
4521 	case RID_AUTO:
4522 	case RID_RESTRICT:
4523 	case RID_COMPLEX:
4524 	case RID_THREAD:
4525 	case RID_INT:
4526 	case RID_CHAR:
4527 	case RID_FLOAT:
4528 	case RID_DOUBLE:
4529 	case RID_VOID:
4530 	case RID_DFLOAT32:
4531 	case RID_DFLOAT64:
4532 	case RID_DFLOAT128:
4533 	CASE_RID_FLOATN_NX:
4534 	case RID_BOOL:
4535 	case RID_FRACT:
4536 	case RID_ACCUM:
4537 	case RID_SAT:
4538 	case RID_TRANSACTION_ATOMIC:
4539 	case RID_TRANSACTION_CANCEL:
4540 	case RID_ATOMIC:
4541 	case RID_AUTO_TYPE:
4542 	case RID_INT_N_0:
4543 	case RID_INT_N_1:
4544 	case RID_INT_N_2:
4545 	case RID_INT_N_3:
4546 	  ok = true;
4547 	  break;
4548 	default:
4549 	  ok = false;
4550 	  break;
4551 	}
4552       if (!ok)
4553 	return NULL_TREE;
4554 
4555       /* Accept __attribute__((__const)) as __attribute__((const)) etc.  */
4556       attr_name = ridpointers[(int) c_parser_peek_token (parser)->keyword];
4557     }
4558   else if (c_parser_next_token_is (parser, CPP_NAME))
4559     attr_name = c_parser_peek_token (parser)->value;
4560 
4561   return attr_name;
4562 }
4563 
4564 /* Parse attribute arguments.  This is a common form of syntax
4565    covering all currently valid GNU and standard attributes.
4566 
4567    gnu-attribute-arguments:
4568      identifier
4569      identifier , nonempty-expr-list
4570      expr-list
4571 
4572    where the "identifier" must not be declared as a type.  ??? Why not
4573    allow identifiers declared as types to start the arguments?  */
4574 
4575 static tree
c_parser_attribute_arguments(c_parser * parser,bool takes_identifier,bool require_string,bool allow_empty_args)4576 c_parser_attribute_arguments (c_parser *parser, bool takes_identifier,
4577 			      bool require_string, bool allow_empty_args)
4578 {
4579   vec<tree, va_gc> *expr_list;
4580   tree attr_args;
4581   /* Parse the attribute contents.  If they start with an
4582      identifier which is followed by a comma or close
4583      parenthesis, then the arguments start with that
4584      identifier; otherwise they are an expression list.
4585      In objective-c the identifier may be a classname.  */
4586   if (c_parser_next_token_is (parser, CPP_NAME)
4587       && (c_parser_peek_token (parser)->id_kind == C_ID_ID
4588 	  || (c_dialect_objc ()
4589 	      && c_parser_peek_token (parser)->id_kind
4590 	      == C_ID_CLASSNAME))
4591       && ((c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
4592 	  || (c_parser_peek_2nd_token (parser)->type
4593 	      == CPP_CLOSE_PAREN))
4594       && (takes_identifier
4595 	  || (c_dialect_objc ()
4596 	      && c_parser_peek_token (parser)->id_kind
4597 	      == C_ID_CLASSNAME)))
4598     {
4599       tree arg1 = c_parser_peek_token (parser)->value;
4600       c_parser_consume_token (parser);
4601       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4602 	attr_args = build_tree_list (NULL_TREE, arg1);
4603       else
4604 	{
4605 	  tree tree_list;
4606 	  c_parser_consume_token (parser);
4607 	  expr_list = c_parser_expr_list (parser, false, true,
4608 					  NULL, NULL, NULL, NULL);
4609 	  tree_list = build_tree_list_vec (expr_list);
4610 	  attr_args = tree_cons (NULL_TREE, arg1, tree_list);
4611 	  release_tree_vector (expr_list);
4612 	}
4613     }
4614   else
4615     {
4616       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4617 	{
4618 	  if (!allow_empty_args)
4619 	    error_at (c_parser_peek_token (parser)->location,
4620 		      "parentheses must be omitted if "
4621 		      "attribute argument list is empty");
4622 	  attr_args = NULL_TREE;
4623 	}
4624       else if (require_string)
4625 	{
4626 	  /* The only valid argument for this attribute is a string
4627 	     literal.  Handle this specially here to avoid accepting
4628 	     string literals with excess parentheses.  */
4629 	  tree string = c_parser_string_literal (parser, false, true).value;
4630 	  attr_args = build_tree_list (NULL_TREE, string);
4631 	}
4632       else
4633 	{
4634 	  expr_list = c_parser_expr_list (parser, false, true,
4635 					  NULL, NULL, NULL, NULL);
4636 	  attr_args = build_tree_list_vec (expr_list);
4637 	  release_tree_vector (expr_list);
4638 	}
4639     }
4640   return attr_args;
4641 }
4642 
4643 /* Parse (possibly empty) gnu-attributes.  This is a GNU extension.
4644 
4645    gnu-attributes:
4646      empty
4647      gnu-attributes gnu-attribute
4648 
4649    gnu-attribute:
4650      __attribute__ ( ( gnu-attribute-list ) )
4651 
4652    gnu-attribute-list:
4653      gnu-attrib
4654      gnu-attribute_list , gnu-attrib
4655 
4656    gnu-attrib:
4657      empty
4658      any-word
4659      any-word ( gnu-attribute-arguments )
4660 
4661    where "any-word" may be any identifier (including one declared as a
4662    type), a reserved word storage class specifier, type specifier or
4663    type qualifier.  ??? This still leaves out most reserved keywords
4664    (following the old parser), shouldn't we include them?
4665    When EXPECT_COMMA is true, expect the attribute to be preceded
4666    by a comma and fail if it isn't.
4667    When EMPTY_OK is true, allow and consume any number of consecutive
4668    commas with no attributes in between.  */
4669 
4670 static tree
c_parser_gnu_attribute(c_parser * parser,tree attrs,bool expect_comma=false,bool empty_ok=true)4671 c_parser_gnu_attribute (c_parser *parser, tree attrs,
4672 			bool expect_comma = false, bool empty_ok = true)
4673 {
4674   bool comma_first = c_parser_next_token_is (parser, CPP_COMMA);
4675   if (!comma_first
4676       && !c_parser_next_token_is (parser, CPP_NAME)
4677       && !c_parser_next_token_is (parser, CPP_KEYWORD))
4678     return NULL_TREE;
4679 
4680   while (c_parser_next_token_is (parser, CPP_COMMA))
4681     {
4682       c_parser_consume_token (parser);
4683       if (!empty_ok)
4684 	return attrs;
4685     }
4686 
4687   tree attr_name = c_parser_gnu_attribute_any_word (parser);
4688   if (attr_name == NULL_TREE)
4689     return NULL_TREE;
4690 
4691   attr_name = canonicalize_attr_name (attr_name);
4692   c_parser_consume_token (parser);
4693 
4694   tree attr;
4695   if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
4696     {
4697       if (expect_comma && !comma_first)
4698 	{
4699 	  /* A comma is missing between the last attribute on the chain
4700 	     and this one.  */
4701 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4702 				     "expected %<)%>");
4703 	  return error_mark_node;
4704 	}
4705       attr = build_tree_list (attr_name, NULL_TREE);
4706       /* Add this attribute to the list.  */
4707       attrs = chainon (attrs, attr);
4708       return attrs;
4709     }
4710   c_parser_consume_token (parser);
4711 
4712   tree attr_args
4713     = c_parser_attribute_arguments (parser,
4714 				    attribute_takes_identifier_p (attr_name),
4715 				    false, true);
4716 
4717   attr = build_tree_list (attr_name, attr_args);
4718   if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4719     c_parser_consume_token (parser);
4720   else
4721     {
4722       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4723 				 "expected %<)%>");
4724       return error_mark_node;
4725     }
4726 
4727   if (expect_comma && !comma_first)
4728     {
4729       /* A comma is missing between the last attribute on the chain
4730 	 and this one.  */
4731       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4732 				 "expected %<)%>");
4733       return error_mark_node;
4734     }
4735 
4736   /* Add this attribute to the list.  */
4737   attrs = chainon (attrs, attr);
4738   return attrs;
4739 }
4740 
4741 static tree
c_parser_gnu_attributes(c_parser * parser)4742 c_parser_gnu_attributes (c_parser *parser)
4743 {
4744   tree attrs = NULL_TREE;
4745   while (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4746     {
4747       bool save_translate_strings_p = parser->translate_strings_p;
4748       parser->translate_strings_p = false;
4749       /* Consume the `__attribute__' keyword.  */
4750       c_parser_consume_token (parser);
4751       /* Look for the two `(' tokens.  */
4752       if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4753 	{
4754 	  parser->translate_strings_p = save_translate_strings_p;
4755 	  return attrs;
4756 	}
4757       if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4758 	{
4759 	  parser->translate_strings_p = save_translate_strings_p;
4760 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4761 	  return attrs;
4762 	}
4763       /* Parse the attribute list.  Require a comma between successive
4764 	 (possibly empty) attributes.  */
4765       for (bool expect_comma = false; ; expect_comma = true)
4766 	{
4767 	  /* Parse a single attribute.  */
4768 	  tree attr = c_parser_gnu_attribute (parser, attrs, expect_comma);
4769 	  if (attr == error_mark_node)
4770 	    return attrs;
4771 	  if (!attr)
4772 	    break;
4773 	  attrs = attr;
4774       }
4775 
4776       /* Look for the two `)' tokens.  */
4777       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4778 	c_parser_consume_token (parser);
4779       else
4780 	{
4781 	  parser->translate_strings_p = save_translate_strings_p;
4782 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4783 				     "expected %<)%>");
4784 	  return attrs;
4785 	}
4786       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4787 	c_parser_consume_token (parser);
4788       else
4789 	{
4790 	  parser->translate_strings_p = save_translate_strings_p;
4791 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4792 				     "expected %<)%>");
4793 	  return attrs;
4794 	}
4795       parser->translate_strings_p = save_translate_strings_p;
4796     }
4797 
4798   return attrs;
4799 }
4800 
4801 /* Parse an optional balanced token sequence.
4802 
4803    balanced-token-sequence:
4804      balanced-token
4805      balanced-token-sequence balanced-token
4806 
4807    balanced-token:
4808      ( balanced-token-sequence[opt] )
4809      [ balanced-token-sequence[opt] ]
4810      { balanced-token-sequence[opt] }
4811      any token other than ()[]{}
4812 */
4813 
4814 static void
c_parser_balanced_token_sequence(c_parser * parser)4815 c_parser_balanced_token_sequence (c_parser *parser)
4816 {
4817   while (true)
4818     {
4819       c_token *token = c_parser_peek_token (parser);
4820       switch (token->type)
4821 	{
4822 	case CPP_OPEN_BRACE:
4823 	  {
4824 	    matching_braces braces;
4825 	    braces.consume_open (parser);
4826 	    c_parser_balanced_token_sequence (parser);
4827 	    braces.require_close (parser);
4828 	    break;
4829 	  }
4830 
4831 	case CPP_OPEN_PAREN:
4832 	  {
4833 	    matching_parens parens;
4834 	    parens.consume_open (parser);
4835 	    c_parser_balanced_token_sequence (parser);
4836 	    parens.require_close (parser);
4837 	    break;
4838 	  }
4839 
4840 	case CPP_OPEN_SQUARE:
4841 	  c_parser_consume_token (parser);
4842 	  c_parser_balanced_token_sequence (parser);
4843 	  c_parser_require (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
4844 	  break;
4845 
4846 	case CPP_CLOSE_BRACE:
4847 	case CPP_CLOSE_PAREN:
4848 	case CPP_CLOSE_SQUARE:
4849 	case CPP_EOF:
4850 	  return;
4851 
4852 	case CPP_PRAGMA:
4853 	  c_parser_consume_pragma (parser);
4854 	  c_parser_skip_to_pragma_eol (parser, false);
4855 	  break;
4856 
4857 	default:
4858 	  c_parser_consume_token (parser);
4859 	  break;
4860 	}
4861     }
4862 }
4863 
4864 /* Parse standard (C2X) attributes (including GNU attributes in the
4865    gnu:: namespace).
4866 
4867    attribute-specifier-sequence:
4868      attribute-specifier-sequence[opt] attribute-specifier
4869 
4870    attribute-specifier:
4871      [ [ attribute-list ] ]
4872 
4873    attribute-list:
4874      attribute[opt]
4875      attribute-list, attribute[opt]
4876 
4877    attribute:
4878      attribute-token attribute-argument-clause[opt]
4879 
4880    attribute-token:
4881      standard-attribute
4882      attribute-prefixed-token
4883 
4884    standard-attribute:
4885      identifier
4886 
4887    attribute-prefixed-token:
4888      attribute-prefix :: identifier
4889 
4890    attribute-prefix:
4891      identifier
4892 
4893    attribute-argument-clause:
4894      ( balanced-token-sequence[opt] )
4895 
4896    Keywords are accepted as identifiers for this purpose.
4897 */
4898 
4899 static tree
c_parser_std_attribute(c_parser * parser,bool for_tm)4900 c_parser_std_attribute (c_parser *parser, bool for_tm)
4901 {
4902   c_token *token = c_parser_peek_token (parser);
4903   tree ns, name, attribute;
4904 
4905   /* Parse the attribute-token.  */
4906   if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
4907     {
4908       c_parser_error (parser, "expected identifier");
4909       return error_mark_node;
4910     }
4911   name = canonicalize_attr_name (token->value);
4912   c_parser_consume_token (parser);
4913   if (c_parser_next_token_is (parser, CPP_SCOPE))
4914     {
4915       ns = name;
4916       c_parser_consume_token (parser);
4917       token = c_parser_peek_token (parser);
4918       if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
4919 	{
4920 	  c_parser_error (parser, "expected identifier");
4921 	  return error_mark_node;
4922 	}
4923       name = canonicalize_attr_name (token->value);
4924       c_parser_consume_token (parser);
4925     }
4926   else
4927     ns = NULL_TREE;
4928   attribute = build_tree_list (build_tree_list (ns, name), NULL_TREE);
4929 
4930   /* Parse the arguments, if any.  */
4931   const attribute_spec *as = lookup_attribute_spec (TREE_PURPOSE (attribute));
4932   if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
4933     goto out;
4934   {
4935     location_t open_loc = c_parser_peek_token (parser)->location;
4936     matching_parens parens;
4937     parens.consume_open (parser);
4938     if ((as && as->max_length == 0)
4939 	/* Special-case the transactional-memory attribute "outer",
4940 	   which is specially handled but not registered as an
4941 	   attribute, to avoid allowing arbitrary balanced token
4942 	   sequences as arguments.  */
4943 	|| is_attribute_p ("outer", name))
4944       {
4945 	error_at (open_loc, "%qE attribute does not take any arguments", name);
4946 	parens.skip_until_found_close (parser);
4947 	return error_mark_node;
4948       }
4949     /* If this is a fake attribute created to handle -Wno-attributes,
4950        we must skip parsing the arguments.  */
4951     if (as && !attribute_ignored_p (as))
4952       {
4953 	bool takes_identifier
4954 	  = (ns != NULL_TREE
4955 	     && strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0
4956 	     && attribute_takes_identifier_p (name));
4957 	bool require_string
4958 	  = (ns == NULL_TREE
4959 	     && (strcmp (IDENTIFIER_POINTER (name), "deprecated") == 0
4960 		 || strcmp (IDENTIFIER_POINTER (name), "nodiscard") == 0));
4961 	TREE_VALUE (attribute)
4962 	  = c_parser_attribute_arguments (parser, takes_identifier,
4963 					  require_string, false);
4964       }
4965     else
4966       c_parser_balanced_token_sequence (parser);
4967     parens.require_close (parser);
4968   }
4969  out:
4970   if (ns == NULL_TREE && !for_tm && !as)
4971     {
4972       /* An attribute with standard syntax and no namespace specified
4973 	 is a constraint violation if it is not one of the known
4974 	 standard attributes.  Diagnose it here with a pedwarn and
4975 	 then discard it to prevent a duplicate warning later.  */
4976       pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored",
4977 	       name);
4978       return error_mark_node;
4979     }
4980   return attribute;
4981 }
4982 
4983 static tree
c_parser_std_attribute_specifier(c_parser * parser,bool for_tm)4984 c_parser_std_attribute_specifier (c_parser *parser, bool for_tm)
4985 {
4986   location_t loc = c_parser_peek_token (parser)->location;
4987   if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
4988     return NULL_TREE;
4989   if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
4990     {
4991       c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
4992       return NULL_TREE;
4993     }
4994   if (!for_tm)
4995     pedwarn_c11 (loc, OPT_Wpedantic,
4996 		 "ISO C does not support %<[[]]%> attributes before C2X");
4997   tree attributes = NULL_TREE;
4998   while (true)
4999     {
5000       c_token *token = c_parser_peek_token (parser);
5001       if (token->type == CPP_CLOSE_SQUARE)
5002 	break;
5003       if (token->type == CPP_COMMA)
5004 	{
5005 	  c_parser_consume_token (parser);
5006 	  continue;
5007 	}
5008       tree attribute = c_parser_std_attribute (parser, for_tm);
5009       if (attribute != error_mark_node)
5010 	{
5011 	  TREE_CHAIN (attribute) = attributes;
5012 	  attributes = attribute;
5013 	}
5014       if (c_parser_next_token_is_not (parser, CPP_COMMA))
5015 	break;
5016     }
5017   c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5018   c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5019   return nreverse (attributes);
5020 }
5021 
5022 /* Look past an optional balanced token sequence of raw look-ahead
5023    tokens starting with the *Nth token.  *N is updated to point to the
5024    following token.  Return true if such a sequence was found, false
5025    if the tokens parsed were not balanced.  */
5026 
5027 static bool
c_parser_check_balanced_raw_token_sequence(c_parser * parser,unsigned int * n)5028 c_parser_check_balanced_raw_token_sequence (c_parser *parser, unsigned int *n)
5029 {
5030   while (true)
5031     {
5032       c_token *token = c_parser_peek_nth_token_raw (parser, *n);
5033       switch (token->type)
5034 	{
5035 	case CPP_OPEN_BRACE:
5036 	  {
5037 	    ++*n;
5038 	    if (c_parser_check_balanced_raw_token_sequence (parser, n))
5039 	      {
5040 		token = c_parser_peek_nth_token_raw (parser, *n);
5041 		if (token->type == CPP_CLOSE_BRACE)
5042 		  ++*n;
5043 		else
5044 		  return false;
5045 	      }
5046 	    else
5047 	      return false;
5048 	    break;
5049 	  }
5050 
5051 	case CPP_OPEN_PAREN:
5052 	  {
5053 	    ++*n;
5054 	    if (c_parser_check_balanced_raw_token_sequence (parser, n))
5055 	      {
5056 		token = c_parser_peek_nth_token_raw (parser, *n);
5057 		if (token->type == CPP_CLOSE_PAREN)
5058 		  ++*n;
5059 		else
5060 		  return false;
5061 	      }
5062 	    else
5063 	      return false;
5064 	    break;
5065 	  }
5066 
5067 	case CPP_OPEN_SQUARE:
5068 	  {
5069 	    ++*n;
5070 	    if (c_parser_check_balanced_raw_token_sequence (parser, n))
5071 	      {
5072 		token = c_parser_peek_nth_token_raw (parser, *n);
5073 		if (token->type == CPP_CLOSE_SQUARE)
5074 		  ++*n;
5075 		else
5076 		  return false;
5077 	      }
5078 	    else
5079 	      return false;
5080 	    break;
5081 	  }
5082 
5083 	case CPP_CLOSE_BRACE:
5084 	case CPP_CLOSE_PAREN:
5085 	case CPP_CLOSE_SQUARE:
5086 	case CPP_EOF:
5087 	  return true;
5088 
5089 	default:
5090 	  ++*n;
5091 	  break;
5092 	}
5093     }
5094 }
5095 
5096 /* Return whether standard attributes start with the Nth token.  */
5097 
5098 static bool
c_parser_nth_token_starts_std_attributes(c_parser * parser,unsigned int n)5099 c_parser_nth_token_starts_std_attributes (c_parser *parser, unsigned int n)
5100 {
5101   if (!(c_parser_peek_nth_token (parser, n)->type == CPP_OPEN_SQUARE
5102 	&& c_parser_peek_nth_token (parser, n + 1)->type == CPP_OPEN_SQUARE))
5103     return false;
5104   /* In C, '[[' must start attributes.  In Objective-C, we need to
5105      check whether '[[' is matched by ']]'.  */
5106   if (!c_dialect_objc ())
5107     return true;
5108   n += 2;
5109   if (!c_parser_check_balanced_raw_token_sequence (parser, &n))
5110     return false;
5111   c_token *token = c_parser_peek_nth_token_raw (parser, n);
5112   if (token->type != CPP_CLOSE_SQUARE)
5113     return false;
5114   token = c_parser_peek_nth_token_raw (parser, n + 1);
5115   return token->type == CPP_CLOSE_SQUARE;
5116 }
5117 
5118 static tree
c_parser_std_attribute_specifier_sequence(c_parser * parser)5119 c_parser_std_attribute_specifier_sequence (c_parser *parser)
5120 {
5121   tree attributes = NULL_TREE;
5122   do
5123     {
5124       tree attrs = c_parser_std_attribute_specifier (parser, false);
5125       attributes = chainon (attributes, attrs);
5126     }
5127   while (c_parser_nth_token_starts_std_attributes (parser, 1));
5128   return attributes;
5129 }
5130 
5131 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7).  ALIGNAS_OK
5132    says whether alignment specifiers are OK (only in cases that might
5133    be the type name of a compound literal).
5134 
5135    type-name:
5136      specifier-qualifier-list abstract-declarator[opt]
5137 */
5138 
5139 struct c_type_name *
c_parser_type_name(c_parser * parser,bool alignas_ok)5140 c_parser_type_name (c_parser *parser, bool alignas_ok)
5141 {
5142   struct c_declspecs *specs = build_null_declspecs ();
5143   struct c_declarator *declarator;
5144   struct c_type_name *ret;
5145   bool dummy = false;
5146   c_parser_declspecs (parser, specs, false, true, true, alignas_ok, false,
5147 		      false, true, cla_prefer_type);
5148   if (!specs->declspecs_seen_p)
5149     {
5150       c_parser_error (parser, "expected specifier-qualifier-list");
5151       return NULL;
5152     }
5153   if (specs->type != error_mark_node)
5154     {
5155       pending_xref_error ();
5156       finish_declspecs (specs);
5157     }
5158   declarator = c_parser_declarator (parser,
5159 				    specs->typespec_kind != ctsk_none,
5160 				    C_DTR_ABSTRACT, &dummy);
5161   if (declarator == NULL)
5162     return NULL;
5163   ret = XOBNEW (&parser_obstack, struct c_type_name);
5164   ret->specs = specs;
5165   ret->declarator = declarator;
5166   return ret;
5167 }
5168 
5169 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
5170 
5171    initializer:
5172      assignment-expression
5173      { initializer-list }
5174      { initializer-list , }
5175 
5176    initializer-list:
5177      designation[opt] initializer
5178      initializer-list , designation[opt] initializer
5179 
5180    designation:
5181      designator-list =
5182 
5183    designator-list:
5184      designator
5185      designator-list designator
5186 
5187    designator:
5188      array-designator
5189      . identifier
5190 
5191    array-designator:
5192      [ constant-expression ]
5193 
5194    GNU extensions:
5195 
5196    initializer:
5197      { }
5198 
5199    designation:
5200      array-designator
5201      identifier :
5202 
5203    array-designator:
5204      [ constant-expression ... constant-expression ]
5205 
5206    Any expression without commas is accepted in the syntax for the
5207    constant-expressions, with non-constant expressions rejected later.
5208 
5209    DECL is the declaration we're parsing this initializer for.
5210 
5211    This function is only used for top-level initializers; for nested
5212    ones, see c_parser_initval.  */
5213 
5214 static struct c_expr
c_parser_initializer(c_parser * parser,tree decl)5215 c_parser_initializer (c_parser *parser, tree decl)
5216 {
5217   if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
5218     return c_parser_braced_init (parser, NULL_TREE, false, NULL);
5219   else
5220     {
5221       struct c_expr ret;
5222       location_t loc = c_parser_peek_token (parser)->location;
5223       ret = c_parser_expr_no_commas (parser, NULL);
5224       /* This is handled mostly by gimplify.cc, but we have to deal with
5225 	 not warning about int x = x; as it is a GCC extension to turn off
5226 	 this warning but only if warn_init_self is zero.  */
5227       if (VAR_P (decl)
5228 	  && !DECL_EXTERNAL (decl)
5229 	  && !TREE_STATIC (decl)
5230 	  && ret.value == decl
5231 	  && !warning_enabled_at (DECL_SOURCE_LOCATION (decl), OPT_Winit_self))
5232 	suppress_warning (decl, OPT_Winit_self);
5233       if (TREE_CODE (ret.value) != STRING_CST
5234 	  && TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR)
5235 	ret = convert_lvalue_to_rvalue (loc, ret, true, true);
5236       return ret;
5237     }
5238 }
5239 
5240 /* The location of the last comma within the current initializer list,
5241    or UNKNOWN_LOCATION if not within one.  */
5242 
5243 location_t last_init_list_comma;
5244 
5245 /* Parse a braced initializer list.  TYPE is the type specified for a
5246    compound literal, and NULL_TREE for other initializers and for
5247    nested braced lists.  NESTED_P is true for nested braced lists,
5248    false for the list of a compound literal or the list that is the
5249    top-level initializer in a declaration.  */
5250 
5251 static struct c_expr
c_parser_braced_init(c_parser * parser,tree type,bool nested_p,struct obstack * outer_obstack)5252 c_parser_braced_init (c_parser *parser, tree type, bool nested_p,
5253 		      struct obstack *outer_obstack)
5254 {
5255   struct c_expr ret;
5256   struct obstack braced_init_obstack;
5257   location_t brace_loc = c_parser_peek_token (parser)->location;
5258   gcc_obstack_init (&braced_init_obstack);
5259   gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
5260   matching_braces braces;
5261   braces.consume_open (parser);
5262   if (nested_p)
5263     {
5264       finish_implicit_inits (brace_loc, outer_obstack);
5265       push_init_level (brace_loc, 0, &braced_init_obstack);
5266     }
5267   else
5268     really_start_incremental_init (type);
5269   if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5270     {
5271       pedwarn (brace_loc, OPT_Wpedantic, "ISO C forbids empty initializer braces");
5272     }
5273   else
5274     {
5275       /* Parse a non-empty initializer list, possibly with a trailing
5276 	 comma.  */
5277       while (true)
5278 	{
5279 	  c_parser_initelt (parser, &braced_init_obstack);
5280 	  if (parser->error)
5281 	    break;
5282 	  if (c_parser_next_token_is (parser, CPP_COMMA))
5283 	    {
5284 	      last_init_list_comma = c_parser_peek_token (parser)->location;
5285 	      c_parser_consume_token (parser);
5286 	    }
5287 	  else
5288 	    break;
5289 	  if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5290 	    break;
5291 	}
5292     }
5293   c_token *next_tok = c_parser_peek_token (parser);
5294   if (next_tok->type != CPP_CLOSE_BRACE)
5295     {
5296       ret.set_error ();
5297       ret.original_code = ERROR_MARK;
5298       ret.original_type = NULL;
5299       braces.skip_until_found_close (parser);
5300       pop_init_level (brace_loc, 0, &braced_init_obstack, last_init_list_comma);
5301       obstack_free (&braced_init_obstack, NULL);
5302       return ret;
5303     }
5304   location_t close_loc = next_tok->location;
5305   c_parser_consume_token (parser);
5306   ret = pop_init_level (brace_loc, 0, &braced_init_obstack, close_loc);
5307   obstack_free (&braced_init_obstack, NULL);
5308   set_c_expr_source_range (&ret, brace_loc, close_loc);
5309   return ret;
5310 }
5311 
5312 /* Parse a nested initializer, including designators.  */
5313 
5314 static void
c_parser_initelt(c_parser * parser,struct obstack * braced_init_obstack)5315 c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
5316 {
5317   /* Parse any designator or designator list.  A single array
5318      designator may have the subsequent "=" omitted in GNU C, but a
5319      longer list or a structure member designator may not.  */
5320   if (c_parser_next_token_is (parser, CPP_NAME)
5321       && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
5322     {
5323       /* Old-style structure member designator.  */
5324       set_init_label (c_parser_peek_token (parser)->location,
5325 		      c_parser_peek_token (parser)->value,
5326 		      c_parser_peek_token (parser)->location,
5327 		      braced_init_obstack);
5328       /* Use the colon as the error location.  */
5329       pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_Wpedantic,
5330 	       "obsolete use of designated initializer with %<:%>");
5331       c_parser_consume_token (parser);
5332       c_parser_consume_token (parser);
5333     }
5334   else
5335     {
5336       /* des_seen is 0 if there have been no designators, 1 if there
5337 	 has been a single array designator and 2 otherwise.  */
5338       int des_seen = 0;
5339       /* Location of a designator.  */
5340       location_t des_loc = UNKNOWN_LOCATION;  /* Quiet warning.  */
5341       while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
5342 	     || c_parser_next_token_is (parser, CPP_DOT))
5343 	{
5344 	  int des_prev = des_seen;
5345 	  if (!des_seen)
5346 	    des_loc = c_parser_peek_token (parser)->location;
5347 	  if (des_seen < 2)
5348 	    des_seen++;
5349 	  if (c_parser_next_token_is (parser, CPP_DOT))
5350 	    {
5351 	      des_seen = 2;
5352 	      c_parser_consume_token (parser);
5353 	      if (c_parser_next_token_is (parser, CPP_NAME))
5354 		{
5355 		  set_init_label (des_loc, c_parser_peek_token (parser)->value,
5356 				  c_parser_peek_token (parser)->location,
5357 				  braced_init_obstack);
5358 		  c_parser_consume_token (parser);
5359 		}
5360 	      else
5361 		{
5362 		  struct c_expr init;
5363 		  init.set_error ();
5364 		  init.original_code = ERROR_MARK;
5365 		  init.original_type = NULL;
5366 		  c_parser_error (parser, "expected identifier");
5367 		  c_parser_skip_until_found (parser, CPP_COMMA, NULL);
5368 		  process_init_element (input_location, init, false,
5369 					braced_init_obstack);
5370 		  return;
5371 		}
5372 	    }
5373 	  else
5374 	    {
5375 	      tree first, second;
5376 	      location_t ellipsis_loc = UNKNOWN_LOCATION;  /* Quiet warning.  */
5377 	      location_t array_index_loc = UNKNOWN_LOCATION;
5378 	      /* ??? Following the old parser, [ objc-receiver
5379 		 objc-message-args ] is accepted as an initializer,
5380 		 being distinguished from a designator by what follows
5381 		 the first assignment expression inside the square
5382 		 brackets, but after a first array designator a
5383 		 subsequent square bracket is for Objective-C taken to
5384 		 start an expression, using the obsolete form of
5385 		 designated initializer without '=', rather than
5386 		 possibly being a second level of designation: in LALR
5387 		 terms, the '[' is shifted rather than reducing
5388 		 designator to designator-list.  */
5389 	      if (des_prev == 1 && c_dialect_objc ())
5390 		{
5391 		  des_seen = des_prev;
5392 		  break;
5393 		}
5394 	      if (des_prev == 0 && c_dialect_objc ())
5395 		{
5396 		  /* This might be an array designator or an
5397 		     Objective-C message expression.  If the former,
5398 		     continue parsing here; if the latter, parse the
5399 		     remainder of the initializer given the starting
5400 		     primary-expression.  ??? It might make sense to
5401 		     distinguish when des_prev == 1 as well; see
5402 		     previous comment.  */
5403 		  tree rec, args;
5404 		  struct c_expr mexpr;
5405 		  c_parser_consume_token (parser);
5406 		  if (c_parser_peek_token (parser)->type == CPP_NAME
5407 		      && ((c_parser_peek_token (parser)->id_kind
5408 			   == C_ID_TYPENAME)
5409 			  || (c_parser_peek_token (parser)->id_kind
5410 			      == C_ID_CLASSNAME)))
5411 		    {
5412 		      /* Type name receiver.  */
5413 		      tree id = c_parser_peek_token (parser)->value;
5414 		      c_parser_consume_token (parser);
5415 		      rec = objc_get_class_reference (id);
5416 		      goto parse_message_args;
5417 		    }
5418 		  first = c_parser_expr_no_commas (parser, NULL).value;
5419 		  mark_exp_read (first);
5420 		  if (c_parser_next_token_is (parser, CPP_ELLIPSIS)
5421 		      || c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
5422 		    goto array_desig_after_first;
5423 		  /* Expression receiver.  So far only one part
5424 		     without commas has been parsed; there might be
5425 		     more of the expression.  */
5426 		  rec = first;
5427 		  while (c_parser_next_token_is (parser, CPP_COMMA))
5428 		    {
5429 		      struct c_expr next;
5430 		      location_t comma_loc, exp_loc;
5431 		      comma_loc = c_parser_peek_token (parser)->location;
5432 		      c_parser_consume_token (parser);
5433 		      exp_loc = c_parser_peek_token (parser)->location;
5434 		      next = c_parser_expr_no_commas (parser, NULL);
5435 		      next = convert_lvalue_to_rvalue (exp_loc, next,
5436 						       true, true);
5437 		      rec = build_compound_expr (comma_loc, rec, next.value);
5438 		    }
5439 		parse_message_args:
5440 		  /* Now parse the objc-message-args.  */
5441 		  args = c_parser_objc_message_args (parser);
5442 		  c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5443 					     "expected %<]%>");
5444 		  mexpr.value
5445 		    = objc_build_message_expr (rec, args);
5446 		  mexpr.original_code = ERROR_MARK;
5447 		  mexpr.original_type = NULL;
5448 		  /* Now parse and process the remainder of the
5449 		     initializer, starting with this message
5450 		     expression as a primary-expression.  */
5451 		  c_parser_initval (parser, &mexpr, braced_init_obstack);
5452 		  return;
5453 		}
5454 	      c_parser_consume_token (parser);
5455 	      array_index_loc = c_parser_peek_token (parser)->location;
5456 	      first = c_parser_expr_no_commas (parser, NULL).value;
5457 	      mark_exp_read (first);
5458 	    array_desig_after_first:
5459 	      if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
5460 		{
5461 		  ellipsis_loc = c_parser_peek_token (parser)->location;
5462 		  c_parser_consume_token (parser);
5463 		  second = c_parser_expr_no_commas (parser, NULL).value;
5464 		  mark_exp_read (second);
5465 		}
5466 	      else
5467 		second = NULL_TREE;
5468 	      if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
5469 		{
5470 		  c_parser_consume_token (parser);
5471 		  set_init_index (array_index_loc, first, second,
5472 				  braced_init_obstack);
5473 		  if (second)
5474 		    pedwarn (ellipsis_loc, OPT_Wpedantic,
5475 			     "ISO C forbids specifying range of elements to initialize");
5476 		}
5477 	      else
5478 		c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5479 					   "expected %<]%>");
5480 	    }
5481 	}
5482       if (des_seen >= 1)
5483 	{
5484 	  if (c_parser_next_token_is (parser, CPP_EQ))
5485 	    {
5486 	      pedwarn_c90 (des_loc, OPT_Wpedantic,
5487 			   "ISO C90 forbids specifying subobject "
5488 			   "to initialize");
5489 	      c_parser_consume_token (parser);
5490 	    }
5491 	  else
5492 	    {
5493 	      if (des_seen == 1)
5494 		pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
5495 			 "obsolete use of designated initializer without %<=%>");
5496 	      else
5497 		{
5498 		  struct c_expr init;
5499 		  init.set_error ();
5500 		  init.original_code = ERROR_MARK;
5501 		  init.original_type = NULL;
5502 		  c_parser_error (parser, "expected %<=%>");
5503 		  c_parser_skip_until_found (parser, CPP_COMMA, NULL);
5504 		  process_init_element (input_location, init, false,
5505 					braced_init_obstack);
5506 		  return;
5507 		}
5508 	    }
5509 	}
5510     }
5511   c_parser_initval (parser, NULL, braced_init_obstack);
5512 }
5513 
5514 /* Parse a nested initializer; as c_parser_initializer but parses
5515    initializers within braced lists, after any designators have been
5516    applied.  If AFTER is not NULL then it is an Objective-C message
5517    expression which is the primary-expression starting the
5518    initializer.  */
5519 
5520 static void
c_parser_initval(c_parser * parser,struct c_expr * after,struct obstack * braced_init_obstack)5521 c_parser_initval (c_parser *parser, struct c_expr *after,
5522 		  struct obstack * braced_init_obstack)
5523 {
5524   struct c_expr init;
5525   gcc_assert (!after || c_dialect_objc ());
5526   location_t loc = c_parser_peek_token (parser)->location;
5527 
5528   if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after)
5529     init = c_parser_braced_init (parser, NULL_TREE, true,
5530 				 braced_init_obstack);
5531   else
5532     {
5533       init = c_parser_expr_no_commas (parser, after);
5534       if (init.value != NULL_TREE
5535 	  && TREE_CODE (init.value) != STRING_CST
5536 	  && TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR)
5537 	init = convert_lvalue_to_rvalue (loc, init, true, true);
5538     }
5539   process_init_element (loc, init, false, braced_init_obstack);
5540 }
5541 
5542 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
5543    C99 6.8.2, C11 6.8.2, C2X 6.8.2).
5544 
5545    compound-statement:
5546      { block-item-list[opt] }
5547      { label-declarations block-item-list }
5548 
5549    block-item-list:
5550      block-item
5551      block-item-list block-item
5552 
5553    block-item:
5554      label
5555      nested-declaration
5556      statement
5557 
5558    nested-declaration:
5559      declaration
5560 
5561    GNU extensions:
5562 
5563    compound-statement:
5564      { label-declarations block-item-list }
5565 
5566    nested-declaration:
5567      __extension__ nested-declaration
5568      nested-function-definition
5569 
5570    label-declarations:
5571      label-declaration
5572      label-declarations label-declaration
5573 
5574    label-declaration:
5575      __label__ identifier-list ;
5576 
5577    Allowing the mixing of declarations and code is new in C99.  The
5578    GNU syntax also permits (not shown above) labels at the end of
5579    compound statements, which yield an error.  We don't allow labels
5580    on declarations; this might seem like a natural extension, but
5581    there would be a conflict between gnu-attributes on the label and
5582    prefix gnu-attributes on the declaration.  ??? The syntax follows the
5583    old parser in requiring something after label declarations.
5584    Although they are erroneous if the labels declared aren't defined,
5585    is it useful for the syntax to be this way?
5586 
5587    OpenACC:
5588 
5589    block-item:
5590      openacc-directive
5591 
5592    openacc-directive:
5593      update-directive
5594 
5595    OpenMP:
5596 
5597    block-item:
5598      openmp-directive
5599 
5600    openmp-directive:
5601      barrier-directive
5602      flush-directive
5603      taskwait-directive
5604      taskyield-directive
5605      cancel-directive
5606      cancellation-point-directive  */
5607 
5608 static tree
c_parser_compound_statement(c_parser * parser,location_t * endlocp)5609 c_parser_compound_statement (c_parser *parser, location_t *endlocp)
5610 {
5611   tree stmt;
5612   location_t brace_loc;
5613   brace_loc = c_parser_peek_token (parser)->location;
5614   if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
5615     {
5616       /* Ensure a scope is entered and left anyway to avoid confusion
5617 	 if we have just prepared to enter a function body.  */
5618       stmt = c_begin_compound_stmt (true);
5619       c_end_compound_stmt (brace_loc, stmt, true);
5620       return error_mark_node;
5621     }
5622   stmt = c_begin_compound_stmt (true);
5623   location_t end_loc = c_parser_compound_statement_nostart (parser);
5624   if (endlocp)
5625     *endlocp = end_loc;
5626 
5627   return c_end_compound_stmt (brace_loc, stmt, true);
5628 }
5629 
5630 /* Parse a compound statement except for the opening brace.  This is
5631    used for parsing both compound statements and statement expressions
5632    (which follow different paths to handling the opening).  */
5633 
5634 static location_t
c_parser_compound_statement_nostart(c_parser * parser)5635 c_parser_compound_statement_nostart (c_parser *parser)
5636 {
5637   bool last_stmt = false;
5638   bool last_label = false;
5639   bool save_valid_for_pragma = valid_location_for_stdc_pragma_p ();
5640   location_t label_loc = UNKNOWN_LOCATION;  /* Quiet warning.  */
5641   if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5642     {
5643       location_t endloc = c_parser_peek_token (parser)->location;
5644       add_debug_begin_stmt (endloc);
5645       c_parser_consume_token (parser);
5646       return endloc;
5647     }
5648   mark_valid_location_for_stdc_pragma (true);
5649   if (c_parser_next_token_is_keyword (parser, RID_LABEL))
5650     {
5651       /* Read zero or more forward-declarations for labels that nested
5652 	 functions can jump to.  */
5653       mark_valid_location_for_stdc_pragma (false);
5654       while (c_parser_next_token_is_keyword (parser, RID_LABEL))
5655 	{
5656 	  label_loc = c_parser_peek_token (parser)->location;
5657 	  c_parser_consume_token (parser);
5658 	  /* Any identifiers, including those declared as type names,
5659 	     are OK here.  */
5660 	  while (true)
5661 	    {
5662 	      tree label;
5663 	      if (c_parser_next_token_is_not (parser, CPP_NAME))
5664 		{
5665 		  c_parser_error (parser, "expected identifier");
5666 		  break;
5667 		}
5668 	      label
5669 		= declare_label (c_parser_peek_token (parser)->value);
5670 	      C_DECLARED_LABEL_FLAG (label) = 1;
5671 	      add_stmt (build_stmt (label_loc, DECL_EXPR, label));
5672 	      c_parser_consume_token (parser);
5673 	      if (c_parser_next_token_is (parser, CPP_COMMA))
5674 		c_parser_consume_token (parser);
5675 	      else
5676 		break;
5677 	    }
5678 	  c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
5679 	}
5680       pedwarn (label_loc, OPT_Wpedantic, "ISO C forbids label declarations");
5681     }
5682   /* We must now have at least one statement, label or declaration.  */
5683   if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5684     {
5685       mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5686       c_parser_error (parser, "expected declaration or statement");
5687       location_t endloc = c_parser_peek_token (parser)->location;
5688       c_parser_consume_token (parser);
5689       return endloc;
5690     }
5691   while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
5692     {
5693       location_t loc = c_parser_peek_token (parser)->location;
5694       loc = expansion_point_location_if_in_system_header (loc);
5695       /* Standard attributes may start a label, statement or declaration.  */
5696       bool have_std_attrs
5697 	= c_parser_nth_token_starts_std_attributes (parser, 1);
5698       tree std_attrs = NULL_TREE;
5699       if (have_std_attrs)
5700 	std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5701       if (c_parser_next_token_is_keyword (parser, RID_CASE)
5702 	  || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
5703 	  || (c_parser_next_token_is (parser, CPP_NAME)
5704 	      && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5705 	{
5706 	  if (c_parser_next_token_is_keyword (parser, RID_CASE))
5707 	    label_loc = c_parser_peek_2nd_token (parser)->location;
5708 	  else
5709 	    label_loc = c_parser_peek_token (parser)->location;
5710 	  last_label = true;
5711 	  last_stmt = false;
5712 	  mark_valid_location_for_stdc_pragma (false);
5713 	  c_parser_label (parser, std_attrs);
5714 	}
5715       else if (c_parser_next_tokens_start_declaration (parser)
5716 	       || (have_std_attrs
5717 		   && c_parser_next_token_is (parser, CPP_SEMICOLON)))
5718 	{
5719 	  if (last_label)
5720 	    pedwarn_c11 (c_parser_peek_token (parser)->location, OPT_Wpedantic,
5721 			 "a label can only be part of a statement and "
5722 			 "a declaration is not a statement");
5723 
5724 	  mark_valid_location_for_stdc_pragma (false);
5725 	  bool fallthru_attr_p = false;
5726 	  c_parser_declaration_or_fndef (parser, true, !have_std_attrs,
5727 					 true, true, true, NULL,
5728 					 NULL, have_std_attrs, std_attrs,
5729 					 NULL, &fallthru_attr_p);
5730 
5731 	  if (last_stmt && !fallthru_attr_p)
5732 	    pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
5733 			 "ISO C90 forbids mixed declarations and code");
5734 	  last_stmt = fallthru_attr_p;
5735 	  last_label = false;
5736 	}
5737       else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
5738 	{
5739 	  /* __extension__ can start a declaration, but is also an
5740 	     unary operator that can start an expression.  Consume all
5741 	     but the last of a possible series of __extension__ to
5742 	     determine which.  If standard attributes have already
5743 	     been seen, it must start a statement, not a declaration,
5744 	     but standard attributes starting a declaration may appear
5745 	     after __extension__.  */
5746 	  while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
5747 		 && (c_parser_peek_2nd_token (parser)->keyword
5748 		     == RID_EXTENSION))
5749 	    c_parser_consume_token (parser);
5750 	  if (!have_std_attrs
5751 	      && (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
5752 		  || c_parser_nth_token_starts_std_attributes (parser, 2)))
5753 	    {
5754 	      int ext;
5755 	      ext = disable_extension_diagnostics ();
5756 	      c_parser_consume_token (parser);
5757 	      last_label = false;
5758 	      mark_valid_location_for_stdc_pragma (false);
5759 	      c_parser_declaration_or_fndef (parser, true, true, true, true,
5760 					     true);
5761 	      /* Following the old parser, __extension__ does not
5762 		 disable this diagnostic.  */
5763 	      restore_extension_diagnostics (ext);
5764 	      if (last_stmt)
5765 		pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
5766 			     "ISO C90 forbids mixed declarations and code");
5767 	      last_stmt = false;
5768 	    }
5769 	  else
5770 	    goto statement;
5771 	}
5772       else if (c_parser_next_token_is (parser, CPP_PRAGMA))
5773 	{
5774 	  if (have_std_attrs)
5775 	    c_parser_error (parser, "expected declaration or statement");
5776 	  /* External pragmas, and some omp pragmas, are not associated
5777 	     with regular c code, and so are not to be considered statements
5778 	     syntactically.  This ensures that the user doesn't put them
5779 	     places that would turn into syntax errors if the directive
5780 	     were ignored.  */
5781 	  if (c_parser_pragma (parser,
5782 			       last_label ? pragma_stmt : pragma_compound,
5783 			       NULL))
5784 	    last_label = false, last_stmt = true;
5785 	}
5786       else if (c_parser_next_token_is (parser, CPP_EOF))
5787 	{
5788 	  mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5789 	  c_parser_error (parser, "expected declaration or statement");
5790 	  return c_parser_peek_token (parser)->location;
5791 	}
5792       else if (c_parser_next_token_is_keyword (parser, RID_ELSE))
5793         {
5794           if (parser->in_if_block)
5795             {
5796 	      mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5797 	      error_at (loc, "expected %<}%> before %<else%>");
5798 	      return c_parser_peek_token (parser)->location;
5799             }
5800           else
5801             {
5802               error_at (loc, "%<else%> without a previous %<if%>");
5803               c_parser_consume_token (parser);
5804               continue;
5805             }
5806         }
5807       else
5808 	{
5809 	statement:
5810 	  c_warn_unused_attributes (std_attrs);
5811 	  last_label = false;
5812 	  last_stmt = true;
5813 	  mark_valid_location_for_stdc_pragma (false);
5814 	  c_parser_statement_after_labels (parser, NULL);
5815 	}
5816 
5817       parser->error = false;
5818     }
5819   if (last_label)
5820     pedwarn_c11 (label_loc, OPT_Wpedantic, "label at end of compound statement");
5821   location_t endloc = c_parser_peek_token (parser)->location;
5822   c_parser_consume_token (parser);
5823   /* Restore the value we started with.  */
5824   mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5825   return endloc;
5826 }
5827 
5828 /* Parse all consecutive labels, possibly preceded by standard
5829    attributes.  In this context, a statement is required, not a
5830    declaration, so attributes must be followed by a statement that is
5831    not just a semicolon.  */
5832 
5833 static void
c_parser_all_labels(c_parser * parser)5834 c_parser_all_labels (c_parser *parser)
5835 {
5836   tree std_attrs = NULL;
5837   if (c_parser_nth_token_starts_std_attributes (parser, 1))
5838     {
5839       std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5840       if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5841 	c_parser_error (parser, "expected statement");
5842     }
5843   while (c_parser_next_token_is_keyword (parser, RID_CASE)
5844 	 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
5845 	 || (c_parser_next_token_is (parser, CPP_NAME)
5846 	     && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5847     {
5848       c_parser_label (parser, std_attrs);
5849       std_attrs = NULL;
5850       if (c_parser_nth_token_starts_std_attributes (parser, 1))
5851 	{
5852 	  std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5853 	  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5854 	    c_parser_error (parser, "expected statement");
5855 	}
5856     }
5857    if (std_attrs)
5858      c_warn_unused_attributes (std_attrs);
5859 }
5860 
5861 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
5862 
5863    label:
5864      identifier : gnu-attributes[opt]
5865      case constant-expression :
5866      default :
5867 
5868    GNU extensions:
5869 
5870    label:
5871      case constant-expression ... constant-expression :
5872 
5873    The use of gnu-attributes on labels is a GNU extension.  The syntax in
5874    GNU C accepts any expressions without commas, non-constant
5875    expressions being rejected later.  Any standard
5876    attribute-specifier-sequence before the first label has been parsed
5877    in the caller, to distinguish statements from declarations.  Any
5878    attribute-specifier-sequence after the label is parsed in this
5879    function.  */
5880 static void
c_parser_label(c_parser * parser,tree std_attrs)5881 c_parser_label (c_parser *parser, tree std_attrs)
5882 {
5883   location_t loc1 = c_parser_peek_token (parser)->location;
5884   tree label = NULL_TREE;
5885 
5886   /* Remember whether this case or a user-defined label is allowed to fall
5887      through to.  */
5888   bool fallthrough_p = c_parser_peek_token (parser)->flags & PREV_FALLTHROUGH;
5889 
5890   if (c_parser_next_token_is_keyword (parser, RID_CASE))
5891     {
5892       tree exp1, exp2;
5893       c_parser_consume_token (parser);
5894       exp1 = c_parser_expr_no_commas (parser, NULL).value;
5895       if (c_parser_next_token_is (parser, CPP_COLON))
5896 	{
5897 	  c_parser_consume_token (parser);
5898 	  label = do_case (loc1, exp1, NULL_TREE);
5899 	}
5900       else if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
5901 	{
5902 	  c_parser_consume_token (parser);
5903 	  exp2 = c_parser_expr_no_commas (parser, NULL).value;
5904 	  if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
5905 	    label = do_case (loc1, exp1, exp2);
5906 	}
5907       else
5908 	c_parser_error (parser, "expected %<:%> or %<...%>");
5909     }
5910   else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
5911     {
5912       c_parser_consume_token (parser);
5913       if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
5914 	label = do_case (loc1, NULL_TREE, NULL_TREE);
5915     }
5916   else
5917     {
5918       tree name = c_parser_peek_token (parser)->value;
5919       tree tlab;
5920       tree attrs;
5921       location_t loc2 = c_parser_peek_token (parser)->location;
5922       gcc_assert (c_parser_next_token_is (parser, CPP_NAME));
5923       c_parser_consume_token (parser);
5924       gcc_assert (c_parser_next_token_is (parser, CPP_COLON));
5925       c_parser_consume_token (parser);
5926       attrs = c_parser_gnu_attributes (parser);
5927       tlab = define_label (loc2, name);
5928       if (tlab)
5929 	{
5930 	  decl_attributes (&tlab, attrs, 0);
5931 	  decl_attributes (&tlab, std_attrs, 0);
5932 	  label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab));
5933 	}
5934       if (attrs
5935 	  && c_parser_next_tokens_start_declaration (parser))
5936 	  warning_at (loc2, OPT_Wattributes, "GNU-style attribute between"
5937 		      " label and declaration appertains to the label");
5938     }
5939   if (label)
5940     {
5941       if (TREE_CODE (label) == LABEL_EXPR)
5942 	FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label)) = fallthrough_p;
5943       else
5944 	FALLTHROUGH_LABEL_P (CASE_LABEL (label)) = fallthrough_p;
5945     }
5946 }
5947 
5948 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
5949 
5950    statement:
5951      labeled-statement
5952      attribute-specifier-sequence[opt] compound-statement
5953      expression-statement
5954      attribute-specifier-sequence[opt] selection-statement
5955      attribute-specifier-sequence[opt] iteration-statement
5956      attribute-specifier-sequence[opt] jump-statement
5957 
5958    labeled-statement:
5959      attribute-specifier-sequence[opt] label statement
5960 
5961    expression-statement:
5962      expression[opt] ;
5963      attribute-specifier-sequence expression ;
5964 
5965    selection-statement:
5966      if-statement
5967      switch-statement
5968 
5969    iteration-statement:
5970      while-statement
5971      do-statement
5972      for-statement
5973 
5974    jump-statement:
5975      goto identifier ;
5976      continue ;
5977      break ;
5978      return expression[opt] ;
5979 
5980    GNU extensions:
5981 
5982    statement:
5983      attribute-specifier-sequence[opt] asm-statement
5984 
5985    jump-statement:
5986      goto * expression ;
5987 
5988    expression-statement:
5989      gnu-attributes ;
5990 
5991    Objective-C:
5992 
5993    statement:
5994      attribute-specifier-sequence[opt] objc-throw-statement
5995      attribute-specifier-sequence[opt] objc-try-catch-statement
5996      attribute-specifier-sequence[opt] objc-synchronized-statement
5997 
5998    objc-throw-statement:
5999      @throw expression ;
6000      @throw ;
6001 
6002    OpenACC:
6003 
6004    statement:
6005      attribute-specifier-sequence[opt] openacc-construct
6006 
6007    openacc-construct:
6008      parallel-construct
6009      kernels-construct
6010      data-construct
6011      loop-construct
6012 
6013    parallel-construct:
6014      parallel-directive structured-block
6015 
6016    kernels-construct:
6017      kernels-directive structured-block
6018 
6019    data-construct:
6020      data-directive structured-block
6021 
6022    loop-construct:
6023      loop-directive structured-block
6024 
6025    OpenMP:
6026 
6027    statement:
6028      attribute-specifier-sequence[opt] openmp-construct
6029 
6030    openmp-construct:
6031      parallel-construct
6032      for-construct
6033      simd-construct
6034      for-simd-construct
6035      sections-construct
6036      single-construct
6037      parallel-for-construct
6038      parallel-for-simd-construct
6039      parallel-sections-construct
6040      master-construct
6041      critical-construct
6042      atomic-construct
6043      ordered-construct
6044 
6045    parallel-construct:
6046      parallel-directive structured-block
6047 
6048    for-construct:
6049      for-directive iteration-statement
6050 
6051    simd-construct:
6052      simd-directive iteration-statements
6053 
6054    for-simd-construct:
6055      for-simd-directive iteration-statements
6056 
6057    sections-construct:
6058      sections-directive section-scope
6059 
6060    single-construct:
6061      single-directive structured-block
6062 
6063    parallel-for-construct:
6064      parallel-for-directive iteration-statement
6065 
6066    parallel-for-simd-construct:
6067      parallel-for-simd-directive iteration-statement
6068 
6069    parallel-sections-construct:
6070      parallel-sections-directive section-scope
6071 
6072    master-construct:
6073      master-directive structured-block
6074 
6075    critical-construct:
6076      critical-directive structured-block
6077 
6078    atomic-construct:
6079      atomic-directive expression-statement
6080 
6081    ordered-construct:
6082      ordered-directive structured-block
6083 
6084    Transactional Memory:
6085 
6086    statement:
6087      attribute-specifier-sequence[opt] transaction-statement
6088      attribute-specifier-sequence[opt] transaction-cancel-statement
6089 
6090    IF_P is used to track whether there's a (possibly labeled) if statement
6091    which is not enclosed in braces and has an else clause.  This is used to
6092    implement -Wparentheses.  */
6093 
6094 static void
c_parser_statement(c_parser * parser,bool * if_p,location_t * loc_after_labels)6095 c_parser_statement (c_parser *parser, bool *if_p, location_t *loc_after_labels)
6096 {
6097   c_parser_all_labels (parser);
6098   if (loc_after_labels)
6099     *loc_after_labels = c_parser_peek_token (parser)->location;
6100   c_parser_statement_after_labels (parser, if_p, NULL);
6101 }
6102 
6103 /* Parse a statement, other than a labeled statement.  CHAIN is a vector
6104    of if-else-if conditions.  All labels and standard attributes have
6105    been parsed in the caller.
6106 
6107    IF_P is used to track whether there's a (possibly labeled) if statement
6108    which is not enclosed in braces and has an else clause.  This is used to
6109    implement -Wparentheses.  */
6110 
6111 static void
c_parser_statement_after_labels(c_parser * parser,bool * if_p,vec<tree> * chain)6112 c_parser_statement_after_labels (c_parser *parser, bool *if_p,
6113 				 vec<tree> *chain)
6114 {
6115   location_t loc = c_parser_peek_token (parser)->location;
6116   tree stmt = NULL_TREE;
6117   bool in_if_block = parser->in_if_block;
6118   parser->in_if_block = false;
6119   if (if_p != NULL)
6120     *if_p = false;
6121 
6122   if (c_parser_peek_token (parser)->type != CPP_OPEN_BRACE)
6123     add_debug_begin_stmt (loc);
6124 
6125  restart:
6126   switch (c_parser_peek_token (parser)->type)
6127     {
6128     case CPP_OPEN_BRACE:
6129       add_stmt (c_parser_compound_statement (parser));
6130       break;
6131     case CPP_KEYWORD:
6132       switch (c_parser_peek_token (parser)->keyword)
6133 	{
6134 	case RID_IF:
6135 	  c_parser_if_statement (parser, if_p, chain);
6136 	  break;
6137 	case RID_SWITCH:
6138 	  c_parser_switch_statement (parser, if_p);
6139 	  break;
6140 	case RID_WHILE:
6141 	  c_parser_while_statement (parser, false, 0, if_p);
6142 	  break;
6143 	case RID_DO:
6144 	  c_parser_do_statement (parser, false, 0);
6145 	  break;
6146 	case RID_FOR:
6147 	  c_parser_for_statement (parser, false, 0, if_p);
6148 	  break;
6149 	case RID_GOTO:
6150 	  c_parser_consume_token (parser);
6151 	  if (c_parser_next_token_is (parser, CPP_NAME))
6152 	    {
6153 	      stmt = c_finish_goto_label (loc,
6154 					  c_parser_peek_token (parser)->value);
6155 	      c_parser_consume_token (parser);
6156 	    }
6157 	  else if (c_parser_next_token_is (parser, CPP_MULT))
6158 	    {
6159 	      struct c_expr val;
6160 
6161 	      c_parser_consume_token (parser);
6162 	      val = c_parser_expression (parser);
6163 	      val = convert_lvalue_to_rvalue (loc, val, false, true);
6164 	      stmt = c_finish_goto_ptr (loc, val);
6165 	    }
6166 	  else
6167 	    c_parser_error (parser, "expected identifier or %<*%>");
6168 	  goto expect_semicolon;
6169 	case RID_CONTINUE:
6170 	  c_parser_consume_token (parser);
6171 	  stmt = c_finish_bc_stmt (loc, objc_foreach_continue_label, false);
6172 	  goto expect_semicolon;
6173 	case RID_BREAK:
6174 	  c_parser_consume_token (parser);
6175 	  stmt = c_finish_bc_stmt (loc, objc_foreach_break_label, true);
6176 	  goto expect_semicolon;
6177 	case RID_RETURN:
6178 	  c_parser_consume_token (parser);
6179 	  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6180 	    {
6181 	      stmt = c_finish_return (loc, NULL_TREE, NULL_TREE);
6182 	      c_parser_consume_token (parser);
6183 	    }
6184 	  else
6185 	    {
6186 	      location_t xloc = c_parser_peek_token (parser)->location;
6187 	      struct c_expr expr = c_parser_expression_conv (parser);
6188 	      mark_exp_read (expr.value);
6189 	      stmt = c_finish_return (EXPR_LOC_OR_LOC (expr.value, xloc),
6190 				      expr.value, expr.original_type);
6191 	      goto expect_semicolon;
6192 	    }
6193 	  break;
6194 	case RID_ASM:
6195 	  stmt = c_parser_asm_statement (parser);
6196 	  break;
6197 	case RID_TRANSACTION_ATOMIC:
6198 	case RID_TRANSACTION_RELAXED:
6199 	  stmt = c_parser_transaction (parser,
6200 	      c_parser_peek_token (parser)->keyword);
6201 	  break;
6202 	case RID_TRANSACTION_CANCEL:
6203 	  stmt = c_parser_transaction_cancel (parser);
6204 	  goto expect_semicolon;
6205 	case RID_AT_THROW:
6206 	  gcc_assert (c_dialect_objc ());
6207 	  c_parser_consume_token (parser);
6208 	  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6209 	    {
6210 	      stmt = objc_build_throw_stmt (loc, NULL_TREE);
6211 	      c_parser_consume_token (parser);
6212 	    }
6213 	  else
6214 	    {
6215 	      struct c_expr expr = c_parser_expression (parser);
6216 	      expr = convert_lvalue_to_rvalue (loc, expr, false, false);
6217 	      expr.value = c_fully_fold (expr.value, false, NULL);
6218 	      stmt = objc_build_throw_stmt (loc, expr.value);
6219 	      goto expect_semicolon;
6220 	    }
6221 	  break;
6222 	case RID_AT_TRY:
6223 	  gcc_assert (c_dialect_objc ());
6224 	  c_parser_objc_try_catch_finally_statement (parser);
6225 	  break;
6226 	case RID_AT_SYNCHRONIZED:
6227 	  gcc_assert (c_dialect_objc ());
6228 	  c_parser_objc_synchronized_statement (parser);
6229 	  break;
6230 	case RID_ATTRIBUTE:
6231 	  {
6232 	    /* Allow '__attribute__((fallthrough));'.  */
6233 	    tree attrs = c_parser_gnu_attributes (parser);
6234 	    if (attribute_fallthrough_p (attrs))
6235 	      {
6236 		if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6237 		  {
6238 		    tree fn = build_call_expr_internal_loc (loc,
6239 							    IFN_FALLTHROUGH,
6240 							    void_type_node, 0);
6241 		    add_stmt (fn);
6242 		    /* Eat the ';'.  */
6243 		    c_parser_consume_token (parser);
6244 		  }
6245 		else
6246 		  warning_at (loc, OPT_Wattributes,
6247 			      "%<fallthrough%> attribute not followed "
6248 			      "by %<;%>");
6249 	      }
6250 	    else if (attrs != NULL_TREE)
6251 	      warning_at (loc, OPT_Wattributes, "only attribute %<fallthrough%>"
6252 			  " can be applied to a null statement");
6253 	    break;
6254 	  }
6255 	default:
6256 	  goto expr_stmt;
6257 	}
6258       break;
6259     case CPP_SEMICOLON:
6260       c_parser_consume_token (parser);
6261       break;
6262     case CPP_CLOSE_PAREN:
6263     case CPP_CLOSE_SQUARE:
6264       /* Avoid infinite loop in error recovery:
6265 	 c_parser_skip_until_found stops at a closing nesting
6266 	 delimiter without consuming it, but here we need to consume
6267 	 it to proceed further.  */
6268       c_parser_error (parser, "expected statement");
6269       c_parser_consume_token (parser);
6270       break;
6271     case CPP_PRAGMA:
6272       if (!c_parser_pragma (parser, pragma_stmt, if_p))
6273         goto restart;
6274       break;
6275     default:
6276     expr_stmt:
6277       stmt = c_finish_expr_stmt (loc, c_parser_expression_conv (parser).value);
6278     expect_semicolon:
6279       c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
6280       break;
6281     }
6282   /* Two cases cannot and do not have line numbers associated: If stmt
6283      is degenerate, such as "2;", then stmt is an INTEGER_CST, which
6284      cannot hold line numbers.  But that's OK because the statement
6285      will either be changed to a MODIFY_EXPR during gimplification of
6286      the statement expr, or discarded.  If stmt was compound, but
6287      without new variables, we will have skipped the creation of a
6288      BIND and will have a bare STATEMENT_LIST.  But that's OK because
6289      (recursively) all of the component statements should already have
6290      line numbers assigned.  ??? Can we discard no-op statements
6291      earlier?  */
6292   if (EXPR_LOCATION (stmt) == UNKNOWN_LOCATION)
6293     protected_set_expr_location (stmt, loc);
6294 
6295   parser->in_if_block = in_if_block;
6296 }
6297 
6298 /* Parse the condition from an if, do, while or for statements.  */
6299 
6300 static tree
c_parser_condition(c_parser * parser)6301 c_parser_condition (c_parser *parser)
6302 {
6303   location_t loc = c_parser_peek_token (parser)->location;
6304   tree cond;
6305   cond = c_parser_expression_conv (parser).value;
6306   cond = c_objc_common_truthvalue_conversion (loc, cond);
6307   cond = c_fully_fold (cond, false, NULL);
6308   if (warn_sequence_point)
6309     verify_sequence_points (cond);
6310   return cond;
6311 }
6312 
6313 /* Parse a parenthesized condition from an if, do or while statement.
6314 
6315    condition:
6316      ( expression )
6317 */
6318 static tree
c_parser_paren_condition(c_parser * parser)6319 c_parser_paren_condition (c_parser *parser)
6320 {
6321   tree cond;
6322   matching_parens parens;
6323   if (!parens.require_open (parser))
6324     return error_mark_node;
6325   cond = c_parser_condition (parser);
6326   parens.skip_until_found_close (parser);
6327   return cond;
6328 }
6329 
6330 /* Parse a statement which is a block in C99.
6331 
6332    IF_P is used to track whether there's a (possibly labeled) if statement
6333    which is not enclosed in braces and has an else clause.  This is used to
6334    implement -Wparentheses.  */
6335 
6336 static tree
c_parser_c99_block_statement(c_parser * parser,bool * if_p,location_t * loc_after_labels)6337 c_parser_c99_block_statement (c_parser *parser, bool *if_p,
6338 			      location_t *loc_after_labels)
6339 {
6340   tree block = c_begin_compound_stmt (flag_isoc99);
6341   location_t loc = c_parser_peek_token (parser)->location;
6342   c_parser_statement (parser, if_p, loc_after_labels);
6343   return c_end_compound_stmt (loc, block, flag_isoc99);
6344 }
6345 
6346 /* Parse the body of an if statement.  This is just parsing a
6347    statement but (a) it is a block in C99, (b) we track whether the
6348    body is an if statement for the sake of -Wparentheses warnings, (c)
6349    we handle an empty body specially for the sake of -Wempty-body
6350    warnings, and (d) we call parser_compound_statement directly
6351    because c_parser_statement_after_labels resets
6352    parser->in_if_block.
6353 
6354    IF_P is used to track whether there's a (possibly labeled) if statement
6355    which is not enclosed in braces and has an else clause.  This is used to
6356    implement -Wparentheses.  */
6357 
6358 static tree
c_parser_if_body(c_parser * parser,bool * if_p,const token_indent_info & if_tinfo)6359 c_parser_if_body (c_parser *parser, bool *if_p,
6360 		  const token_indent_info &if_tinfo)
6361 {
6362   tree block = c_begin_compound_stmt (flag_isoc99);
6363   location_t body_loc = c_parser_peek_token (parser)->location;
6364   location_t body_loc_after_labels = UNKNOWN_LOCATION;
6365   token_indent_info body_tinfo
6366     = get_token_indent_info (c_parser_peek_token (parser));
6367 
6368   c_parser_all_labels (parser);
6369   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6370     {
6371       location_t loc = c_parser_peek_token (parser)->location;
6372       add_stmt (build_empty_stmt (loc));
6373       c_parser_consume_token (parser);
6374       if (!c_parser_next_token_is_keyword (parser, RID_ELSE))
6375 	warning_at (loc, OPT_Wempty_body,
6376 		    "suggest braces around empty body in an %<if%> statement");
6377     }
6378   else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6379     add_stmt (c_parser_compound_statement (parser));
6380   else
6381     {
6382       body_loc_after_labels = c_parser_peek_token (parser)->location;
6383       c_parser_statement_after_labels (parser, if_p);
6384     }
6385 
6386   token_indent_info next_tinfo
6387     = get_token_indent_info (c_parser_peek_token (parser));
6388   warn_for_misleading_indentation (if_tinfo, body_tinfo, next_tinfo);
6389   if (body_loc_after_labels != UNKNOWN_LOCATION
6390       && next_tinfo.type != CPP_SEMICOLON)
6391     warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
6392 				    if_tinfo.location, RID_IF);
6393 
6394   return c_end_compound_stmt (body_loc, block, flag_isoc99);
6395 }
6396 
6397 /* Parse the else body of an if statement.  This is just parsing a
6398    statement but (a) it is a block in C99, (b) we handle an empty body
6399    specially for the sake of -Wempty-body warnings.  CHAIN is a vector
6400    of if-else-if conditions.  */
6401 
6402 static tree
c_parser_else_body(c_parser * parser,const token_indent_info & else_tinfo,vec<tree> * chain)6403 c_parser_else_body (c_parser *parser, const token_indent_info &else_tinfo,
6404 		    vec<tree> *chain)
6405 {
6406   location_t body_loc = c_parser_peek_token (parser)->location;
6407   tree block = c_begin_compound_stmt (flag_isoc99);
6408   token_indent_info body_tinfo
6409     = get_token_indent_info (c_parser_peek_token (parser));
6410   location_t body_loc_after_labels = UNKNOWN_LOCATION;
6411 
6412   c_parser_all_labels (parser);
6413   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6414     {
6415       location_t loc = c_parser_peek_token (parser)->location;
6416       warning_at (loc,
6417 		  OPT_Wempty_body,
6418 	         "suggest braces around empty body in an %<else%> statement");
6419       add_stmt (build_empty_stmt (loc));
6420       c_parser_consume_token (parser);
6421     }
6422   else
6423     {
6424       if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6425 	body_loc_after_labels = c_parser_peek_token (parser)->location;
6426       c_parser_statement_after_labels (parser, NULL, chain);
6427     }
6428 
6429   token_indent_info next_tinfo
6430     = get_token_indent_info (c_parser_peek_token (parser));
6431   warn_for_misleading_indentation (else_tinfo, body_tinfo, next_tinfo);
6432   if (body_loc_after_labels != UNKNOWN_LOCATION
6433       && next_tinfo.type != CPP_SEMICOLON)
6434     warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
6435 				    else_tinfo.location, RID_ELSE);
6436 
6437   return c_end_compound_stmt (body_loc, block, flag_isoc99);
6438 }
6439 
6440 /* We might need to reclassify any previously-lexed identifier, e.g.
6441    when we've left a for loop with an if-statement without else in the
6442    body - we might have used a wrong scope for the token.  See PR67784.  */
6443 
6444 static void
c_parser_maybe_reclassify_token(c_parser * parser)6445 c_parser_maybe_reclassify_token (c_parser *parser)
6446 {
6447   if (c_parser_next_token_is (parser, CPP_NAME))
6448     {
6449       c_token *token = c_parser_peek_token (parser);
6450 
6451       if (token->id_kind != C_ID_CLASSNAME)
6452 	{
6453 	  tree decl = lookup_name (token->value);
6454 
6455 	  token->id_kind = C_ID_ID;
6456 	  if (decl)
6457 	    {
6458 	      if (TREE_CODE (decl) == TYPE_DECL)
6459 		token->id_kind = C_ID_TYPENAME;
6460 	    }
6461 	  else if (c_dialect_objc ())
6462 	    {
6463 	      tree objc_interface_decl = objc_is_class_name (token->value);
6464 	      /* Objective-C class names are in the same namespace as
6465 		 variables and typedefs, and hence are shadowed by local
6466 		 declarations.  */
6467 	      if (objc_interface_decl)
6468 		{
6469 		  token->value = objc_interface_decl;
6470 		  token->id_kind = C_ID_CLASSNAME;
6471 		}
6472 	    }
6473 	}
6474     }
6475 }
6476 
6477 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6478 
6479    if-statement:
6480      if ( expression ) statement
6481      if ( expression ) statement else statement
6482 
6483    CHAIN is a vector of if-else-if conditions.
6484    IF_P is used to track whether there's a (possibly labeled) if statement
6485    which is not enclosed in braces and has an else clause.  This is used to
6486    implement -Wparentheses.  */
6487 
6488 static void
c_parser_if_statement(c_parser * parser,bool * if_p,vec<tree> * chain)6489 c_parser_if_statement (c_parser *parser, bool *if_p, vec<tree> *chain)
6490 {
6491   tree block;
6492   location_t loc;
6493   tree cond;
6494   bool nested_if = false;
6495   tree first_body, second_body;
6496   bool in_if_block;
6497 
6498   gcc_assert (c_parser_next_token_is_keyword (parser, RID_IF));
6499   token_indent_info if_tinfo
6500     = get_token_indent_info (c_parser_peek_token (parser));
6501   c_parser_consume_token (parser);
6502   block = c_begin_compound_stmt (flag_isoc99);
6503   loc = c_parser_peek_token (parser)->location;
6504   cond = c_parser_paren_condition (parser);
6505   in_if_block = parser->in_if_block;
6506   parser->in_if_block = true;
6507   first_body = c_parser_if_body (parser, &nested_if, if_tinfo);
6508   parser->in_if_block = in_if_block;
6509 
6510   if (warn_duplicated_cond)
6511     warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond), cond, &chain);
6512 
6513   if (c_parser_next_token_is_keyword (parser, RID_ELSE))
6514     {
6515       token_indent_info else_tinfo
6516 	= get_token_indent_info (c_parser_peek_token (parser));
6517       c_parser_consume_token (parser);
6518       if (warn_duplicated_cond)
6519 	{
6520 	  if (c_parser_next_token_is_keyword (parser, RID_IF)
6521 	      && chain == NULL)
6522 	    {
6523 	      /* We've got "if (COND) else if (COND2)".  Start the
6524 		 condition chain and add COND as the first element.  */
6525 	      chain = new vec<tree> ();
6526 	      if (!CONSTANT_CLASS_P (cond) && !TREE_SIDE_EFFECTS (cond))
6527 		chain->safe_push (cond);
6528 	    }
6529 	  else if (!c_parser_next_token_is_keyword (parser, RID_IF))
6530 	    /* This is if-else without subsequent if.  Zap the condition
6531 	       chain; we would have already warned at this point.  */
6532 	    vec_free (chain);
6533 	}
6534       second_body = c_parser_else_body (parser, else_tinfo, chain);
6535       /* Set IF_P to true to indicate that this if statement has an
6536 	 else clause.  This may trigger the Wparentheses warning
6537 	 below when we get back up to the parent if statement.  */
6538       if (if_p != NULL)
6539 	*if_p = true;
6540     }
6541   else
6542     {
6543       second_body = NULL_TREE;
6544 
6545       /* Diagnose an ambiguous else if if-then-else is nested inside
6546 	 if-then.  */
6547       if (nested_if)
6548 	warning_at (loc, OPT_Wdangling_else,
6549 		    "suggest explicit braces to avoid ambiguous %<else%>");
6550 
6551       if (warn_duplicated_cond)
6552 	/* This if statement does not have an else clause.  We don't
6553 	   need the condition chain anymore.  */
6554 	vec_free (chain);
6555     }
6556   c_finish_if_stmt (loc, cond, first_body, second_body);
6557   add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6558 
6559   c_parser_maybe_reclassify_token (parser);
6560 }
6561 
6562 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6563 
6564    switch-statement:
6565      switch (expression) statement
6566 */
6567 
6568 static void
c_parser_switch_statement(c_parser * parser,bool * if_p)6569 c_parser_switch_statement (c_parser *parser, bool *if_p)
6570 {
6571   struct c_expr ce;
6572   tree block, expr, body;
6573   unsigned char save_in_statement;
6574   location_t switch_loc = c_parser_peek_token (parser)->location;
6575   location_t switch_cond_loc;
6576   gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH));
6577   c_parser_consume_token (parser);
6578   block = c_begin_compound_stmt (flag_isoc99);
6579   bool explicit_cast_p = false;
6580   matching_parens parens;
6581   if (parens.require_open (parser))
6582     {
6583       switch_cond_loc = c_parser_peek_token (parser)->location;
6584       if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
6585 	  && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
6586 	explicit_cast_p = true;
6587       ce = c_parser_expression (parser);
6588       ce = convert_lvalue_to_rvalue (switch_cond_loc, ce, true, true);
6589       expr = ce.value;
6590       /* ??? expr has no valid location?  */
6591       parens.skip_until_found_close (parser);
6592     }
6593   else
6594     {
6595       switch_cond_loc = UNKNOWN_LOCATION;
6596       expr = error_mark_node;
6597       ce.original_type = error_mark_node;
6598     }
6599   c_start_switch (switch_loc, switch_cond_loc, expr, explicit_cast_p);
6600   save_in_statement = in_statement;
6601   in_statement |= IN_SWITCH_STMT;
6602   location_t loc_after_labels;
6603   bool open_brace_p = c_parser_peek_token (parser)->type == CPP_OPEN_BRACE;
6604   body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6605   location_t next_loc = c_parser_peek_token (parser)->location;
6606   if (!open_brace_p && c_parser_peek_token (parser)->type != CPP_SEMICOLON)
6607     warn_for_multistatement_macros (loc_after_labels, next_loc, switch_loc,
6608 				    RID_SWITCH);
6609   c_finish_switch (body, ce.original_type);
6610   in_statement = save_in_statement;
6611   add_stmt (c_end_compound_stmt (switch_loc, block, flag_isoc99));
6612   c_parser_maybe_reclassify_token (parser);
6613 }
6614 
6615 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6616 
6617    while-statement:
6618       while (expression) statement
6619 
6620    IF_P is used to track whether there's a (possibly labeled) if statement
6621    which is not enclosed in braces and has an else clause.  This is used to
6622    implement -Wparentheses.  */
6623 
6624 static void
c_parser_while_statement(c_parser * parser,bool ivdep,unsigned short unroll,bool * if_p)6625 c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6626 			  bool *if_p)
6627 {
6628   tree block, cond, body;
6629   unsigned char save_in_statement;
6630   location_t loc;
6631   gcc_assert (c_parser_next_token_is_keyword (parser, RID_WHILE));
6632   token_indent_info while_tinfo
6633     = get_token_indent_info (c_parser_peek_token (parser));
6634   c_parser_consume_token (parser);
6635   block = c_begin_compound_stmt (flag_isoc99);
6636   loc = c_parser_peek_token (parser)->location;
6637   cond = c_parser_paren_condition (parser);
6638   if (ivdep && cond != error_mark_node)
6639     cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6640 		   build_int_cst (integer_type_node,
6641 				  annot_expr_ivdep_kind),
6642 		   integer_zero_node);
6643   if (unroll && cond != error_mark_node)
6644     cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6645 		   build_int_cst (integer_type_node,
6646 				  annot_expr_unroll_kind),
6647 		   build_int_cst (integer_type_node, unroll));
6648   save_in_statement = in_statement;
6649   in_statement = IN_ITERATION_STMT;
6650 
6651   token_indent_info body_tinfo
6652     = get_token_indent_info (c_parser_peek_token (parser));
6653 
6654   location_t loc_after_labels;
6655   bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
6656   body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6657   add_stmt (build_stmt (loc, WHILE_STMT, cond, body));
6658   add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6659   c_parser_maybe_reclassify_token (parser);
6660 
6661   token_indent_info next_tinfo
6662     = get_token_indent_info (c_parser_peek_token (parser));
6663   warn_for_misleading_indentation (while_tinfo, body_tinfo, next_tinfo);
6664 
6665   if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
6666     warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
6667 				    while_tinfo.location, RID_WHILE);
6668 
6669   in_statement = save_in_statement;
6670 }
6671 
6672 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6673 
6674    do-statement:
6675      do statement while ( expression ) ;
6676 */
6677 
6678 static void
c_parser_do_statement(c_parser * parser,bool ivdep,unsigned short unroll)6679 c_parser_do_statement (c_parser *parser, bool ivdep, unsigned short unroll)
6680 {
6681   tree block, cond, body;
6682   unsigned char save_in_statement;
6683   location_t loc;
6684   gcc_assert (c_parser_next_token_is_keyword (parser, RID_DO));
6685   c_parser_consume_token (parser);
6686   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6687     warning_at (c_parser_peek_token (parser)->location,
6688 		OPT_Wempty_body,
6689 		"suggest braces around empty body in %<do%> statement");
6690   block = c_begin_compound_stmt (flag_isoc99);
6691   loc = c_parser_peek_token (parser)->location;
6692   save_in_statement = in_statement;
6693   in_statement = IN_ITERATION_STMT;
6694   body = c_parser_c99_block_statement (parser, NULL);
6695   c_parser_require_keyword (parser, RID_WHILE, "expected %<while%>");
6696   in_statement = save_in_statement;
6697   cond = c_parser_paren_condition (parser);
6698   if (ivdep && cond != error_mark_node)
6699     cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6700 		   build_int_cst (integer_type_node,
6701 				  annot_expr_ivdep_kind),
6702 		   integer_zero_node);
6703   if (unroll && cond != error_mark_node)
6704     cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6705 		   build_int_cst (integer_type_node,
6706 				  annot_expr_unroll_kind),
6707  		   build_int_cst (integer_type_node, unroll));
6708   if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
6709     c_parser_skip_to_end_of_block_or_statement (parser);
6710 
6711   add_stmt (build_stmt (loc, DO_STMT, cond, body));
6712   add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6713 }
6714 
6715 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6716 
6717    for-statement:
6718      for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
6719      for ( nested-declaration expression[opt] ; expression[opt] ) statement
6720 
6721    The form with a declaration is new in C99.
6722 
6723    ??? In accordance with the old parser, the declaration may be a
6724    nested function, which is then rejected in check_for_loop_decls,
6725    but does it make any sense for this to be included in the grammar?
6726    Note in particular that the nested function does not include a
6727    trailing ';', whereas the "declaration" production includes one.
6728    Also, can we reject bad declarations earlier and cheaper than
6729    check_for_loop_decls?
6730 
6731    In Objective-C, there are two additional variants:
6732 
6733    foreach-statement:
6734      for ( expression in expresssion ) statement
6735      for ( declaration in expression ) statement
6736 
6737    This is inconsistent with C, because the second variant is allowed
6738    even if c99 is not enabled.
6739 
6740    The rest of the comment documents these Objective-C foreach-statement.
6741 
6742    Here is the canonical example of the first variant:
6743     for (object in array)    { do something with object }
6744    we call the first expression ("object") the "object_expression" and
6745    the second expression ("array") the "collection_expression".
6746    object_expression must be an lvalue of type "id" (a generic Objective-C
6747    object) because the loop works by assigning to object_expression the
6748    various objects from the collection_expression.  collection_expression
6749    must evaluate to something of type "id" which responds to the method
6750    countByEnumeratingWithState:objects:count:.
6751 
6752    The canonical example of the second variant is:
6753     for (id object in array)    { do something with object }
6754    which is completely equivalent to
6755     {
6756       id object;
6757       for (object in array) { do something with object }
6758     }
6759    Note that initizializing 'object' in some way (eg, "for ((object =
6760    xxx) in array) { do something with object }") is possibly
6761    technically valid, but completely pointless as 'object' will be
6762    assigned to something else as soon as the loop starts.  We should
6763    most likely reject it (TODO).
6764 
6765    The beginning of the Objective-C foreach-statement looks exactly
6766    like the beginning of the for-statement, and we can tell it is a
6767    foreach-statement only because the initial declaration or
6768    expression is terminated by 'in' instead of ';'.
6769 
6770    IF_P is used to track whether there's a (possibly labeled) if statement
6771    which is not enclosed in braces and has an else clause.  This is used to
6772    implement -Wparentheses.  */
6773 
6774 static void
c_parser_for_statement(c_parser * parser,bool ivdep,unsigned short unroll,bool * if_p)6775 c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6776 			bool *if_p)
6777 {
6778   tree block, cond, incr, body;
6779   unsigned char save_in_statement;
6780   tree save_objc_foreach_break_label, save_objc_foreach_continue_label;
6781   /* The following are only used when parsing an ObjC foreach statement.  */
6782   tree object_expression;
6783   /* Silence the bogus uninitialized warning.  */
6784   tree collection_expression = NULL;
6785   location_t loc = c_parser_peek_token (parser)->location;
6786   location_t for_loc = loc;
6787   bool is_foreach_statement = false;
6788   gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
6789   token_indent_info for_tinfo
6790     = get_token_indent_info (c_parser_peek_token (parser));
6791   c_parser_consume_token (parser);
6792   /* Open a compound statement in Objective-C as well, just in case this is
6793      as foreach expression.  */
6794   block = c_begin_compound_stmt (flag_isoc99 || c_dialect_objc ());
6795   cond = error_mark_node;
6796   incr = error_mark_node;
6797   matching_parens parens;
6798   if (parens.require_open (parser))
6799     {
6800       /* Parse the initialization declaration or expression.  */
6801       object_expression = error_mark_node;
6802       parser->objc_could_be_foreach_context = c_dialect_objc ();
6803       if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6804 	{
6805 	  parser->objc_could_be_foreach_context = false;
6806 	  c_parser_consume_token (parser);
6807 	  c_finish_expr_stmt (loc, NULL_TREE);
6808 	}
6809       else if (c_parser_next_tokens_start_declaration (parser)
6810 	       || c_parser_nth_token_starts_std_attributes (parser, 1))
6811 	{
6812 	  c_parser_declaration_or_fndef (parser, true, true, true, true, true,
6813 					 &object_expression);
6814 	  parser->objc_could_be_foreach_context = false;
6815 
6816 	  if (c_parser_next_token_is_keyword (parser, RID_IN))
6817 	    {
6818 	      c_parser_consume_token (parser);
6819 	      is_foreach_statement = true;
6820 	      if (check_for_loop_decls (for_loc, true) == NULL_TREE)
6821 		c_parser_error (parser, "multiple iterating variables in "
6822 					"fast enumeration");
6823 	    }
6824 	  else
6825 	    check_for_loop_decls (for_loc, flag_isoc99);
6826 	}
6827       else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
6828 	{
6829 	  /* __extension__ can start a declaration, but is also an
6830 	     unary operator that can start an expression.  Consume all
6831 	     but the last of a possible series of __extension__ to
6832 	     determine which.  */
6833 	  while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
6834 		 && (c_parser_peek_2nd_token (parser)->keyword
6835 		     == RID_EXTENSION))
6836 	    c_parser_consume_token (parser);
6837 	  if (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
6838 	      || c_parser_nth_token_starts_std_attributes (parser, 2))
6839 	    {
6840 	      int ext;
6841 	      ext = disable_extension_diagnostics ();
6842 	      c_parser_consume_token (parser);
6843 	      c_parser_declaration_or_fndef (parser, true, true, true, true,
6844 					     true, &object_expression);
6845 	      parser->objc_could_be_foreach_context = false;
6846 
6847 	      restore_extension_diagnostics (ext);
6848 	      if (c_parser_next_token_is_keyword (parser, RID_IN))
6849 		{
6850 		  c_parser_consume_token (parser);
6851 		  is_foreach_statement = true;
6852 		  if (check_for_loop_decls (for_loc, true) == NULL_TREE)
6853 		    c_parser_error (parser, "multiple iterating variables in "
6854 					    "fast enumeration");
6855 		}
6856 	      else
6857 		check_for_loop_decls (for_loc, flag_isoc99);
6858 	    }
6859 	  else
6860 	    goto init_expr;
6861 	}
6862       else
6863 	{
6864 	init_expr:
6865 	  {
6866 	    struct c_expr ce;
6867 	    tree init_expression;
6868 	    ce = c_parser_expression (parser);
6869 	    init_expression = ce.value;
6870 	    parser->objc_could_be_foreach_context = false;
6871 	    if (c_parser_next_token_is_keyword (parser, RID_IN))
6872 	      {
6873 		c_parser_consume_token (parser);
6874 		is_foreach_statement = true;
6875 		if (! lvalue_p (init_expression))
6876 		  c_parser_error (parser, "invalid iterating variable in "
6877 					  "fast enumeration");
6878 		object_expression
6879 		  = c_fully_fold (init_expression, false, NULL);
6880 	      }
6881 	    else
6882 	      {
6883 		ce = convert_lvalue_to_rvalue (loc, ce, true, false);
6884 		init_expression = ce.value;
6885 		c_finish_expr_stmt (loc, init_expression);
6886 		c_parser_skip_until_found (parser, CPP_SEMICOLON,
6887 					   "expected %<;%>");
6888 	      }
6889 	  }
6890 	}
6891       /* Parse the loop condition.  In the case of a foreach
6892 	 statement, there is no loop condition.  */
6893       gcc_assert (!parser->objc_could_be_foreach_context);
6894       if (!is_foreach_statement)
6895 	{
6896 	  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6897 	    {
6898 	      if (ivdep)
6899 		{
6900 		  c_parser_error (parser, "missing loop condition in loop "
6901 					  "with %<GCC ivdep%> pragma");
6902 		  cond = error_mark_node;
6903 		}
6904 	      else if (unroll)
6905 		{
6906 		  c_parser_error (parser, "missing loop condition in loop "
6907 					  "with %<GCC unroll%> pragma");
6908 		  cond = error_mark_node;
6909 		}
6910 	      else
6911 		{
6912 		  c_parser_consume_token (parser);
6913 		  cond = NULL_TREE;
6914 		}
6915 	    }
6916 	  else
6917 	    {
6918 	      cond = c_parser_condition (parser);
6919 	      c_parser_skip_until_found (parser, CPP_SEMICOLON,
6920 					 "expected %<;%>");
6921 	    }
6922 	  if (ivdep && cond != error_mark_node)
6923 	    cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6924 			   build_int_cst (integer_type_node,
6925 					  annot_expr_ivdep_kind),
6926 			   integer_zero_node);
6927 	  if (unroll && cond != error_mark_node)
6928 	    cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6929  			   build_int_cst (integer_type_node,
6930 					  annot_expr_unroll_kind),
6931 			   build_int_cst (integer_type_node, unroll));
6932 	}
6933       /* Parse the increment expression (the third expression in a
6934 	 for-statement).  In the case of a foreach-statement, this is
6935 	 the expression that follows the 'in'.  */
6936       loc = c_parser_peek_token (parser)->location;
6937       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
6938 	{
6939 	  if (is_foreach_statement)
6940 	    {
6941 	      c_parser_error (parser,
6942 			      "missing collection in fast enumeration");
6943 	      collection_expression = error_mark_node;
6944 	    }
6945 	  else
6946 	    incr = c_process_expr_stmt (loc, NULL_TREE);
6947 	}
6948       else
6949 	{
6950 	  if (is_foreach_statement)
6951 	    collection_expression
6952 	      = c_fully_fold (c_parser_expression (parser).value, false, NULL);
6953 	  else
6954 	    {
6955 	      struct c_expr ce = c_parser_expression (parser);
6956 	      ce = convert_lvalue_to_rvalue (loc, ce, true, false);
6957 	      incr = c_process_expr_stmt (loc, ce.value);
6958 	    }
6959 	}
6960       parens.skip_until_found_close (parser);
6961     }
6962   save_in_statement = in_statement;
6963   if (is_foreach_statement)
6964     {
6965       in_statement = IN_OBJC_FOREACH;
6966       save_objc_foreach_break_label = objc_foreach_break_label;
6967       save_objc_foreach_continue_label = objc_foreach_continue_label;
6968       objc_foreach_break_label = create_artificial_label (loc);
6969       objc_foreach_continue_label = create_artificial_label (loc);
6970     }
6971   else
6972     in_statement = IN_ITERATION_STMT;
6973 
6974   token_indent_info body_tinfo
6975     = get_token_indent_info (c_parser_peek_token (parser));
6976 
6977   location_t loc_after_labels;
6978   bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
6979   body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6980 
6981   if (is_foreach_statement)
6982     objc_finish_foreach_loop (for_loc, object_expression,
6983 			      collection_expression, body,
6984 			      objc_foreach_break_label,
6985 			      objc_foreach_continue_label);
6986   else
6987     add_stmt (build_stmt (for_loc, FOR_STMT, NULL_TREE, cond, incr,
6988 			  body, NULL_TREE));
6989   add_stmt (c_end_compound_stmt (for_loc, block,
6990 				 flag_isoc99 || c_dialect_objc ()));
6991   c_parser_maybe_reclassify_token (parser);
6992 
6993   token_indent_info next_tinfo
6994     = get_token_indent_info (c_parser_peek_token (parser));
6995   warn_for_misleading_indentation (for_tinfo, body_tinfo, next_tinfo);
6996 
6997   if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
6998     warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
6999 				    for_tinfo.location, RID_FOR);
7000 
7001   in_statement = save_in_statement;
7002   if (is_foreach_statement)
7003     {
7004       objc_foreach_break_label = save_objc_foreach_break_label;
7005       objc_foreach_continue_label = save_objc_foreach_continue_label;
7006     }
7007 }
7008 
7009 /* Parse an asm statement, a GNU extension.  This is a full-blown asm
7010    statement with inputs, outputs, clobbers, and volatile, inline, and goto
7011    tags allowed.
7012 
7013    asm-qualifier:
7014      volatile
7015      inline
7016      goto
7017 
7018    asm-qualifier-list:
7019      asm-qualifier-list asm-qualifier
7020      asm-qualifier
7021 
7022    asm-statement:
7023      asm asm-qualifier-list[opt] ( asm-argument ) ;
7024 
7025    asm-argument:
7026      asm-string-literal
7027      asm-string-literal : asm-operands[opt]
7028      asm-string-literal : asm-operands[opt] : asm-operands[opt]
7029      asm-string-literal : asm-operands[opt] : asm-operands[opt] \
7030        : asm-clobbers[opt]
7031      asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
7032        : asm-goto-operands
7033 
7034    The form with asm-goto-operands is valid if and only if the
7035    asm-qualifier-list contains goto, and is the only allowed form in that case.
7036    Duplicate asm-qualifiers are not allowed.
7037 
7038    The :: token is considered equivalent to two consecutive : tokens.  */
7039 
7040 static tree
c_parser_asm_statement(c_parser * parser)7041 c_parser_asm_statement (c_parser *parser)
7042 {
7043   tree str, outputs, inputs, clobbers, labels, ret;
7044   bool simple;
7045   location_t asm_loc = c_parser_peek_token (parser)->location;
7046   int section, nsections;
7047 
7048   gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
7049   c_parser_consume_token (parser);
7050 
7051   /* Handle the asm-qualifier-list.  */
7052   location_t volatile_loc = UNKNOWN_LOCATION;
7053   location_t inline_loc = UNKNOWN_LOCATION;
7054   location_t goto_loc = UNKNOWN_LOCATION;
7055   for (;;)
7056     {
7057       c_token *token = c_parser_peek_token (parser);
7058       location_t loc = token->location;
7059       switch (token->keyword)
7060 	{
7061 	case RID_VOLATILE:
7062 	  if (volatile_loc)
7063 	    {
7064 	      error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7065 	      inform (volatile_loc, "first seen here");
7066 	    }
7067 	  else
7068 	    volatile_loc = loc;
7069 	  c_parser_consume_token (parser);
7070 	  continue;
7071 
7072 	case RID_INLINE:
7073 	  if (inline_loc)
7074 	    {
7075 	      error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7076 	      inform (inline_loc, "first seen here");
7077 	    }
7078 	  else
7079 	    inline_loc = loc;
7080 	  c_parser_consume_token (parser);
7081 	  continue;
7082 
7083 	case RID_GOTO:
7084 	  if (goto_loc)
7085 	    {
7086 	      error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7087 	      inform (goto_loc, "first seen here");
7088 	    }
7089 	  else
7090 	    goto_loc = loc;
7091 	  c_parser_consume_token (parser);
7092 	  continue;
7093 
7094 	case RID_CONST:
7095 	case RID_RESTRICT:
7096 	  error_at (loc, "%qE is not a valid %<asm%> qualifier", token->value);
7097 	  c_parser_consume_token (parser);
7098 	  continue;
7099 
7100 	default:
7101 	  break;
7102 	}
7103       break;
7104     }
7105 
7106   bool is_volatile = (volatile_loc != UNKNOWN_LOCATION);
7107   bool is_inline = (inline_loc != UNKNOWN_LOCATION);
7108   bool is_goto = (goto_loc != UNKNOWN_LOCATION);
7109 
7110   ret = NULL;
7111 
7112   matching_parens parens;
7113   if (!parens.require_open (parser))
7114     goto error;
7115 
7116   str = c_parser_asm_string_literal (parser);
7117   if (str == NULL_TREE)
7118     goto error_close_paren;
7119 
7120   simple = true;
7121   outputs = NULL_TREE;
7122   inputs = NULL_TREE;
7123   clobbers = NULL_TREE;
7124   labels = NULL_TREE;
7125 
7126   if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
7127     goto done_asm;
7128 
7129   /* Parse each colon-delimited section of operands.  */
7130   nsections = 3 + is_goto;
7131   for (section = 0; section < nsections; ++section)
7132     {
7133       if (c_parser_next_token_is (parser, CPP_SCOPE))
7134 	{
7135 	  ++section;
7136 	  if (section == nsections)
7137 	    {
7138 	      c_parser_error (parser, "expected %<)%>");
7139 	      goto error_close_paren;
7140 	    }
7141 	  c_parser_consume_token (parser);
7142 	}
7143       else if (!c_parser_require (parser, CPP_COLON,
7144 				  is_goto
7145 				  ? G_("expected %<:%>")
7146 				  : G_("expected %<:%> or %<)%>"),
7147 				  UNKNOWN_LOCATION, is_goto))
7148 	goto error_close_paren;
7149 
7150       /* Once past any colon, we're no longer a simple asm.  */
7151       simple = false;
7152 
7153       if ((!c_parser_next_token_is (parser, CPP_COLON)
7154 	   && !c_parser_next_token_is (parser, CPP_SCOPE)
7155 	   && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
7156 	  || section == 3)
7157 	switch (section)
7158 	  {
7159 	  case 0:
7160 	    outputs = c_parser_asm_operands (parser);
7161 	    break;
7162 	  case 1:
7163 	    inputs = c_parser_asm_operands (parser);
7164 	    break;
7165 	  case 2:
7166 	    clobbers = c_parser_asm_clobbers (parser);
7167 	    break;
7168 	  case 3:
7169 	    labels = c_parser_asm_goto_operands (parser);
7170 	    break;
7171 	  default:
7172 	    gcc_unreachable ();
7173 	  }
7174 
7175       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
7176 	goto done_asm;
7177     }
7178 
7179  done_asm:
7180   if (!parens.require_close (parser))
7181     {
7182       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7183       goto error;
7184     }
7185 
7186   if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
7187     c_parser_skip_to_end_of_block_or_statement (parser);
7188 
7189   ret = build_asm_stmt (is_volatile,
7190 			build_asm_expr (asm_loc, str, outputs, inputs,
7191 					clobbers, labels, simple, is_inline));
7192 
7193  error:
7194   return ret;
7195 
7196  error_close_paren:
7197   c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7198   goto error;
7199 }
7200 
7201 /* Parse asm operands, a GNU extension.
7202 
7203    asm-operands:
7204      asm-operand
7205      asm-operands , asm-operand
7206 
7207    asm-operand:
7208      asm-string-literal ( expression )
7209      [ identifier ] asm-string-literal ( expression )
7210 */
7211 
7212 static tree
c_parser_asm_operands(c_parser * parser)7213 c_parser_asm_operands (c_parser *parser)
7214 {
7215   tree list = NULL_TREE;
7216   while (true)
7217     {
7218       tree name, str;
7219       struct c_expr expr;
7220       if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
7221 	{
7222 	  c_parser_consume_token (parser);
7223 	  if (c_parser_next_token_is (parser, CPP_NAME))
7224 	    {
7225 	      tree id = c_parser_peek_token (parser)->value;
7226 	      c_parser_consume_token (parser);
7227 	      name = build_string (IDENTIFIER_LENGTH (id),
7228 				   IDENTIFIER_POINTER (id));
7229 	    }
7230 	  else
7231 	    {
7232 	      c_parser_error (parser, "expected identifier");
7233 	      c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
7234 	      return NULL_TREE;
7235 	    }
7236 	  c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
7237 				     "expected %<]%>");
7238 	}
7239       else
7240 	name = NULL_TREE;
7241       str = c_parser_asm_string_literal (parser);
7242       if (str == NULL_TREE)
7243 	return NULL_TREE;
7244       matching_parens parens;
7245       if (!parens.require_open (parser))
7246 	return NULL_TREE;
7247       expr = c_parser_expression (parser);
7248       mark_exp_read (expr.value);
7249       if (!parens.require_close (parser))
7250 	{
7251 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7252 	  return NULL_TREE;
7253 	}
7254       list = chainon (list, build_tree_list (build_tree_list (name, str),
7255 					     expr.value));
7256       if (c_parser_next_token_is (parser, CPP_COMMA))
7257 	c_parser_consume_token (parser);
7258       else
7259 	break;
7260     }
7261   return list;
7262 }
7263 
7264 /* Parse asm clobbers, a GNU extension.
7265 
7266    asm-clobbers:
7267      asm-string-literal
7268      asm-clobbers , asm-string-literal
7269 */
7270 
7271 static tree
c_parser_asm_clobbers(c_parser * parser)7272 c_parser_asm_clobbers (c_parser *parser)
7273 {
7274   tree list = NULL_TREE;
7275   while (true)
7276     {
7277       tree str = c_parser_asm_string_literal (parser);
7278       if (str)
7279 	list = tree_cons (NULL_TREE, str, list);
7280       else
7281 	return NULL_TREE;
7282       if (c_parser_next_token_is (parser, CPP_COMMA))
7283 	c_parser_consume_token (parser);
7284       else
7285 	break;
7286     }
7287   return list;
7288 }
7289 
7290 /* Parse asm goto labels, a GNU extension.
7291 
7292    asm-goto-operands:
7293      identifier
7294      asm-goto-operands , identifier
7295 */
7296 
7297 static tree
c_parser_asm_goto_operands(c_parser * parser)7298 c_parser_asm_goto_operands (c_parser *parser)
7299 {
7300   tree list = NULL_TREE;
7301   while (true)
7302     {
7303       tree name, label;
7304 
7305       if (c_parser_next_token_is (parser, CPP_NAME))
7306 	{
7307 	  c_token *tok = c_parser_peek_token (parser);
7308 	  name = tok->value;
7309 	  label = lookup_label_for_goto (tok->location, name);
7310 	  c_parser_consume_token (parser);
7311 	  TREE_USED (label) = 1;
7312 	}
7313       else
7314 	{
7315 	  c_parser_error (parser, "expected identifier");
7316 	  return NULL_TREE;
7317 	}
7318 
7319       name = build_string (IDENTIFIER_LENGTH (name),
7320 			   IDENTIFIER_POINTER (name));
7321       list = tree_cons (name, label, list);
7322       if (c_parser_next_token_is (parser, CPP_COMMA))
7323 	c_parser_consume_token (parser);
7324       else
7325 	return nreverse (list);
7326     }
7327 }
7328 
7329 /* Parse a possibly concatenated sequence of string literals.
7330    TRANSLATE says whether to translate them to the execution character
7331    set; WIDE_OK says whether any kind of prefixed string literal is
7332    permitted in this context.  This code is based on that in
7333    lex_string.  */
7334 
7335 struct c_expr
c_parser_string_literal(c_parser * parser,bool translate,bool wide_ok)7336 c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok)
7337 {
7338   struct c_expr ret;
7339   size_t count;
7340   struct obstack str_ob;
7341   struct obstack loc_ob;
7342   cpp_string str, istr, *strs;
7343   c_token *tok;
7344   location_t loc, last_tok_loc;
7345   enum cpp_ttype type;
7346   tree value, string_tree;
7347 
7348   tok = c_parser_peek_token (parser);
7349   loc = tok->location;
7350   last_tok_loc = linemap_resolve_location (line_table, loc,
7351 					   LRK_MACRO_DEFINITION_LOCATION,
7352 					   NULL);
7353   type = tok->type;
7354   switch (type)
7355     {
7356     case CPP_STRING:
7357     case CPP_WSTRING:
7358     case CPP_STRING16:
7359     case CPP_STRING32:
7360     case CPP_UTF8STRING:
7361       string_tree = tok->value;
7362       break;
7363 
7364     default:
7365       c_parser_error (parser, "expected string literal");
7366       ret.set_error ();
7367       ret.value = NULL_TREE;
7368       ret.original_code = ERROR_MARK;
7369       ret.original_type = NULL_TREE;
7370       return ret;
7371     }
7372 
7373   /* Try to avoid the overhead of creating and destroying an obstack
7374      for the common case of just one string.  */
7375   switch (c_parser_peek_2nd_token (parser)->type)
7376     {
7377     default:
7378       c_parser_consume_token (parser);
7379       str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
7380       str.len = TREE_STRING_LENGTH (string_tree);
7381       count = 1;
7382       strs = &str;
7383       break;
7384 
7385     case CPP_STRING:
7386     case CPP_WSTRING:
7387     case CPP_STRING16:
7388     case CPP_STRING32:
7389     case CPP_UTF8STRING:
7390       gcc_obstack_init (&str_ob);
7391       gcc_obstack_init (&loc_ob);
7392       count = 0;
7393       do
7394 	{
7395 	  c_parser_consume_token (parser);
7396 	  count++;
7397 	  str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
7398 	  str.len = TREE_STRING_LENGTH (string_tree);
7399 	  if (type != tok->type)
7400 	    {
7401 	      if (type == CPP_STRING)
7402 		type = tok->type;
7403 	      else if (tok->type != CPP_STRING)
7404 		error ("unsupported non-standard concatenation "
7405 		       "of string literals");
7406 	    }
7407 	  obstack_grow (&str_ob, &str, sizeof (cpp_string));
7408 	  obstack_grow (&loc_ob, &last_tok_loc, sizeof (location_t));
7409 	  tok = c_parser_peek_token (parser);
7410 	  string_tree = tok->value;
7411 	  last_tok_loc
7412 	    = linemap_resolve_location (line_table, tok->location,
7413 					LRK_MACRO_DEFINITION_LOCATION, NULL);
7414 	}
7415       while (tok->type == CPP_STRING
7416 	     || tok->type == CPP_WSTRING
7417 	     || tok->type == CPP_STRING16
7418 	     || tok->type == CPP_STRING32
7419 	     || tok->type == CPP_UTF8STRING);
7420       strs = (cpp_string *) obstack_finish (&str_ob);
7421     }
7422 
7423   if (count > 1 && !in_system_header_at (input_location))
7424     warning (OPT_Wtraditional,
7425 	     "traditional C rejects string constant concatenation");
7426 
7427   if ((type == CPP_STRING || wide_ok)
7428       && ((translate
7429 	  ? cpp_interpret_string : cpp_interpret_string_notranslate)
7430 	  (parse_in, strs, count, &istr, type)))
7431     {
7432       value = build_string (istr.len, (const char *) istr.text);
7433       free (CONST_CAST (unsigned char *, istr.text));
7434       if (count > 1)
7435 	{
7436 	  location_t *locs = (location_t *) obstack_finish (&loc_ob);
7437 	  gcc_assert (g_string_concat_db);
7438 	  g_string_concat_db->record_string_concatenation (count, locs);
7439 	}
7440     }
7441   else
7442     {
7443       if (type != CPP_STRING && !wide_ok)
7444 	{
7445 	  error_at (loc, "a wide string is invalid in this context");
7446 	  type = CPP_STRING;
7447 	}
7448       /* Callers cannot generally handle error_mark_node in this
7449 	 context, so return the empty string instead.  An error has
7450 	 been issued, either above or from cpp_interpret_string.  */
7451       switch (type)
7452 	{
7453 	default:
7454 	case CPP_STRING:
7455 	case CPP_UTF8STRING:
7456 	  value = build_string (1, "");
7457 	  break;
7458 	case CPP_STRING16:
7459 	  value = build_string (TYPE_PRECISION (char16_type_node)
7460 				/ TYPE_PRECISION (char_type_node),
7461 				"\0");  /* char16_t is 16 bits */
7462 	  break;
7463 	case CPP_STRING32:
7464 	  value = build_string (TYPE_PRECISION (char32_type_node)
7465 				/ TYPE_PRECISION (char_type_node),
7466 				"\0\0\0");  /* char32_t is 32 bits */
7467 	  break;
7468 	case CPP_WSTRING:
7469 	  value = build_string (TYPE_PRECISION (wchar_type_node)
7470 				/ TYPE_PRECISION (char_type_node),
7471 				"\0\0\0");  /* widest supported wchar_t
7472 					       is 32 bits */
7473 	  break;
7474         }
7475     }
7476 
7477   switch (type)
7478     {
7479     default:
7480     case CPP_STRING:
7481     case CPP_UTF8STRING:
7482       TREE_TYPE (value) = char_array_type_node;
7483       break;
7484     case CPP_STRING16:
7485       TREE_TYPE (value) = char16_array_type_node;
7486       break;
7487     case CPP_STRING32:
7488       TREE_TYPE (value) = char32_array_type_node;
7489       break;
7490     case CPP_WSTRING:
7491       TREE_TYPE (value) = wchar_array_type_node;
7492     }
7493   value = fix_string_type (value);
7494 
7495   if (count > 1)
7496     {
7497       obstack_free (&str_ob, 0);
7498       obstack_free (&loc_ob, 0);
7499     }
7500 
7501   ret.value = value;
7502   ret.original_code = STRING_CST;
7503   ret.original_type = NULL_TREE;
7504   set_c_expr_source_range (&ret, get_range_from_loc (line_table, loc));
7505   parser->seen_string_literal = true;
7506   return ret;
7507 }
7508 
7509 /* Parse an expression other than a compound expression; that is, an
7510    assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16).  If
7511    AFTER is not NULL then it is an Objective-C message expression which
7512    is the primary-expression starting the expression as an initializer.
7513 
7514    assignment-expression:
7515      conditional-expression
7516      unary-expression assignment-operator assignment-expression
7517 
7518    assignment-operator: one of
7519      = *= /= %= += -= <<= >>= &= ^= |=
7520 
7521    In GNU C we accept any conditional expression on the LHS and
7522    diagnose the invalid lvalue rather than producing a syntax
7523    error.  */
7524 
7525 static struct c_expr
c_parser_expr_no_commas(c_parser * parser,struct c_expr * after,tree omp_atomic_lhs)7526 c_parser_expr_no_commas (c_parser *parser, struct c_expr *after,
7527 			 tree omp_atomic_lhs)
7528 {
7529   struct c_expr lhs, rhs, ret;
7530   enum tree_code code;
7531   location_t op_location, exp_location;
7532   bool save_in_omp_for = c_in_omp_for;
7533   c_in_omp_for = false;
7534   gcc_assert (!after || c_dialect_objc ());
7535   lhs = c_parser_conditional_expression (parser, after, omp_atomic_lhs);
7536   op_location = c_parser_peek_token (parser)->location;
7537   switch (c_parser_peek_token (parser)->type)
7538     {
7539     case CPP_EQ:
7540       code = NOP_EXPR;
7541       break;
7542     case CPP_MULT_EQ:
7543       code = MULT_EXPR;
7544       break;
7545     case CPP_DIV_EQ:
7546       code = TRUNC_DIV_EXPR;
7547       break;
7548     case CPP_MOD_EQ:
7549       code = TRUNC_MOD_EXPR;
7550       break;
7551     case CPP_PLUS_EQ:
7552       code = PLUS_EXPR;
7553       break;
7554     case CPP_MINUS_EQ:
7555       code = MINUS_EXPR;
7556       break;
7557     case CPP_LSHIFT_EQ:
7558       code = LSHIFT_EXPR;
7559       break;
7560     case CPP_RSHIFT_EQ:
7561       code = RSHIFT_EXPR;
7562       break;
7563     case CPP_AND_EQ:
7564       code = BIT_AND_EXPR;
7565       break;
7566     case CPP_XOR_EQ:
7567       code = BIT_XOR_EXPR;
7568       break;
7569     case CPP_OR_EQ:
7570       code = BIT_IOR_EXPR;
7571       break;
7572     default:
7573       c_in_omp_for = save_in_omp_for;
7574       return lhs;
7575     }
7576   c_parser_consume_token (parser);
7577   exp_location = c_parser_peek_token (parser)->location;
7578   rhs = c_parser_expr_no_commas (parser, NULL);
7579   rhs = convert_lvalue_to_rvalue (exp_location, rhs, true, true);
7580 
7581   ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
7582 				 code, exp_location, rhs.value,
7583 				 rhs.original_type);
7584   set_c_expr_source_range (&ret, lhs.get_start (), rhs.get_finish ());
7585   if (code == NOP_EXPR)
7586     ret.original_code = MODIFY_EXPR;
7587   else
7588     {
7589       suppress_warning (ret.value, OPT_Wparentheses);
7590       ret.original_code = ERROR_MARK;
7591     }
7592   ret.original_type = NULL;
7593   c_in_omp_for = save_in_omp_for;
7594   return ret;
7595 }
7596 
7597 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15).  If
7598    AFTER is not NULL then it is an Objective-C message expression which is
7599    the primary-expression starting the expression as an initializer.
7600 
7601    conditional-expression:
7602      logical-OR-expression
7603      logical-OR-expression ? expression : conditional-expression
7604 
7605    GNU extensions:
7606 
7607    conditional-expression:
7608      logical-OR-expression ? : conditional-expression
7609 */
7610 
7611 static struct c_expr
c_parser_conditional_expression(c_parser * parser,struct c_expr * after,tree omp_atomic_lhs)7612 c_parser_conditional_expression (c_parser *parser, struct c_expr *after,
7613 				 tree omp_atomic_lhs)
7614 {
7615   struct c_expr cond, exp1, exp2, ret;
7616   location_t start, cond_loc, colon_loc;
7617 
7618   gcc_assert (!after || c_dialect_objc ());
7619 
7620   cond = c_parser_binary_expression (parser, after, omp_atomic_lhs);
7621 
7622   if (c_parser_next_token_is_not (parser, CPP_QUERY))
7623     return cond;
7624   if (cond.value != error_mark_node)
7625     start = cond.get_start ();
7626   else
7627     start = UNKNOWN_LOCATION;
7628   cond_loc = c_parser_peek_token (parser)->location;
7629   cond = convert_lvalue_to_rvalue (cond_loc, cond, true, true);
7630   c_parser_consume_token (parser);
7631   if (c_parser_next_token_is (parser, CPP_COLON))
7632     {
7633       tree eptype = NULL_TREE;
7634 
7635       location_t middle_loc = c_parser_peek_token (parser)->location;
7636       pedwarn (middle_loc, OPT_Wpedantic,
7637 	       "ISO C forbids omitting the middle term of a %<?:%> expression");
7638       if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR)
7639 	{
7640 	  eptype = TREE_TYPE (cond.value);
7641 	  cond.value = TREE_OPERAND (cond.value, 0);
7642 	}
7643       tree e = cond.value;
7644       while (TREE_CODE (e) == COMPOUND_EXPR)
7645 	e = TREE_OPERAND (e, 1);
7646       warn_for_omitted_condop (middle_loc, e);
7647       /* Make sure first operand is calculated only once.  */
7648       exp1.value = save_expr (default_conversion (cond.value));
7649       if (eptype)
7650 	exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value);
7651       exp1.original_type = NULL;
7652       exp1.src_range = cond.src_range;
7653       cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value);
7654       c_inhibit_evaluation_warnings += cond.value == truthvalue_true_node;
7655     }
7656   else
7657     {
7658       cond.value
7659 	= c_objc_common_truthvalue_conversion
7660 	(cond_loc, default_conversion (cond.value));
7661       c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node;
7662       exp1 = c_parser_expression_conv (parser);
7663       mark_exp_read (exp1.value);
7664       c_inhibit_evaluation_warnings +=
7665 	((cond.value == truthvalue_true_node)
7666 	 - (cond.value == truthvalue_false_node));
7667     }
7668 
7669   colon_loc = c_parser_peek_token (parser)->location;
7670   if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
7671     {
7672       c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
7673       ret.set_error ();
7674       ret.original_code = ERROR_MARK;
7675       ret.original_type = NULL;
7676       return ret;
7677     }
7678   {
7679     location_t exp2_loc = c_parser_peek_token (parser)->location;
7680     exp2 = c_parser_conditional_expression (parser, NULL, NULL_TREE);
7681     exp2 = convert_lvalue_to_rvalue (exp2_loc, exp2, true, true);
7682   }
7683   c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
7684   location_t loc1 = make_location (exp1.get_start (), exp1.src_range);
7685   location_t loc2 = make_location (exp2.get_start (), exp2.src_range);
7686   if (__builtin_expect (omp_atomic_lhs != NULL, 0)
7687       && (TREE_CODE (cond.value) == GT_EXPR
7688 	  || TREE_CODE (cond.value) == LT_EXPR
7689 	  || TREE_CODE (cond.value) == EQ_EXPR)
7690       && c_tree_equal (exp2.value, omp_atomic_lhs)
7691       && (c_tree_equal (TREE_OPERAND (cond.value, 0), omp_atomic_lhs)
7692 	  || c_tree_equal (TREE_OPERAND (cond.value, 1), omp_atomic_lhs)))
7693     ret.value = build3_loc (colon_loc, COND_EXPR, TREE_TYPE (omp_atomic_lhs),
7694 			    cond.value, exp1.value, exp2.value);
7695   else
7696     ret.value
7697       = build_conditional_expr (colon_loc, cond.value,
7698 				cond.original_code == C_MAYBE_CONST_EXPR,
7699 				exp1.value, exp1.original_type, loc1,
7700 				exp2.value, exp2.original_type, loc2);
7701   ret.original_code = ERROR_MARK;
7702   if (exp1.value == error_mark_node || exp2.value == error_mark_node)
7703     ret.original_type = NULL;
7704   else
7705     {
7706       tree t1, t2;
7707 
7708       /* If both sides are enum type, the default conversion will have
7709 	 made the type of the result be an integer type.  We want to
7710 	 remember the enum types we started with.  */
7711       t1 = exp1.original_type ? exp1.original_type : TREE_TYPE (exp1.value);
7712       t2 = exp2.original_type ? exp2.original_type : TREE_TYPE (exp2.value);
7713       ret.original_type = ((t1 != error_mark_node
7714 			    && t2 != error_mark_node
7715 			    && (TYPE_MAIN_VARIANT (t1)
7716 				== TYPE_MAIN_VARIANT (t2)))
7717 			   ? t1
7718 			   : NULL);
7719     }
7720   set_c_expr_source_range (&ret, start, exp2.get_finish ());
7721   return ret;
7722 }
7723 
7724 /* Parse a binary expression; that is, a logical-OR-expression (C90
7725    6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14).  If AFTER is not
7726    NULL then it is an Objective-C message expression which is the
7727    primary-expression starting the expression as an initializer.
7728 
7729    OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
7730    when it should be the unfolded lhs.  In a valid OpenMP source,
7731    one of the operands of the toplevel binary expression must be equal
7732    to it.  In that case, just return a build2 created binary operation
7733    rather than result of parser_build_binary_op.
7734 
7735    multiplicative-expression:
7736      cast-expression
7737      multiplicative-expression * cast-expression
7738      multiplicative-expression / cast-expression
7739      multiplicative-expression % cast-expression
7740 
7741    additive-expression:
7742      multiplicative-expression
7743      additive-expression + multiplicative-expression
7744      additive-expression - multiplicative-expression
7745 
7746    shift-expression:
7747      additive-expression
7748      shift-expression << additive-expression
7749      shift-expression >> additive-expression
7750 
7751    relational-expression:
7752      shift-expression
7753      relational-expression < shift-expression
7754      relational-expression > shift-expression
7755      relational-expression <= shift-expression
7756      relational-expression >= shift-expression
7757 
7758    equality-expression:
7759      relational-expression
7760      equality-expression == relational-expression
7761      equality-expression != relational-expression
7762 
7763    AND-expression:
7764      equality-expression
7765      AND-expression & equality-expression
7766 
7767    exclusive-OR-expression:
7768      AND-expression
7769      exclusive-OR-expression ^ AND-expression
7770 
7771    inclusive-OR-expression:
7772      exclusive-OR-expression
7773      inclusive-OR-expression | exclusive-OR-expression
7774 
7775    logical-AND-expression:
7776      inclusive-OR-expression
7777      logical-AND-expression && inclusive-OR-expression
7778 
7779    logical-OR-expression:
7780      logical-AND-expression
7781      logical-OR-expression || logical-AND-expression
7782 */
7783 
7784 static struct c_expr
c_parser_binary_expression(c_parser * parser,struct c_expr * after,tree omp_atomic_lhs)7785 c_parser_binary_expression (c_parser *parser, struct c_expr *after,
7786 			    tree omp_atomic_lhs)
7787 {
7788   /* A binary expression is parsed using operator-precedence parsing,
7789      with the operands being cast expressions.  All the binary
7790      operators are left-associative.  Thus a binary expression is of
7791      form:
7792 
7793      E0 op1 E1 op2 E2 ...
7794 
7795      which we represent on a stack.  On the stack, the precedence
7796      levels are strictly increasing.  When a new operator is
7797      encountered of higher precedence than that at the top of the
7798      stack, it is pushed; its LHS is the top expression, and its RHS
7799      is everything parsed until it is popped.  When a new operator is
7800      encountered with precedence less than or equal to that at the top
7801      of the stack, triples E[i-1] op[i] E[i] are popped and replaced
7802      by the result of the operation until the operator at the top of
7803      the stack has lower precedence than the new operator or there is
7804      only one element on the stack; then the top expression is the LHS
7805      of the new operator.  In the case of logical AND and OR
7806      expressions, we also need to adjust c_inhibit_evaluation_warnings
7807      as appropriate when the operators are pushed and popped.  */
7808 
7809   struct {
7810     /* The expression at this stack level.  */
7811     struct c_expr expr;
7812     /* The precedence of the operator on its left, PREC_NONE at the
7813        bottom of the stack.  */
7814     enum c_parser_prec prec;
7815     /* The operation on its left.  */
7816     enum tree_code op;
7817     /* The source location of this operation.  */
7818     location_t loc;
7819     /* The sizeof argument if expr.original_code == {PAREN_,}SIZEOF_EXPR.  */
7820     tree sizeof_arg;
7821   } stack[NUM_PRECS];
7822   int sp;
7823   /* Location of the binary operator.  */
7824   location_t binary_loc = UNKNOWN_LOCATION;  /* Quiet warning.  */
7825 #define POP								      \
7826   do {									      \
7827     switch (stack[sp].op)						      \
7828       {									      \
7829       case TRUTH_ANDIF_EXPR:						      \
7830 	c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value	      \
7831 					  == truthvalue_false_node);	      \
7832 	break;								      \
7833       case TRUTH_ORIF_EXPR:						      \
7834 	c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value	      \
7835 					  == truthvalue_true_node);	      \
7836 	break;								      \
7837       case TRUNC_DIV_EXPR:						      \
7838 	if ((stack[sp - 1].expr.original_code == SIZEOF_EXPR		      \
7839 	     || stack[sp - 1].expr.original_code == PAREN_SIZEOF_EXPR)	      \
7840 	    && (stack[sp].expr.original_code == SIZEOF_EXPR		      \
7841 		|| stack[sp].expr.original_code == PAREN_SIZEOF_EXPR))	      \
7842 	  {								      \
7843 	    tree type0 = stack[sp - 1].sizeof_arg;			      \
7844 	    tree type1 = stack[sp].sizeof_arg;				      \
7845 	    tree first_arg = type0;					      \
7846 	    if (!TYPE_P (type0))					      \
7847 	      type0 = TREE_TYPE (type0);				      \
7848 	    if (!TYPE_P (type1))					      \
7849 	      type1 = TREE_TYPE (type1);				      \
7850 	    if (POINTER_TYPE_P (type0)					      \
7851 		&& comptypes (TREE_TYPE (type0), type1)			      \
7852 		&& !(TREE_CODE (first_arg) == PARM_DECL			      \
7853 		     && C_ARRAY_PARAMETER (first_arg)			      \
7854 		     && warn_sizeof_array_argument))			      \
7855 	      {								      \
7856 		auto_diagnostic_group d;				      \
7857 		if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div,	      \
7858 				  "division %<sizeof (%T) / sizeof (%T)%> "   \
7859 				  "does not compute the number of array "     \
7860 				  "elements",				      \
7861 				  type0, type1))			      \
7862 		  if (DECL_P (first_arg))				      \
7863 		    inform (DECL_SOURCE_LOCATION (first_arg),		      \
7864 			      "first %<sizeof%> operand was declared here");  \
7865 	      }								      \
7866 	    else if (TREE_CODE (type0) == ARRAY_TYPE			      \
7867 		     && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0)))  \
7868 		     && stack[sp].expr.original_code != PAREN_SIZEOF_EXPR)    \
7869 	      maybe_warn_sizeof_array_div (stack[sp].loc, first_arg, type0,   \
7870 					   stack[sp].sizeof_arg, type1);      \
7871 	  }								      \
7872 	break;								      \
7873       default:								      \
7874 	break;								      \
7875       }									      \
7876     stack[sp - 1].expr							      \
7877       = convert_lvalue_to_rvalue (stack[sp - 1].loc,			      \
7878 				  stack[sp - 1].expr, true, true);	      \
7879     stack[sp].expr							      \
7880       = convert_lvalue_to_rvalue (stack[sp].loc,			      \
7881 				  stack[sp].expr, true, true);		      \
7882     if (__builtin_expect (omp_atomic_lhs != NULL_TREE, 0) && sp == 1	      \
7883 	&& ((c_parser_next_token_is (parser, CPP_SEMICOLON)		      \
7884 	     && ((1 << stack[sp].prec)					      \
7885 		 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR)		      \
7886 		     | (1 << PREC_BITAND) | (1 << PREC_SHIFT)		      \
7887 		     | (1 << PREC_ADD) | (1 << PREC_MULT)		      \
7888 		     | (1 << PREC_EQ))))				      \
7889 	    || ((c_parser_next_token_is (parser, CPP_QUERY)		      \
7890 		 || (omp_atomic_lhs == void_list_node			      \
7891 		     && c_parser_next_token_is (parser, CPP_CLOSE_PAREN)))    \
7892 		&& (stack[sp].prec == PREC_REL || stack[sp].prec == PREC_EQ)))\
7893 	&& stack[sp].op != TRUNC_MOD_EXPR				      \
7894 	&& stack[sp].op != GE_EXPR					      \
7895 	&& stack[sp].op != LE_EXPR					      \
7896 	&& stack[sp].op != NE_EXPR					      \
7897 	&& stack[0].expr.value != error_mark_node			      \
7898 	&& stack[1].expr.value != error_mark_node			      \
7899 	&& (omp_atomic_lhs == void_list_node				      \
7900 	    || c_tree_equal (stack[0].expr.value, omp_atomic_lhs)	      \
7901 	    || c_tree_equal (stack[1].expr.value, omp_atomic_lhs)	      \
7902 	    || (stack[sp].op == EQ_EXPR					      \
7903 		&& c_parser_peek_2nd_token (parser)->keyword == RID_IF)))     \
7904       {									      \
7905 	tree t = make_node (stack[1].op);				      \
7906 	TREE_TYPE (t) = TREE_TYPE (stack[0].expr.value);		      \
7907 	TREE_OPERAND (t, 0) = stack[0].expr.value;			      \
7908 	TREE_OPERAND (t, 1) = stack[1].expr.value;			      \
7909 	stack[0].expr.value = t;					      \
7910       }									      \
7911     else								      \
7912       stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc,	      \
7913 						   stack[sp].op,	      \
7914 						   stack[sp - 1].expr,	      \
7915 						   stack[sp].expr);	      \
7916     sp--;								      \
7917   } while (0)
7918   gcc_assert (!after || c_dialect_objc ());
7919   stack[0].loc = c_parser_peek_token (parser)->location;
7920   stack[0].expr = c_parser_cast_expression (parser, after);
7921   stack[0].prec = PREC_NONE;
7922   stack[0].sizeof_arg = c_last_sizeof_arg;
7923   sp = 0;
7924   while (true)
7925     {
7926       enum c_parser_prec oprec;
7927       enum tree_code ocode;
7928       source_range src_range;
7929       if (parser->error)
7930 	goto out;
7931       switch (c_parser_peek_token (parser)->type)
7932 	{
7933 	case CPP_MULT:
7934 	  oprec = PREC_MULT;
7935 	  ocode = MULT_EXPR;
7936 	  break;
7937 	case CPP_DIV:
7938 	  oprec = PREC_MULT;
7939 	  ocode = TRUNC_DIV_EXPR;
7940 	  break;
7941 	case CPP_MOD:
7942 	  oprec = PREC_MULT;
7943 	  ocode = TRUNC_MOD_EXPR;
7944 	  break;
7945 	case CPP_PLUS:
7946 	  oprec = PREC_ADD;
7947 	  ocode = PLUS_EXPR;
7948 	  break;
7949 	case CPP_MINUS:
7950 	  oprec = PREC_ADD;
7951 	  ocode = MINUS_EXPR;
7952 	  break;
7953 	case CPP_LSHIFT:
7954 	  oprec = PREC_SHIFT;
7955 	  ocode = LSHIFT_EXPR;
7956 	  break;
7957 	case CPP_RSHIFT:
7958 	  oprec = PREC_SHIFT;
7959 	  ocode = RSHIFT_EXPR;
7960 	  break;
7961 	case CPP_LESS:
7962 	  oprec = PREC_REL;
7963 	  ocode = LT_EXPR;
7964 	  break;
7965 	case CPP_GREATER:
7966 	  oprec = PREC_REL;
7967 	  ocode = GT_EXPR;
7968 	  break;
7969 	case CPP_LESS_EQ:
7970 	  oprec = PREC_REL;
7971 	  ocode = LE_EXPR;
7972 	  break;
7973 	case CPP_GREATER_EQ:
7974 	  oprec = PREC_REL;
7975 	  ocode = GE_EXPR;
7976 	  break;
7977 	case CPP_EQ_EQ:
7978 	  oprec = PREC_EQ;
7979 	  ocode = EQ_EXPR;
7980 	  break;
7981 	case CPP_NOT_EQ:
7982 	  oprec = PREC_EQ;
7983 	  ocode = NE_EXPR;
7984 	  break;
7985 	case CPP_AND:
7986 	  oprec = PREC_BITAND;
7987 	  ocode = BIT_AND_EXPR;
7988 	  break;
7989 	case CPP_XOR:
7990 	  oprec = PREC_BITXOR;
7991 	  ocode = BIT_XOR_EXPR;
7992 	  break;
7993 	case CPP_OR:
7994 	  oprec = PREC_BITOR;
7995 	  ocode = BIT_IOR_EXPR;
7996 	  break;
7997 	case CPP_AND_AND:
7998 	  oprec = PREC_LOGAND;
7999 	  ocode = TRUTH_ANDIF_EXPR;
8000 	  break;
8001 	case CPP_OR_OR:
8002 	  oprec = PREC_LOGOR;
8003 	  ocode = TRUTH_ORIF_EXPR;
8004 	  break;
8005 	default:
8006 	  /* Not a binary operator, so end of the binary
8007 	     expression.  */
8008 	  goto out;
8009 	}
8010       binary_loc = c_parser_peek_token (parser)->location;
8011       while (oprec <= stack[sp].prec)
8012 	POP;
8013       c_parser_consume_token (parser);
8014       switch (ocode)
8015 	{
8016 	case TRUTH_ANDIF_EXPR:
8017 	  src_range = stack[sp].expr.src_range;
8018 	  stack[sp].expr
8019 	    = convert_lvalue_to_rvalue (stack[sp].loc,
8020 					stack[sp].expr, true, true);
8021 	  stack[sp].expr.value = c_objc_common_truthvalue_conversion
8022 	    (stack[sp].loc, default_conversion (stack[sp].expr.value));
8023 	  c_inhibit_evaluation_warnings += (stack[sp].expr.value
8024 					    == truthvalue_false_node);
8025 	  set_c_expr_source_range (&stack[sp].expr, src_range);
8026 	  break;
8027 	case TRUTH_ORIF_EXPR:
8028 	  src_range = stack[sp].expr.src_range;
8029 	  stack[sp].expr
8030 	    = convert_lvalue_to_rvalue (stack[sp].loc,
8031 					stack[sp].expr, true, true);
8032 	  stack[sp].expr.value = c_objc_common_truthvalue_conversion
8033 	    (stack[sp].loc, default_conversion (stack[sp].expr.value));
8034 	  c_inhibit_evaluation_warnings += (stack[sp].expr.value
8035 					    == truthvalue_true_node);
8036 	  set_c_expr_source_range (&stack[sp].expr, src_range);
8037 	  break;
8038 	default:
8039 	  break;
8040 	}
8041       sp++;
8042       stack[sp].loc = binary_loc;
8043       stack[sp].expr = c_parser_cast_expression (parser, NULL);
8044       stack[sp].prec = oprec;
8045       stack[sp].op = ocode;
8046       stack[sp].sizeof_arg = c_last_sizeof_arg;
8047     }
8048  out:
8049   while (sp > 0)
8050     POP;
8051   return stack[0].expr;
8052 #undef POP
8053 }
8054 
8055 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4).  If AFTER
8056    is not NULL then it is an Objective-C message expression which is the
8057    primary-expression starting the expression as an initializer.
8058 
8059    cast-expression:
8060      unary-expression
8061      ( type-name ) unary-expression
8062 */
8063 
8064 static struct c_expr
c_parser_cast_expression(c_parser * parser,struct c_expr * after)8065 c_parser_cast_expression (c_parser *parser, struct c_expr *after)
8066 {
8067   location_t cast_loc = c_parser_peek_token (parser)->location;
8068   gcc_assert (!after || c_dialect_objc ());
8069   if (after)
8070     return c_parser_postfix_expression_after_primary (parser,
8071 						      cast_loc, *after);
8072   /* If the expression begins with a parenthesized type name, it may
8073      be either a cast or a compound literal; we need to see whether
8074      the next character is '{' to tell the difference.  If not, it is
8075      an unary expression.  Full detection of unknown typenames here
8076      would require a 3-token lookahead.  */
8077   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8078       && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8079     {
8080       struct c_type_name *type_name;
8081       struct c_expr ret;
8082       struct c_expr expr;
8083       matching_parens parens;
8084       parens.consume_open (parser);
8085       type_name = c_parser_type_name (parser, true);
8086       parens.skip_until_found_close (parser);
8087       if (type_name == NULL)
8088 	{
8089 	  ret.set_error ();
8090 	  ret.original_code = ERROR_MARK;
8091 	  ret.original_type = NULL;
8092 	  return ret;
8093 	}
8094 
8095       /* Save casted types in the function's used types hash table.  */
8096       used_types_insert (type_name->specs->type);
8097 
8098       if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8099 	return c_parser_postfix_expression_after_paren_type (parser, type_name,
8100 							     cast_loc);
8101       if (type_name->specs->alignas_p)
8102 	error_at (type_name->specs->locations[cdw_alignas],
8103 		  "alignment specified for type name in cast");
8104       {
8105 	location_t expr_loc = c_parser_peek_token (parser)->location;
8106 	expr = c_parser_cast_expression (parser, NULL);
8107 	expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
8108       }
8109       ret.value = c_cast_expr (cast_loc, type_name, expr.value);
8110       if (ret.value && expr.value)
8111 	set_c_expr_source_range (&ret, cast_loc, expr.get_finish ());
8112       ret.original_code = ERROR_MARK;
8113       ret.original_type = NULL;
8114       return ret;
8115     }
8116   else
8117     return c_parser_unary_expression (parser);
8118 }
8119 
8120 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
8121 
8122    unary-expression:
8123      postfix-expression
8124      ++ unary-expression
8125      -- unary-expression
8126      unary-operator cast-expression
8127      sizeof unary-expression
8128      sizeof ( type-name )
8129 
8130    unary-operator: one of
8131      & * + - ~ !
8132 
8133    GNU extensions:
8134 
8135    unary-expression:
8136      __alignof__ unary-expression
8137      __alignof__ ( type-name )
8138      && identifier
8139 
8140    (C11 permits _Alignof with type names only.)
8141 
8142    unary-operator: one of
8143      __extension__ __real__ __imag__
8144 
8145    Transactional Memory:
8146 
8147    unary-expression:
8148      transaction-expression
8149 
8150    In addition, the GNU syntax treats ++ and -- as unary operators, so
8151    they may be applied to cast expressions with errors for non-lvalues
8152    given later.  */
8153 
8154 static struct c_expr
c_parser_unary_expression(c_parser * parser)8155 c_parser_unary_expression (c_parser *parser)
8156 {
8157   int ext;
8158   struct c_expr ret, op;
8159   location_t op_loc = c_parser_peek_token (parser)->location;
8160   location_t exp_loc;
8161   location_t finish;
8162   ret.original_code = ERROR_MARK;
8163   ret.original_type = NULL;
8164   switch (c_parser_peek_token (parser)->type)
8165     {
8166     case CPP_PLUS_PLUS:
8167       c_parser_consume_token (parser);
8168       exp_loc = c_parser_peek_token (parser)->location;
8169       op = c_parser_cast_expression (parser, NULL);
8170 
8171       op = default_function_array_read_conversion (exp_loc, op);
8172       return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
8173     case CPP_MINUS_MINUS:
8174       c_parser_consume_token (parser);
8175       exp_loc = c_parser_peek_token (parser)->location;
8176       op = c_parser_cast_expression (parser, NULL);
8177 
8178       op = default_function_array_read_conversion (exp_loc, op);
8179       return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
8180     case CPP_AND:
8181       c_parser_consume_token (parser);
8182       op = c_parser_cast_expression (parser, NULL);
8183       mark_exp_read (op.value);
8184       return parser_build_unary_op (op_loc, ADDR_EXPR, op);
8185     case CPP_MULT:
8186       {
8187 	c_parser_consume_token (parser);
8188 	exp_loc = c_parser_peek_token (parser)->location;
8189 	op = c_parser_cast_expression (parser, NULL);
8190 	finish = op.get_finish ();
8191 	op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8192 	location_t combined_loc = make_location (op_loc, op_loc, finish);
8193 	ret.value = build_indirect_ref (combined_loc, op.value, RO_UNARY_STAR);
8194 	ret.src_range.m_start = op_loc;
8195 	ret.src_range.m_finish = finish;
8196 	return ret;
8197       }
8198     case CPP_PLUS:
8199       if (!c_dialect_objc () && !in_system_header_at (input_location))
8200 	warning_at (op_loc,
8201 		    OPT_Wtraditional,
8202 		    "traditional C rejects the unary plus operator");
8203       c_parser_consume_token (parser);
8204       exp_loc = c_parser_peek_token (parser)->location;
8205       op = c_parser_cast_expression (parser, NULL);
8206       op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8207       return parser_build_unary_op (op_loc, CONVERT_EXPR, op);
8208     case CPP_MINUS:
8209       c_parser_consume_token (parser);
8210       exp_loc = c_parser_peek_token (parser)->location;
8211       op = c_parser_cast_expression (parser, NULL);
8212       op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8213       return parser_build_unary_op (op_loc, NEGATE_EXPR, op);
8214     case CPP_COMPL:
8215       c_parser_consume_token (parser);
8216       exp_loc = c_parser_peek_token (parser)->location;
8217       op = c_parser_cast_expression (parser, NULL);
8218       op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8219       return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
8220     case CPP_NOT:
8221       c_parser_consume_token (parser);
8222       exp_loc = c_parser_peek_token (parser)->location;
8223       op = c_parser_cast_expression (parser, NULL);
8224       op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8225       return parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op);
8226     case CPP_AND_AND:
8227       /* Refer to the address of a label as a pointer.  */
8228       c_parser_consume_token (parser);
8229       if (c_parser_next_token_is (parser, CPP_NAME))
8230 	{
8231 	  ret.value = finish_label_address_expr
8232 	    (c_parser_peek_token (parser)->value, op_loc);
8233 	  set_c_expr_source_range (&ret, op_loc,
8234 				   c_parser_peek_token (parser)->get_finish ());
8235 	  c_parser_consume_token (parser);
8236 	}
8237       else
8238 	{
8239 	  c_parser_error (parser, "expected identifier");
8240 	  ret.set_error ();
8241 	}
8242       return ret;
8243     case CPP_KEYWORD:
8244       switch (c_parser_peek_token (parser)->keyword)
8245 	{
8246 	case RID_SIZEOF:
8247 	  return c_parser_sizeof_expression (parser);
8248 	case RID_ALIGNOF:
8249 	  return c_parser_alignof_expression (parser);
8250 	case RID_BUILTIN_HAS_ATTRIBUTE:
8251 	  return c_parser_has_attribute_expression (parser);
8252 	case RID_EXTENSION:
8253 	  c_parser_consume_token (parser);
8254 	  ext = disable_extension_diagnostics ();
8255 	  ret = c_parser_cast_expression (parser, NULL);
8256 	  restore_extension_diagnostics (ext);
8257 	  return ret;
8258 	case RID_REALPART:
8259 	  c_parser_consume_token (parser);
8260 	  exp_loc = c_parser_peek_token (parser)->location;
8261 	  op = c_parser_cast_expression (parser, NULL);
8262 	  op = default_function_array_conversion (exp_loc, op);
8263 	  return parser_build_unary_op (op_loc, REALPART_EXPR, op);
8264 	case RID_IMAGPART:
8265 	  c_parser_consume_token (parser);
8266 	  exp_loc = c_parser_peek_token (parser)->location;
8267 	  op = c_parser_cast_expression (parser, NULL);
8268 	  op = default_function_array_conversion (exp_loc, op);
8269 	  return parser_build_unary_op (op_loc, IMAGPART_EXPR, op);
8270 	case RID_TRANSACTION_ATOMIC:
8271 	case RID_TRANSACTION_RELAXED:
8272 	  return c_parser_transaction_expression (parser,
8273 	      c_parser_peek_token (parser)->keyword);
8274 	default:
8275 	  return c_parser_postfix_expression (parser);
8276 	}
8277     default:
8278       return c_parser_postfix_expression (parser);
8279     }
8280 }
8281 
8282 /* Parse a sizeof expression.  */
8283 
8284 static struct c_expr
c_parser_sizeof_expression(c_parser * parser)8285 c_parser_sizeof_expression (c_parser *parser)
8286 {
8287   struct c_expr expr;
8288   struct c_expr result;
8289   location_t expr_loc;
8290   gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF));
8291 
8292   location_t start;
8293   location_t finish = UNKNOWN_LOCATION;
8294 
8295   start = c_parser_peek_token (parser)->location;
8296 
8297   c_parser_consume_token (parser);
8298   c_inhibit_evaluation_warnings++;
8299   in_sizeof++;
8300   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8301       && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8302     {
8303       /* Either sizeof ( type-name ) or sizeof unary-expression
8304 	 starting with a compound literal.  */
8305       struct c_type_name *type_name;
8306       matching_parens parens;
8307       parens.consume_open (parser);
8308       expr_loc = c_parser_peek_token (parser)->location;
8309       type_name = c_parser_type_name (parser, true);
8310       parens.skip_until_found_close (parser);
8311       finish = parser->tokens_buf[0].location;
8312       if (type_name == NULL)
8313 	{
8314 	  struct c_expr ret;
8315 	  c_inhibit_evaluation_warnings--;
8316 	  in_sizeof--;
8317 	  ret.set_error ();
8318 	  ret.original_code = ERROR_MARK;
8319 	  ret.original_type = NULL;
8320 	  return ret;
8321 	}
8322       if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8323 	{
8324 	  expr = c_parser_postfix_expression_after_paren_type (parser,
8325 							       type_name,
8326 							       expr_loc);
8327 	  finish = expr.get_finish ();
8328 	  goto sizeof_expr;
8329 	}
8330       /* sizeof ( type-name ).  */
8331       if (type_name->specs->alignas_p)
8332 	error_at (type_name->specs->locations[cdw_alignas],
8333 		  "alignment specified for type name in %<sizeof%>");
8334       c_inhibit_evaluation_warnings--;
8335       in_sizeof--;
8336       result = c_expr_sizeof_type (expr_loc, type_name);
8337     }
8338   else
8339     {
8340       expr_loc = c_parser_peek_token (parser)->location;
8341       expr = c_parser_unary_expression (parser);
8342       finish = expr.get_finish ();
8343     sizeof_expr:
8344       c_inhibit_evaluation_warnings--;
8345       in_sizeof--;
8346       mark_exp_read (expr.value);
8347       if (TREE_CODE (expr.value) == COMPONENT_REF
8348 	  && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
8349 	error_at (expr_loc, "%<sizeof%> applied to a bit-field");
8350       result = c_expr_sizeof_expr (expr_loc, expr);
8351     }
8352   if (finish == UNKNOWN_LOCATION)
8353     finish = start;
8354   set_c_expr_source_range (&result, start, finish);
8355   return result;
8356 }
8357 
8358 /* Parse an alignof expression.  */
8359 
8360 static struct c_expr
c_parser_alignof_expression(c_parser * parser)8361 c_parser_alignof_expression (c_parser *parser)
8362 {
8363   struct c_expr expr;
8364   location_t start_loc = c_parser_peek_token (parser)->location;
8365   location_t end_loc;
8366   tree alignof_spelling = c_parser_peek_token (parser)->value;
8367   gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF));
8368   bool is_c11_alignof = strcmp (IDENTIFIER_POINTER (alignof_spelling),
8369 				"_Alignof") == 0;
8370   /* A diagnostic is not required for the use of this identifier in
8371      the implementation namespace; only diagnose it for the C11
8372      spelling because of existing code using the other spellings.  */
8373   if (is_c11_alignof)
8374     {
8375       if (flag_isoc99)
8376 	pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C99 does not support %qE",
8377 		     alignof_spelling);
8378       else
8379 	pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C90 does not support %qE",
8380 		     alignof_spelling);
8381     }
8382   c_parser_consume_token (parser);
8383   c_inhibit_evaluation_warnings++;
8384   in_alignof++;
8385   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8386       && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8387     {
8388       /* Either __alignof__ ( type-name ) or __alignof__
8389 	 unary-expression starting with a compound literal.  */
8390       location_t loc;
8391       struct c_type_name *type_name;
8392       struct c_expr ret;
8393       matching_parens parens;
8394       parens.consume_open (parser);
8395       loc = c_parser_peek_token (parser)->location;
8396       type_name = c_parser_type_name (parser, true);
8397       end_loc = c_parser_peek_token (parser)->location;
8398       parens.skip_until_found_close (parser);
8399       if (type_name == NULL)
8400 	{
8401 	  struct c_expr ret;
8402 	  c_inhibit_evaluation_warnings--;
8403 	  in_alignof--;
8404 	  ret.set_error ();
8405 	  ret.original_code = ERROR_MARK;
8406 	  ret.original_type = NULL;
8407 	  return ret;
8408 	}
8409       if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8410 	{
8411 	  expr = c_parser_postfix_expression_after_paren_type (parser,
8412 							       type_name,
8413 							       loc);
8414 	  goto alignof_expr;
8415 	}
8416       /* alignof ( type-name ).  */
8417       if (type_name->specs->alignas_p)
8418 	error_at (type_name->specs->locations[cdw_alignas],
8419 		  "alignment specified for type name in %qE",
8420 		  alignof_spelling);
8421       c_inhibit_evaluation_warnings--;
8422       in_alignof--;
8423       ret.value = c_sizeof_or_alignof_type (loc, groktypename (type_name,
8424 							       NULL, NULL),
8425 					    false, is_c11_alignof, 1);
8426       ret.original_code = ERROR_MARK;
8427       ret.original_type = NULL;
8428       set_c_expr_source_range (&ret, start_loc, end_loc);
8429       return ret;
8430     }
8431   else
8432     {
8433       struct c_expr ret;
8434       expr = c_parser_unary_expression (parser);
8435       end_loc = expr.src_range.m_finish;
8436     alignof_expr:
8437       mark_exp_read (expr.value);
8438       c_inhibit_evaluation_warnings--;
8439       in_alignof--;
8440       if (is_c11_alignof)
8441 	pedwarn (start_loc,
8442 		 OPT_Wpedantic, "ISO C does not allow %<%E (expression)%>",
8443 		 alignof_spelling);
8444       ret.value = c_alignof_expr (start_loc, expr.value);
8445       ret.original_code = ERROR_MARK;
8446       ret.original_type = NULL;
8447       set_c_expr_source_range (&ret, start_loc, end_loc);
8448       return ret;
8449     }
8450 }
8451 
8452 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
8453    expression.  */
8454 
8455 static struct c_expr
c_parser_has_attribute_expression(c_parser * parser)8456 c_parser_has_attribute_expression (c_parser *parser)
8457 {
8458   gcc_assert (c_parser_next_token_is_keyword (parser,
8459 					      RID_BUILTIN_HAS_ATTRIBUTE));
8460   location_t start = c_parser_peek_token (parser)->location;
8461   c_parser_consume_token (parser);
8462 
8463   c_inhibit_evaluation_warnings++;
8464 
8465   matching_parens parens;
8466   if (!parens.require_open (parser))
8467     {
8468       c_inhibit_evaluation_warnings--;
8469       in_typeof--;
8470 
8471       struct c_expr result;
8472       result.set_error ();
8473       result.original_code = ERROR_MARK;
8474       result.original_type = NULL;
8475       return result;
8476     }
8477 
8478   /* Treat the type argument the same way as in typeof for the purposes
8479      of warnings.  FIXME: Generalize this so the warning refers to
8480      __builtin_has_attribute rather than typeof.  */
8481   in_typeof++;
8482 
8483   /* The first operand: one of DECL, EXPR, or TYPE.  */
8484   tree oper = NULL_TREE;
8485   if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
8486     {
8487       struct c_type_name *tname = c_parser_type_name (parser);
8488       in_typeof--;
8489       if (tname)
8490 	{
8491 	  oper = groktypename (tname, NULL, NULL);
8492 	  pop_maybe_used (variably_modified_type_p (oper, NULL_TREE));
8493 	}
8494     }
8495   else
8496     {
8497       struct c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
8498       c_inhibit_evaluation_warnings--;
8499       in_typeof--;
8500       if (cexpr.value != error_mark_node)
8501 	{
8502 	  mark_exp_read (cexpr.value);
8503 	  oper = cexpr.value;
8504 	  tree etype = TREE_TYPE (oper);
8505 	  bool was_vm = variably_modified_type_p (etype, NULL_TREE);
8506 	  /* This is returned with the type so that when the type is
8507 	     evaluated, this can be evaluated.  */
8508 	  if (was_vm)
8509 	    oper = c_fully_fold (oper, false, NULL);
8510 	  pop_maybe_used (was_vm);
8511 	}
8512     }
8513 
8514   struct c_expr result;
8515   result.original_code = ERROR_MARK;
8516   result.original_type = NULL;
8517 
8518   if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8519     {
8520       /* Consume the closing parenthesis if that's the next token
8521 	 in the likely case the built-in was invoked with fewer
8522 	 than two arguments.  */
8523       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8524 	c_parser_consume_token (parser);
8525       c_inhibit_evaluation_warnings--;
8526       result.set_error ();
8527       return result;
8528     }
8529 
8530   bool save_translate_strings_p = parser->translate_strings_p;
8531 
8532   location_t atloc = c_parser_peek_token (parser)->location;
8533   /* Parse a single attribute.  Require no leading comma and do not
8534      allow empty attributes.  */
8535   tree attr = c_parser_gnu_attribute (parser, NULL_TREE, false, false);
8536 
8537   parser->translate_strings_p = save_translate_strings_p;
8538 
8539   location_t finish = c_parser_peek_token (parser)->location;
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   set_c_expr_source_range (&result, start, finish);
8569   return result;
8570 }
8571 
8572 /* Helper function to read arguments of builtins which are interfaces
8573    for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
8574    others.  The name of the builtin is passed using BNAME parameter.
8575    Function returns true if there were no errors while parsing and
8576    stores the arguments in CEXPR_LIST.  If it returns true,
8577    *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
8578    parenthesis.  */
8579 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)8580 c_parser_get_builtin_args (c_parser *parser, const char *bname,
8581 			   vec<c_expr_t, va_gc> **ret_cexpr_list,
8582 			   bool choose_expr_p,
8583 			   location_t *out_close_paren_loc)
8584 {
8585   location_t loc = c_parser_peek_token (parser)->location;
8586   vec<c_expr_t, va_gc> *cexpr_list;
8587   c_expr_t expr;
8588   bool saved_force_folding_builtin_constant_p;
8589 
8590   *ret_cexpr_list = NULL;
8591   if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
8592     {
8593       error_at (loc, "cannot take address of %qs", bname);
8594       return false;
8595     }
8596 
8597   c_parser_consume_token (parser);
8598 
8599   if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8600     {
8601       *out_close_paren_loc = c_parser_peek_token (parser)->location;
8602       c_parser_consume_token (parser);
8603       return true;
8604     }
8605 
8606   saved_force_folding_builtin_constant_p
8607     = force_folding_builtin_constant_p;
8608   force_folding_builtin_constant_p |= choose_expr_p;
8609   expr = c_parser_expr_no_commas (parser, NULL);
8610   force_folding_builtin_constant_p
8611     = saved_force_folding_builtin_constant_p;
8612   vec_alloc (cexpr_list, 1);
8613   vec_safe_push (cexpr_list, expr);
8614   while (c_parser_next_token_is (parser, CPP_COMMA))
8615     {
8616       c_parser_consume_token (parser);
8617       expr = c_parser_expr_no_commas (parser, NULL);
8618       vec_safe_push (cexpr_list, expr);
8619     }
8620 
8621   *out_close_paren_loc = c_parser_peek_token (parser)->location;
8622   if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
8623     return false;
8624 
8625   *ret_cexpr_list = cexpr_list;
8626   return true;
8627 }
8628 
8629 /* This represents a single generic-association.  */
8630 
8631 struct c_generic_association
8632 {
8633   /* The location of the starting token of the type.  */
8634   location_t type_location;
8635   /* The association's type, or NULL_TREE for 'default'.  */
8636   tree type;
8637   /* The association's expression.  */
8638   struct c_expr expression;
8639 };
8640 
8641 /* Parse a generic-selection.  (C11 6.5.1.1).
8642 
8643    generic-selection:
8644      _Generic ( assignment-expression , generic-assoc-list )
8645 
8646    generic-assoc-list:
8647      generic-association
8648      generic-assoc-list , generic-association
8649 
8650    generic-association:
8651      type-name : assignment-expression
8652      default : assignment-expression
8653 */
8654 
8655 static struct c_expr
c_parser_generic_selection(c_parser * parser)8656 c_parser_generic_selection (c_parser *parser)
8657 {
8658   struct c_expr selector, error_expr;
8659   tree selector_type;
8660   struct c_generic_association matched_assoc;
8661   int match_found = -1;
8662   location_t generic_loc, selector_loc;
8663 
8664   error_expr.original_code = ERROR_MARK;
8665   error_expr.original_type = NULL;
8666   error_expr.set_error ();
8667   matched_assoc.type_location = UNKNOWN_LOCATION;
8668   matched_assoc.type = NULL_TREE;
8669   matched_assoc.expression = error_expr;
8670 
8671   gcc_assert (c_parser_next_token_is_keyword (parser, RID_GENERIC));
8672   generic_loc = c_parser_peek_token (parser)->location;
8673   c_parser_consume_token (parser);
8674   if (flag_isoc99)
8675     pedwarn_c99 (generic_loc, OPT_Wpedantic,
8676 		 "ISO C99 does not support %<_Generic%>");
8677   else
8678     pedwarn_c99 (generic_loc, OPT_Wpedantic,
8679 		 "ISO C90 does not support %<_Generic%>");
8680 
8681   matching_parens parens;
8682   if (!parens.require_open (parser))
8683     return error_expr;
8684 
8685   c_inhibit_evaluation_warnings++;
8686   selector_loc = c_parser_peek_token (parser)->location;
8687   selector = c_parser_expr_no_commas (parser, NULL);
8688   selector = default_function_array_conversion (selector_loc, selector);
8689   c_inhibit_evaluation_warnings--;
8690 
8691   if (selector.value == error_mark_node)
8692     {
8693       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8694       return selector;
8695     }
8696   mark_exp_read (selector.value);
8697   selector_type = TREE_TYPE (selector.value);
8698   /* In ISO C terms, rvalues (including the controlling expression of
8699      _Generic) do not have qualified types.  */
8700   if (TREE_CODE (selector_type) != ARRAY_TYPE)
8701     selector_type = TYPE_MAIN_VARIANT (selector_type);
8702   /* In ISO C terms, _Noreturn is not part of the type of expressions
8703      such as &abort, but in GCC it is represented internally as a type
8704      qualifier.  */
8705   if (FUNCTION_POINTER_TYPE_P (selector_type)
8706       && TYPE_QUALS (TREE_TYPE (selector_type)) != TYPE_UNQUALIFIED)
8707     selector_type
8708       = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type)));
8709 
8710   if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8711     {
8712       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8713       return error_expr;
8714     }
8715 
8716   auto_vec<c_generic_association> associations;
8717   while (1)
8718     {
8719       struct c_generic_association assoc, *iter;
8720       unsigned int ix;
8721       c_token *token = c_parser_peek_token (parser);
8722 
8723       assoc.type_location = token->location;
8724       if (token->type == CPP_KEYWORD && token->keyword == RID_DEFAULT)
8725 	{
8726 	  c_parser_consume_token (parser);
8727 	  assoc.type = NULL_TREE;
8728 	}
8729       else
8730 	{
8731 	  struct c_type_name *type_name;
8732 
8733 	  type_name = c_parser_type_name (parser);
8734 	  if (type_name == NULL)
8735 	    {
8736 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8737 	      return error_expr;
8738 	    }
8739 	  assoc.type = groktypename (type_name, NULL, NULL);
8740 	  if (assoc.type == error_mark_node)
8741 	    {
8742 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8743 	      return error_expr;
8744 	    }
8745 
8746 	  if (TREE_CODE (assoc.type) == FUNCTION_TYPE)
8747 	    error_at (assoc.type_location,
8748 		      "%<_Generic%> association has function type");
8749 	  else if (!COMPLETE_TYPE_P (assoc.type))
8750 	    error_at (assoc.type_location,
8751 		      "%<_Generic%> association has incomplete type");
8752 
8753 	  if (variably_modified_type_p (assoc.type, NULL_TREE))
8754 	    error_at (assoc.type_location,
8755 		      "%<_Generic%> association has "
8756 		      "variable length type");
8757 	}
8758 
8759       if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
8760 	{
8761 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8762 	  return error_expr;
8763 	}
8764 
8765       assoc.expression = c_parser_expr_no_commas (parser, NULL);
8766       if (assoc.expression.value == error_mark_node)
8767 	{
8768 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8769 	  return error_expr;
8770 	}
8771 
8772       for (ix = 0; associations.iterate (ix, &iter); ++ix)
8773 	{
8774 	  if (assoc.type == NULL_TREE)
8775 	    {
8776 	      if (iter->type == NULL_TREE)
8777 		{
8778 		  error_at (assoc.type_location,
8779 			    "duplicate %<default%> case in %<_Generic%>");
8780 		  inform (iter->type_location, "original %<default%> is here");
8781 		}
8782 	    }
8783 	  else if (iter->type != NULL_TREE)
8784 	    {
8785 	      if (comptypes (assoc.type, iter->type))
8786 		{
8787 		  error_at (assoc.type_location,
8788 			    "%<_Generic%> specifies two compatible types");
8789 		  inform (iter->type_location, "compatible type is here");
8790 		}
8791 	    }
8792 	}
8793 
8794       if (assoc.type == NULL_TREE)
8795 	{
8796 	  if (match_found < 0)
8797 	    {
8798 	      matched_assoc = assoc;
8799 	      match_found = associations.length ();
8800 	    }
8801 	}
8802       else if (comptypes (assoc.type, selector_type))
8803 	{
8804 	  if (match_found < 0 || matched_assoc.type == NULL_TREE)
8805 	    {
8806 	      matched_assoc = assoc;
8807 	      match_found = associations.length ();
8808 	    }
8809 	  else
8810 	    {
8811 	      error_at (assoc.type_location,
8812 			"%<_Generic%> selector matches multiple associations");
8813 	      inform (matched_assoc.type_location,
8814 		      "other match is here");
8815 	    }
8816 	}
8817 
8818       associations.safe_push (assoc);
8819 
8820       if (c_parser_peek_token (parser)->type != CPP_COMMA)
8821 	break;
8822       c_parser_consume_token (parser);
8823     }
8824 
8825   unsigned int ix;
8826   struct c_generic_association *iter;
8827   FOR_EACH_VEC_ELT (associations, ix, iter)
8828     if (ix != (unsigned) match_found)
8829       mark_exp_read (iter->expression.value);
8830 
8831   if (!parens.require_close (parser))
8832     {
8833       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8834       return error_expr;
8835     }
8836 
8837   if (match_found < 0)
8838     {
8839       error_at (selector_loc, "%<_Generic%> selector of type %qT is not "
8840 		"compatible with any association",
8841 		selector_type);
8842       return error_expr;
8843     }
8844 
8845   return matched_assoc.expression;
8846 }
8847 
8848 /* Check the validity of a function pointer argument *EXPR (argument
8849    position POS) to __builtin_tgmath.  Return the number of function
8850    arguments if possibly valid; return 0 having reported an error if
8851    not valid.  */
8852 
8853 static unsigned int
check_tgmath_function(c_expr * expr,unsigned int pos)8854 check_tgmath_function (c_expr *expr, unsigned int pos)
8855 {
8856   tree type = TREE_TYPE (expr->value);
8857   if (!FUNCTION_POINTER_TYPE_P (type))
8858     {
8859       error_at (expr->get_location (),
8860 		"argument %u of %<__builtin_tgmath%> is not a function pointer",
8861 		pos);
8862       return 0;
8863     }
8864   type = TREE_TYPE (type);
8865   if (!prototype_p (type))
8866     {
8867       error_at (expr->get_location (),
8868 		"argument %u of %<__builtin_tgmath%> is unprototyped", pos);
8869       return 0;
8870     }
8871   if (stdarg_p (type))
8872     {
8873       error_at (expr->get_location (),
8874 		"argument %u of %<__builtin_tgmath%> has variable arguments",
8875 		pos);
8876       return 0;
8877     }
8878   unsigned int nargs = 0;
8879   function_args_iterator iter;
8880   tree t;
8881   FOREACH_FUNCTION_ARGS (type, t, iter)
8882     {
8883       if (t == void_type_node)
8884 	break;
8885       nargs++;
8886     }
8887   if (nargs == 0)
8888     {
8889       error_at (expr->get_location (),
8890 		"argument %u of %<__builtin_tgmath%> has no arguments", pos);
8891       return 0;
8892     }
8893   return nargs;
8894 }
8895 
8896 /* Ways in which a parameter or return value of a type-generic macro
8897    may vary between the different functions the macro may call.  */
8898 enum tgmath_parm_kind
8899   {
8900     tgmath_fixed, tgmath_real, tgmath_complex
8901   };
8902 
8903 /* Helper function for c_parser_postfix_expression.  Parse predefined
8904    identifiers.  */
8905 
8906 static struct c_expr
c_parser_predefined_identifier(c_parser * parser)8907 c_parser_predefined_identifier (c_parser *parser)
8908 {
8909   location_t loc = c_parser_peek_token (parser)->location;
8910   switch (c_parser_peek_token (parser)->keyword)
8911     {
8912     case RID_FUNCTION_NAME:
8913       pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
8914 	       "identifier", "__FUNCTION__");
8915       break;
8916     case RID_PRETTY_FUNCTION_NAME:
8917       pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
8918 	       "identifier", "__PRETTY_FUNCTION__");
8919       break;
8920     case RID_C99_FUNCTION_NAME:
8921       pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not support "
8922 		   "%<__func__%> predefined identifier");
8923       break;
8924     default:
8925       gcc_unreachable ();
8926     }
8927 
8928   struct c_expr expr;
8929   expr.original_code = ERROR_MARK;
8930   expr.original_type = NULL;
8931   expr.value = fname_decl (loc, c_parser_peek_token (parser)->keyword,
8932 			   c_parser_peek_token (parser)->value);
8933   set_c_expr_source_range (&expr, loc, loc);
8934   c_parser_consume_token (parser);
8935   return expr;
8936 }
8937 
8938 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
8939    C11 6.5.1-6.5.2).  Compound literals aren't handled here; callers have to
8940    call c_parser_postfix_expression_after_paren_type on encountering them.
8941 
8942    postfix-expression:
8943      primary-expression
8944      postfix-expression [ expression ]
8945      postfix-expression ( argument-expression-list[opt] )
8946      postfix-expression . identifier
8947      postfix-expression -> identifier
8948      postfix-expression ++
8949      postfix-expression --
8950      ( type-name ) { initializer-list }
8951      ( type-name ) { initializer-list , }
8952 
8953    argument-expression-list:
8954      argument-expression
8955      argument-expression-list , argument-expression
8956 
8957    primary-expression:
8958      identifier
8959      constant
8960      string-literal
8961      ( expression )
8962      generic-selection
8963 
8964    GNU extensions:
8965 
8966    primary-expression:
8967      __func__
8968        (treated as a keyword in GNU C)
8969      __FUNCTION__
8970      __PRETTY_FUNCTION__
8971      ( compound-statement )
8972      __builtin_va_arg ( assignment-expression , type-name )
8973      __builtin_offsetof ( type-name , offsetof-member-designator )
8974      __builtin_choose_expr ( assignment-expression ,
8975 			     assignment-expression ,
8976 			     assignment-expression )
8977      __builtin_types_compatible_p ( type-name , type-name )
8978      __builtin_tgmath ( expr-list )
8979      __builtin_complex ( assignment-expression , assignment-expression )
8980      __builtin_shuffle ( assignment-expression , assignment-expression )
8981      __builtin_shuffle ( assignment-expression ,
8982 			 assignment-expression ,
8983 			 assignment-expression, )
8984      __builtin_convertvector ( assignment-expression , type-name )
8985      __builtin_assoc_barrier ( assignment-expression )
8986 
8987    offsetof-member-designator:
8988      identifier
8989      offsetof-member-designator . identifier
8990      offsetof-member-designator [ expression ]
8991 
8992    Objective-C:
8993 
8994    primary-expression:
8995      [ objc-receiver objc-message-args ]
8996      @selector ( objc-selector-arg )
8997      @protocol ( identifier )
8998      @encode ( type-name )
8999      objc-string-literal
9000      Classname . identifier
9001 */
9002 
9003 static struct c_expr
c_parser_postfix_expression(c_parser * parser)9004 c_parser_postfix_expression (c_parser *parser)
9005 {
9006   struct c_expr expr, e1;
9007   struct c_type_name *t1, *t2;
9008   location_t loc = c_parser_peek_token (parser)->location;
9009   source_range tok_range = c_parser_peek_token (parser)->get_range ();
9010   expr.original_code = ERROR_MARK;
9011   expr.original_type = NULL;
9012   switch (c_parser_peek_token (parser)->type)
9013     {
9014     case CPP_NUMBER:
9015       expr.value = c_parser_peek_token (parser)->value;
9016       set_c_expr_source_range (&expr, tok_range);
9017       loc = c_parser_peek_token (parser)->location;
9018       c_parser_consume_token (parser);
9019       if (TREE_CODE (expr.value) == FIXED_CST
9020 	  && !targetm.fixed_point_supported_p ())
9021 	{
9022 	  error_at (loc, "fixed-point types not supported for this target");
9023 	  expr.set_error ();
9024 	}
9025       break;
9026     case CPP_CHAR:
9027     case CPP_CHAR16:
9028     case CPP_CHAR32:
9029     case CPP_UTF8CHAR:
9030     case CPP_WCHAR:
9031       expr.value = c_parser_peek_token (parser)->value;
9032       /* For the purpose of warning when a pointer is compared with
9033 	 a zero character constant.  */
9034       expr.original_type = char_type_node;
9035       set_c_expr_source_range (&expr, tok_range);
9036       c_parser_consume_token (parser);
9037       break;
9038     case CPP_STRING:
9039     case CPP_STRING16:
9040     case CPP_STRING32:
9041     case CPP_WSTRING:
9042     case CPP_UTF8STRING:
9043       expr = c_parser_string_literal (parser, parser->translate_strings_p,
9044 				      true);
9045       break;
9046     case CPP_OBJC_STRING:
9047       gcc_assert (c_dialect_objc ());
9048       expr.value
9049 	= objc_build_string_object (c_parser_peek_token (parser)->value);
9050       set_c_expr_source_range (&expr, tok_range);
9051       c_parser_consume_token (parser);
9052       break;
9053     case CPP_NAME:
9054       switch (c_parser_peek_token (parser)->id_kind)
9055 	{
9056 	case C_ID_ID:
9057 	  {
9058 	    tree id = c_parser_peek_token (parser)->value;
9059 	    c_parser_consume_token (parser);
9060 	    expr.value = build_external_ref (loc, id,
9061 					     (c_parser_peek_token (parser)->type
9062 					      == CPP_OPEN_PAREN),
9063 					     &expr.original_type);
9064 	    set_c_expr_source_range (&expr, tok_range);
9065 	    break;
9066 	  }
9067 	case C_ID_CLASSNAME:
9068 	  {
9069 	    /* Here we parse the Objective-C 2.0 Class.name dot
9070 	       syntax.  */
9071 	    tree class_name = c_parser_peek_token (parser)->value;
9072 	    tree component;
9073 	    c_parser_consume_token (parser);
9074 	    gcc_assert (c_dialect_objc ());
9075 	    if (!c_parser_require (parser, CPP_DOT, "expected %<.%>"))
9076 	      {
9077 		expr.set_error ();
9078 		break;
9079 	      }
9080 	    if (c_parser_next_token_is_not (parser, CPP_NAME))
9081 	      {
9082 		c_parser_error (parser, "expected identifier");
9083 		expr.set_error ();
9084 		break;
9085 	      }
9086 	    c_token *component_tok = c_parser_peek_token (parser);
9087 	    component = component_tok->value;
9088 	    location_t end_loc = component_tok->get_finish ();
9089 	    c_parser_consume_token (parser);
9090 	    expr.value = objc_build_class_component_ref (class_name,
9091 							 component);
9092 	    set_c_expr_source_range (&expr, loc, end_loc);
9093 	    break;
9094 	  }
9095 	default:
9096 	  c_parser_error (parser, "expected expression");
9097 	  expr.set_error ();
9098 	  break;
9099 	}
9100       break;
9101     case CPP_OPEN_PAREN:
9102       /* A parenthesized expression, statement expression or compound
9103 	 literal.  */
9104       if (c_parser_peek_2nd_token (parser)->type == CPP_OPEN_BRACE)
9105 	{
9106 	  /* A statement expression.  */
9107 	  tree stmt;
9108 	  location_t brace_loc;
9109 	  c_parser_consume_token (parser);
9110 	  brace_loc = c_parser_peek_token (parser)->location;
9111 	  c_parser_consume_token (parser);
9112 	  /* If we've not yet started the current function's statement list,
9113 	     or we're in the parameter scope of an old-style function
9114 	     declaration, statement expressions are not allowed.  */
9115 	  if (!building_stmt_list_p () || old_style_parameter_scope ())
9116 	    {
9117 	      error_at (loc, "braced-group within expression allowed "
9118 			"only inside a function");
9119 	      parser->error = true;
9120 	      c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
9121 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9122 	      expr.set_error ();
9123 	      break;
9124 	    }
9125 	  stmt = c_begin_stmt_expr ();
9126 	  c_parser_compound_statement_nostart (parser);
9127 	  location_t close_loc = c_parser_peek_token (parser)->location;
9128 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9129 				     "expected %<)%>");
9130 	  pedwarn (loc, OPT_Wpedantic,
9131 		   "ISO C forbids braced-groups within expressions");
9132 	  expr.value = c_finish_stmt_expr (brace_loc, stmt);
9133 	  set_c_expr_source_range (&expr, loc, close_loc);
9134 	  mark_exp_read (expr.value);
9135 	}
9136       else
9137 	{
9138 	  /* A parenthesized expression.  */
9139 	  location_t loc_open_paren = c_parser_peek_token (parser)->location;
9140 	  c_parser_consume_token (parser);
9141 	  expr = c_parser_expression (parser);
9142 	  if (TREE_CODE (expr.value) == MODIFY_EXPR)
9143 	    suppress_warning (expr.value, OPT_Wparentheses);
9144 	  if (expr.original_code != C_MAYBE_CONST_EXPR
9145 	      && expr.original_code != SIZEOF_EXPR)
9146 	    expr.original_code = ERROR_MARK;
9147 	  /* Remember that we saw ( ) around the sizeof.  */
9148 	  if (expr.original_code == SIZEOF_EXPR)
9149 	    expr.original_code = PAREN_SIZEOF_EXPR;
9150 	  /* Don't change EXPR.ORIGINAL_TYPE.  */
9151 	  location_t loc_close_paren = c_parser_peek_token (parser)->location;
9152 	  set_c_expr_source_range (&expr, loc_open_paren, loc_close_paren);
9153 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9154 				     "expected %<)%>", loc_open_paren);
9155 	}
9156       break;
9157     case CPP_KEYWORD:
9158       switch (c_parser_peek_token (parser)->keyword)
9159 	{
9160 	case RID_FUNCTION_NAME:
9161 	case RID_PRETTY_FUNCTION_NAME:
9162 	case RID_C99_FUNCTION_NAME:
9163 	  expr = c_parser_predefined_identifier (parser);
9164 	  break;
9165 	case RID_VA_ARG:
9166 	  {
9167 	    location_t start_loc = loc;
9168 	    c_parser_consume_token (parser);
9169 	    matching_parens parens;
9170 	    if (!parens.require_open (parser))
9171 	      {
9172 		expr.set_error ();
9173 		break;
9174 	      }
9175 	    e1 = c_parser_expr_no_commas (parser, NULL);
9176 	    mark_exp_read (e1.value);
9177 	    e1.value = c_fully_fold (e1.value, false, NULL);
9178 	    if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9179 	      {
9180 		c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9181 		expr.set_error ();
9182 		break;
9183 	      }
9184 	    loc = c_parser_peek_token (parser)->location;
9185 	    t1 = c_parser_type_name (parser);
9186 	    location_t end_loc = c_parser_peek_token (parser)->get_finish ();
9187 	    c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9188 				       "expected %<)%>");
9189 	    if (t1 == NULL)
9190 	      {
9191 		expr.set_error ();
9192 	      }
9193 	    else
9194 	      {
9195 		tree type_expr = NULL_TREE;
9196 		expr.value = c_build_va_arg (start_loc, e1.value, loc,
9197 					     groktypename (t1, &type_expr, NULL));
9198 		if (type_expr)
9199 		  {
9200 		    expr.value = build2 (C_MAYBE_CONST_EXPR,
9201 					 TREE_TYPE (expr.value), type_expr,
9202 					 expr.value);
9203 		    C_MAYBE_CONST_EXPR_NON_CONST (expr.value) = true;
9204 		  }
9205 		set_c_expr_source_range (&expr, start_loc, end_loc);
9206 	      }
9207 	  }
9208 	  break;
9209 	case RID_OFFSETOF:
9210 	  {
9211 	    c_parser_consume_token (parser);
9212 	    matching_parens parens;
9213 	    if (!parens.require_open (parser))
9214 	      {
9215 		expr.set_error ();
9216 		break;
9217 	      }
9218 	    t1 = c_parser_type_name (parser);
9219 	    if (t1 == NULL)
9220 	      parser->error = true;
9221 	    if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9222 	      gcc_assert (parser->error);
9223 	    if (parser->error)
9224 	      {
9225 		c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9226 		expr.set_error ();
9227 		break;
9228 	      }
9229 	    tree type = groktypename (t1, NULL, NULL);
9230 	    tree offsetof_ref;
9231 	    if (type == error_mark_node)
9232 	      offsetof_ref = error_mark_node;
9233 	    else
9234 	      {
9235 		offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
9236 		SET_EXPR_LOCATION (offsetof_ref, loc);
9237 	      }
9238 	    /* Parse the second argument to __builtin_offsetof.  We
9239 	       must have one identifier, and beyond that we want to
9240 	       accept sub structure and sub array references.  */
9241 	    if (c_parser_next_token_is (parser, CPP_NAME))
9242 	      {
9243 		c_token *comp_tok = c_parser_peek_token (parser);
9244 		offsetof_ref = build_component_ref
9245 		  (loc, offsetof_ref, comp_tok->value, comp_tok->location);
9246 		c_parser_consume_token (parser);
9247 		while (c_parser_next_token_is (parser, CPP_DOT)
9248 		       || c_parser_next_token_is (parser,
9249 						  CPP_OPEN_SQUARE)
9250 		       || c_parser_next_token_is (parser,
9251 						  CPP_DEREF))
9252 		  {
9253 		    if (c_parser_next_token_is (parser, CPP_DEREF))
9254 		      {
9255 			loc = c_parser_peek_token (parser)->location;
9256 			offsetof_ref = build_array_ref (loc,
9257 							offsetof_ref,
9258 							integer_zero_node);
9259 			goto do_dot;
9260 		      }
9261 		    else if (c_parser_next_token_is (parser, CPP_DOT))
9262 		      {
9263 		      do_dot:
9264 			c_parser_consume_token (parser);
9265 			if (c_parser_next_token_is_not (parser,
9266 							CPP_NAME))
9267 			  {
9268 			    c_parser_error (parser, "expected identifier");
9269 			    break;
9270 			  }
9271 			c_token *comp_tok = c_parser_peek_token (parser);
9272 			offsetof_ref = build_component_ref
9273 			  (loc, offsetof_ref, comp_tok->value,
9274 			   comp_tok->location);
9275 			c_parser_consume_token (parser);
9276 		      }
9277 		    else
9278 		      {
9279 			struct c_expr ce;
9280 			tree idx;
9281 			loc = c_parser_peek_token (parser)->location;
9282 			c_parser_consume_token (parser);
9283 			ce = c_parser_expression (parser);
9284 			ce = convert_lvalue_to_rvalue (loc, ce, false, false);
9285 			idx = ce.value;
9286 			idx = c_fully_fold (idx, false, NULL);
9287 			c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
9288 						   "expected %<]%>");
9289 			offsetof_ref = build_array_ref (loc, offsetof_ref, idx);
9290 		      }
9291 		  }
9292 	      }
9293 	    else
9294 	      c_parser_error (parser, "expected identifier");
9295 	    location_t end_loc = c_parser_peek_token (parser)->get_finish ();
9296 	    c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9297 				       "expected %<)%>");
9298 	    expr.value = fold_offsetof (offsetof_ref);
9299 	    set_c_expr_source_range (&expr, loc, end_loc);
9300 	  }
9301 	  break;
9302 	case RID_CHOOSE_EXPR:
9303 	  {
9304 	    vec<c_expr_t, va_gc> *cexpr_list;
9305 	    c_expr_t *e1_p, *e2_p, *e3_p;
9306 	    tree c;
9307 	    location_t close_paren_loc;
9308 
9309 	    c_parser_consume_token (parser);
9310 	    if (!c_parser_get_builtin_args (parser,
9311 					    "__builtin_choose_expr",
9312 					    &cexpr_list, true,
9313 					    &close_paren_loc))
9314 	      {
9315 		expr.set_error ();
9316 		break;
9317 	      }
9318 
9319 	    if (vec_safe_length (cexpr_list) != 3)
9320 	      {
9321 		error_at (loc, "wrong number of arguments to "
9322 			       "%<__builtin_choose_expr%>");
9323 		expr.set_error ();
9324 		break;
9325 	      }
9326 
9327 	    e1_p = &(*cexpr_list)[0];
9328 	    e2_p = &(*cexpr_list)[1];
9329 	    e3_p = &(*cexpr_list)[2];
9330 
9331 	    c = e1_p->value;
9332 	    mark_exp_read (e2_p->value);
9333 	    mark_exp_read (e3_p->value);
9334 	    if (TREE_CODE (c) != INTEGER_CST
9335 		|| !INTEGRAL_TYPE_P (TREE_TYPE (c)))
9336 	      error_at (loc,
9337 			"first argument to %<__builtin_choose_expr%> not"
9338 			" a constant");
9339 	    constant_expression_warning (c);
9340 	    expr = integer_zerop (c) ? *e3_p : *e2_p;
9341 	    set_c_expr_source_range (&expr, loc, close_paren_loc);
9342 	    break;
9343 	  }
9344 	case RID_TYPES_COMPATIBLE_P:
9345 	  {
9346 	    c_parser_consume_token (parser);
9347 	    matching_parens parens;
9348 	    if (!parens.require_open (parser))
9349 	      {
9350 		expr.set_error ();
9351 		break;
9352 	      }
9353 	    t1 = c_parser_type_name (parser);
9354 	    if (t1 == NULL)
9355 	      {
9356 		expr.set_error ();
9357 		break;
9358 	      }
9359 	    if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9360 	      {
9361 		c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9362 		expr.set_error ();
9363 		break;
9364 	      }
9365 	    t2 = c_parser_type_name (parser);
9366 	    if (t2 == NULL)
9367 	      {
9368 		expr.set_error ();
9369 		break;
9370 	      }
9371 	    location_t close_paren_loc = c_parser_peek_token (parser)->location;
9372 	    parens.skip_until_found_close (parser);
9373 	    tree e1, e2;
9374 	    e1 = groktypename (t1, NULL, NULL);
9375 	    e2 = groktypename (t2, NULL, NULL);
9376 	    if (e1 == error_mark_node || e2 == error_mark_node)
9377 	      {
9378 		expr.set_error ();
9379 		break;
9380 	      }
9381 
9382 	    e1 = TYPE_MAIN_VARIANT (e1);
9383 	    e2 = TYPE_MAIN_VARIANT (e2);
9384 
9385 	    expr.value
9386 	      = comptypes (e1, e2) ? integer_one_node : integer_zero_node;
9387 	    set_c_expr_source_range (&expr, loc, close_paren_loc);
9388 	  }
9389 	  break;
9390 	case RID_BUILTIN_TGMATH:
9391 	  {
9392 	    vec<c_expr_t, va_gc> *cexpr_list;
9393 	    location_t close_paren_loc;
9394 
9395 	    c_parser_consume_token (parser);
9396 	    if (!c_parser_get_builtin_args (parser,
9397 					    "__builtin_tgmath",
9398 					    &cexpr_list, false,
9399 					    &close_paren_loc))
9400 	      {
9401 		expr.set_error ();
9402 		break;
9403 	      }
9404 
9405 	    if (vec_safe_length (cexpr_list) < 3)
9406 	      {
9407 		error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9408 		expr.set_error ();
9409 		break;
9410 	      }
9411 
9412 	    unsigned int i;
9413 	    c_expr_t *p;
9414 	    FOR_EACH_VEC_ELT (*cexpr_list, i, p)
9415 	      *p = convert_lvalue_to_rvalue (loc, *p, true, true);
9416 	    unsigned int nargs = check_tgmath_function (&(*cexpr_list)[0], 1);
9417 	    if (nargs == 0)
9418 	      {
9419 		expr.set_error ();
9420 		break;
9421 	      }
9422 	    if (vec_safe_length (cexpr_list) < nargs)
9423 	      {
9424 		error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9425 		expr.set_error ();
9426 		break;
9427 	      }
9428 	    unsigned int num_functions = vec_safe_length (cexpr_list) - nargs;
9429 	    if (num_functions < 2)
9430 	      {
9431 		error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9432 		expr.set_error ();
9433 		break;
9434 	      }
9435 
9436 	    /* The first NUM_FUNCTIONS expressions are the function
9437 	       pointers.  The remaining NARGS expressions are the
9438 	       arguments that are to be passed to one of those
9439 	       functions, chosen following <tgmath.h> rules.  */
9440 	    for (unsigned int j = 1; j < num_functions; j++)
9441 	      {
9442 		unsigned int this_nargs
9443 		  = check_tgmath_function (&(*cexpr_list)[j], j + 1);
9444 		if (this_nargs == 0)
9445 		  {
9446 		    expr.set_error ();
9447 		    goto out;
9448 		  }
9449 		if (this_nargs != nargs)
9450 		  {
9451 		    error_at ((*cexpr_list)[j].get_location (),
9452 			      "argument %u of %<__builtin_tgmath%> has "
9453 			      "wrong number of arguments", j + 1);
9454 		    expr.set_error ();
9455 		    goto out;
9456 		  }
9457 	      }
9458 
9459 	    /* The functions all have the same number of arguments.
9460 	       Determine whether arguments and return types vary in
9461 	       ways permitted for <tgmath.h> functions.  */
9462 	    /* The first entry in each of these vectors is for the
9463 	       return type, subsequent entries for parameter
9464 	       types.  */
9465 	    auto_vec<enum tgmath_parm_kind> parm_kind (nargs + 1);
9466 	    auto_vec<tree> parm_first (nargs + 1);
9467 	    auto_vec<bool> parm_complex (nargs + 1);
9468 	    auto_vec<bool> parm_varies (nargs + 1);
9469 	    tree first_type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[0].value));
9470 	    tree first_ret = TYPE_MAIN_VARIANT (TREE_TYPE (first_type));
9471 	    parm_first.quick_push (first_ret);
9472 	    parm_complex.quick_push (TREE_CODE (first_ret) == COMPLEX_TYPE);
9473 	    parm_varies.quick_push (false);
9474 	    function_args_iterator iter;
9475 	    tree t;
9476 	    unsigned int argpos;
9477 	    FOREACH_FUNCTION_ARGS (first_type, t, iter)
9478 	      {
9479 		if (t == void_type_node)
9480 		  break;
9481 		parm_first.quick_push (TYPE_MAIN_VARIANT (t));
9482 		parm_complex.quick_push (TREE_CODE (t) == COMPLEX_TYPE);
9483 		parm_varies.quick_push (false);
9484 	      }
9485 	    for (unsigned int j = 1; j < num_functions; j++)
9486 	      {
9487 		tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9488 		tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
9489 		if (ret != parm_first[0])
9490 		  {
9491 		    parm_varies[0] = true;
9492 		    if (!SCALAR_FLOAT_TYPE_P (parm_first[0])
9493 			&& !COMPLEX_FLOAT_TYPE_P (parm_first[0]))
9494 		      {
9495 			error_at ((*cexpr_list)[0].get_location (),
9496 				  "invalid type-generic return type for "
9497 				  "argument %u of %<__builtin_tgmath%>",
9498 				  1);
9499 			expr.set_error ();
9500 			goto out;
9501 		      }
9502 		    if (!SCALAR_FLOAT_TYPE_P (ret)
9503 			&& !COMPLEX_FLOAT_TYPE_P (ret))
9504 		      {
9505 			error_at ((*cexpr_list)[j].get_location (),
9506 				  "invalid type-generic return type for "
9507 				  "argument %u of %<__builtin_tgmath%>",
9508 				  j + 1);
9509 			expr.set_error ();
9510 			goto out;
9511 		      }
9512 		  }
9513 		if (TREE_CODE (ret) == COMPLEX_TYPE)
9514 		  parm_complex[0] = true;
9515 		argpos = 1;
9516 		FOREACH_FUNCTION_ARGS (type, t, iter)
9517 		  {
9518 		    if (t == void_type_node)
9519 		      break;
9520 		    t = TYPE_MAIN_VARIANT (t);
9521 		    if (t != parm_first[argpos])
9522 		      {
9523 			parm_varies[argpos] = true;
9524 			if (!SCALAR_FLOAT_TYPE_P (parm_first[argpos])
9525 			    && !COMPLEX_FLOAT_TYPE_P (parm_first[argpos]))
9526 			  {
9527 			    error_at ((*cexpr_list)[0].get_location (),
9528 				      "invalid type-generic type for "
9529 				      "argument %u of argument %u of "
9530 				      "%<__builtin_tgmath%>", argpos, 1);
9531 			    expr.set_error ();
9532 			    goto out;
9533 			  }
9534 			if (!SCALAR_FLOAT_TYPE_P (t)
9535 			    && !COMPLEX_FLOAT_TYPE_P (t))
9536 			  {
9537 			    error_at ((*cexpr_list)[j].get_location (),
9538 				      "invalid type-generic type for "
9539 				      "argument %u of argument %u of "
9540 				      "%<__builtin_tgmath%>", argpos, j + 1);
9541 			    expr.set_error ();
9542 			    goto out;
9543 			  }
9544 		      }
9545 		    if (TREE_CODE (t) == COMPLEX_TYPE)
9546 		      parm_complex[argpos] = true;
9547 		    argpos++;
9548 		  }
9549 	      }
9550 	    enum tgmath_parm_kind max_variation = tgmath_fixed;
9551 	    for (unsigned int j = 0; j <= nargs; j++)
9552 	      {
9553 		enum tgmath_parm_kind this_kind;
9554 		if (parm_varies[j])
9555 		  {
9556 		    if (parm_complex[j])
9557 		      max_variation = this_kind = tgmath_complex;
9558 		    else
9559 		      {
9560 			this_kind = tgmath_real;
9561 			if (max_variation != tgmath_complex)
9562 			  max_variation = tgmath_real;
9563 		      }
9564 		  }
9565 		else
9566 		  this_kind = tgmath_fixed;
9567 		parm_kind.quick_push (this_kind);
9568 	      }
9569 	    if (max_variation == tgmath_fixed)
9570 	      {
9571 		error_at (loc, "function arguments of %<__builtin_tgmath%> "
9572 			  "all have the same type");
9573 		expr.set_error ();
9574 		break;
9575 	      }
9576 
9577 	    /* Identify a parameter (not the return type) that varies,
9578 	       including with complex types if any variation includes
9579 	       complex types; there must be at least one such
9580 	       parameter.  */
9581 	    unsigned int tgarg = 0;
9582 	    for (unsigned int j = 1; j <= nargs; j++)
9583 	      if (parm_kind[j] == max_variation)
9584 		{
9585 		  tgarg = j;
9586 		  break;
9587 		}
9588 	    if (tgarg == 0)
9589 	      {
9590 		error_at (loc, "function arguments of %<__builtin_tgmath%> "
9591 			  "lack type-generic parameter");
9592 		expr.set_error ();
9593 		break;
9594 	      }
9595 
9596 	    /* Determine the type of the relevant parameter for each
9597 	       function.  */
9598 	    auto_vec<tree> tg_type (num_functions);
9599 	    for (unsigned int j = 0; j < num_functions; j++)
9600 	      {
9601 		tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9602 		argpos = 1;
9603 		FOREACH_FUNCTION_ARGS (type, t, iter)
9604 		  {
9605 		    if (argpos == tgarg)
9606 		      {
9607 			tg_type.quick_push (TYPE_MAIN_VARIANT (t));
9608 			break;
9609 		      }
9610 		    argpos++;
9611 		  }
9612 	      }
9613 
9614 	    /* Verify that the corresponding types are different for
9615 	       all the listed functions.  Also determine whether all
9616 	       the types are complex, whether all the types are
9617 	       standard or binary, and whether all the types are
9618 	       decimal.  */
9619 	    bool all_complex = true;
9620 	    bool all_binary = true;
9621 	    bool all_decimal = true;
9622 	    hash_set<tree> tg_types;
9623 	    FOR_EACH_VEC_ELT (tg_type, i, t)
9624 	      {
9625 		if (TREE_CODE (t) == COMPLEX_TYPE)
9626 		  all_decimal = false;
9627 		else
9628 		  {
9629 		    all_complex = false;
9630 		    if (DECIMAL_FLOAT_TYPE_P (t))
9631 		      all_binary = false;
9632 		    else
9633 		      all_decimal = false;
9634 		  }
9635 		if (tg_types.add (t))
9636 		  {
9637 		    error_at ((*cexpr_list)[i].get_location (),
9638 			      "duplicate type-generic parameter type for "
9639 			      "function argument %u of %<__builtin_tgmath%>",
9640 			      i + 1);
9641 		    expr.set_error ();
9642 		    goto out;
9643 		  }
9644 	      }
9645 
9646 	    /* Verify that other parameters and the return type whose
9647 	       types vary have their types varying in the correct
9648 	       way.  */
9649 	    for (unsigned int j = 0; j < num_functions; j++)
9650 	      {
9651 		tree exp_type = tg_type[j];
9652 		tree exp_real_type = exp_type;
9653 		if (TREE_CODE (exp_type) == COMPLEX_TYPE)
9654 		  exp_real_type = TREE_TYPE (exp_type);
9655 		tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9656 		tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
9657 		if ((parm_kind[0] == tgmath_complex && ret != exp_type)
9658 		    || (parm_kind[0] == tgmath_real && ret != exp_real_type))
9659 		  {
9660 		    error_at ((*cexpr_list)[j].get_location (),
9661 			      "bad return type for function argument %u "
9662 			      "of %<__builtin_tgmath%>", j + 1);
9663 		    expr.set_error ();
9664 		    goto out;
9665 		  }
9666 		argpos = 1;
9667 		FOREACH_FUNCTION_ARGS (type, t, iter)
9668 		  {
9669 		    if (t == void_type_node)
9670 		      break;
9671 		    t = TYPE_MAIN_VARIANT (t);
9672 		    if ((parm_kind[argpos] == tgmath_complex
9673 			 && t != exp_type)
9674 			|| (parm_kind[argpos] == tgmath_real
9675 			    && t != exp_real_type))
9676 		      {
9677 			error_at ((*cexpr_list)[j].get_location (),
9678 				  "bad type for argument %u of "
9679 				  "function argument %u of "
9680 				  "%<__builtin_tgmath%>", argpos, j + 1);
9681 			expr.set_error ();
9682 			goto out;
9683 		      }
9684 		    argpos++;
9685 		  }
9686 	      }
9687 
9688 	    /* The functions listed are a valid set of functions for a
9689 	       <tgmath.h> macro to select between.  Identify the
9690 	       matching function, if any.  First, the argument types
9691 	       must be combined following <tgmath.h> rules.  Integer
9692 	       types are treated as _Decimal64 if any type-generic
9693 	       argument is decimal, or if the only alternatives for
9694 	       type-generic arguments are of decimal types, and are
9695 	       otherwise treated as double (or _Complex double for
9696 	       complex integer types, or _Float64 or _Complex _Float64
9697 	       if all the return types are the same _FloatN or
9698 	       _FloatNx type).  After that adjustment, types are
9699 	       combined following the usual arithmetic conversions.
9700 	       If the function only accepts complex arguments, a
9701 	       complex type is produced.  */
9702 	    bool arg_complex = all_complex;
9703 	    bool arg_binary = all_binary;
9704 	    bool arg_int_decimal = all_decimal;
9705 	    for (unsigned int j = 1; j <= nargs; j++)
9706 	      {
9707 		if (parm_kind[j] == tgmath_fixed)
9708 		  continue;
9709 		c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
9710 		tree type = TREE_TYPE (ce->value);
9711 		if (!INTEGRAL_TYPE_P (type)
9712 		    && !SCALAR_FLOAT_TYPE_P (type)
9713 		    && TREE_CODE (type) != COMPLEX_TYPE)
9714 		  {
9715 		    error_at (ce->get_location (),
9716 			      "invalid type of argument %u of type-generic "
9717 			      "function", j);
9718 		    expr.set_error ();
9719 		    goto out;
9720 		  }
9721 		if (DECIMAL_FLOAT_TYPE_P (type))
9722 		  {
9723 		    arg_int_decimal = true;
9724 		    if (all_complex)
9725 		      {
9726 			error_at (ce->get_location (),
9727 				  "decimal floating-point argument %u to "
9728 				  "complex-only type-generic function", j);
9729 			expr.set_error ();
9730 			goto out;
9731 		      }
9732 		    else if (all_binary)
9733 		      {
9734 			error_at (ce->get_location (),
9735 				  "decimal floating-point argument %u to "
9736 				  "binary-only type-generic function", j);
9737 			expr.set_error ();
9738 			goto out;
9739 		      }
9740 		    else if (arg_complex)
9741 		      {
9742 			error_at (ce->get_location (),
9743 				  "both complex and decimal floating-point "
9744 				  "arguments to type-generic function");
9745 			expr.set_error ();
9746 			goto out;
9747 		      }
9748 		    else if (arg_binary)
9749 		      {
9750 			error_at (ce->get_location (),
9751 				  "both binary and decimal floating-point "
9752 				  "arguments to type-generic function");
9753 			expr.set_error ();
9754 			goto out;
9755 		      }
9756 		  }
9757 		else if (TREE_CODE (type) == COMPLEX_TYPE)
9758 		  {
9759 		    arg_complex = true;
9760 		    if (COMPLEX_FLOAT_TYPE_P (type))
9761 		      arg_binary = true;
9762 		    if (all_decimal)
9763 		      {
9764 			error_at (ce->get_location (),
9765 				  "complex argument %u to "
9766 				  "decimal-only type-generic function", j);
9767 			expr.set_error ();
9768 			goto out;
9769 		      }
9770 		    else if (arg_int_decimal)
9771 		      {
9772 			error_at (ce->get_location (),
9773 				  "both complex and decimal floating-point "
9774 				  "arguments to type-generic function");
9775 			expr.set_error ();
9776 			goto out;
9777 		      }
9778 		  }
9779 		else if (SCALAR_FLOAT_TYPE_P (type))
9780 		  {
9781 		    arg_binary = true;
9782 		    if (all_decimal)
9783 		      {
9784 			error_at (ce->get_location (),
9785 				  "binary argument %u to "
9786 				  "decimal-only type-generic function", j);
9787 			expr.set_error ();
9788 			goto out;
9789 		      }
9790 		    else if (arg_int_decimal)
9791 		      {
9792 			error_at (ce->get_location (),
9793 				  "both binary and decimal floating-point "
9794 				  "arguments to type-generic function");
9795 			expr.set_error ();
9796 			goto out;
9797 		      }
9798 		  }
9799 	      }
9800 	    /* For a macro rounding its result to a narrower type, map
9801 	       integer types to _Float64 not double if the return type
9802 	       is a _FloatN or _FloatNx type.  */
9803 	    bool arg_int_float64 = false;
9804 	    if (parm_kind[0] == tgmath_fixed
9805 		&& SCALAR_FLOAT_TYPE_P (parm_first[0])
9806 		&& float64_type_node != NULL_TREE)
9807 	      for (unsigned int j = 0; j < NUM_FLOATN_NX_TYPES; j++)
9808 		if (parm_first[0] == FLOATN_TYPE_NODE (j))
9809 		  {
9810 		    arg_int_float64 = true;
9811 		    break;
9812 		  }
9813 	    tree arg_real = NULL_TREE;
9814 	    for (unsigned int j = 1; j <= nargs; j++)
9815 	      {
9816 		if (parm_kind[j] == tgmath_fixed)
9817 		  continue;
9818 		c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
9819 		tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ce->value));
9820 		if (TREE_CODE (type) == COMPLEX_TYPE)
9821 		  type = TREE_TYPE (type);
9822 		if (INTEGRAL_TYPE_P (type))
9823 		  type = (arg_int_decimal
9824 			  ? dfloat64_type_node
9825 			  : arg_int_float64
9826 			  ? float64_type_node
9827 			  : double_type_node);
9828 		if (arg_real == NULL_TREE)
9829 		  arg_real = type;
9830 		else
9831 		  arg_real = common_type (arg_real, type);
9832 		if (arg_real == error_mark_node)
9833 		  {
9834 		    expr.set_error ();
9835 		    goto out;
9836 		  }
9837 	      }
9838 	    tree arg_type = (arg_complex
9839 			     ? build_complex_type (arg_real)
9840 			     : arg_real);
9841 
9842 	    /* Look for a function to call with type-generic parameter
9843 	       type ARG_TYPE.  */
9844 	    c_expr_t *fn = NULL;
9845 	    for (unsigned int j = 0; j < num_functions; j++)
9846 	      {
9847 		if (tg_type[j] == arg_type)
9848 		  {
9849 		    fn = &(*cexpr_list)[j];
9850 		    break;
9851 		  }
9852 	      }
9853 	    if (fn == NULL
9854 		&& parm_kind[0] == tgmath_fixed
9855 		&& SCALAR_FLOAT_TYPE_P (parm_first[0]))
9856 	      {
9857 		/* Presume this is a macro that rounds its result to a
9858 		   narrower type, and look for the first function with
9859 		   at least the range and precision of the argument
9860 		   type.  */
9861 		for (unsigned int j = 0; j < num_functions; j++)
9862 		  {
9863 		    if (arg_complex
9864 			!= (TREE_CODE (tg_type[j]) == COMPLEX_TYPE))
9865 		      continue;
9866 		    tree real_tg_type = (arg_complex
9867 					 ? TREE_TYPE (tg_type[j])
9868 					 : tg_type[j]);
9869 		    if (DECIMAL_FLOAT_TYPE_P (arg_real)
9870 			!= DECIMAL_FLOAT_TYPE_P (real_tg_type))
9871 		      continue;
9872 		    scalar_float_mode arg_mode
9873 		      = SCALAR_FLOAT_TYPE_MODE (arg_real);
9874 		    scalar_float_mode tg_mode
9875 		      = SCALAR_FLOAT_TYPE_MODE (real_tg_type);
9876 		    const real_format *arg_fmt = REAL_MODE_FORMAT (arg_mode);
9877 		    const real_format *tg_fmt = REAL_MODE_FORMAT (tg_mode);
9878 		    if (arg_fmt->b == tg_fmt->b
9879 			&& arg_fmt->p <= tg_fmt->p
9880 			&& arg_fmt->emax <= tg_fmt->emax
9881 			&& (arg_fmt->emin - arg_fmt->p
9882 			    >= tg_fmt->emin - tg_fmt->p))
9883 		      {
9884 			fn = &(*cexpr_list)[j];
9885 			break;
9886 		      }
9887 		  }
9888 	      }
9889 	    if (fn == NULL)
9890 	      {
9891 		error_at (loc, "no matching function for type-generic call");
9892 		expr.set_error ();
9893 		break;
9894 	      }
9895 
9896 	    /* Construct a call to FN.  */
9897 	    vec<tree, va_gc> *args;
9898 	    vec_alloc (args, nargs);
9899 	    vec<tree, va_gc> *origtypes;
9900 	    vec_alloc (origtypes, nargs);
9901 	    auto_vec<location_t> arg_loc (nargs);
9902 	    for (unsigned int j = 0; j < nargs; j++)
9903 	      {
9904 		c_expr_t *ce = &(*cexpr_list)[num_functions + j];
9905 		args->quick_push (ce->value);
9906 		arg_loc.quick_push (ce->get_location ());
9907 		origtypes->quick_push (ce->original_type);
9908 	      }
9909 	    expr.value = c_build_function_call_vec (loc, arg_loc, fn->value,
9910 						    args, origtypes);
9911 	    set_c_expr_source_range (&expr, loc, close_paren_loc);
9912 	    break;
9913 	  }
9914 	case RID_BUILTIN_CALL_WITH_STATIC_CHAIN:
9915 	  {
9916 	    vec<c_expr_t, va_gc> *cexpr_list;
9917 	    c_expr_t *e2_p;
9918 	    tree chain_value;
9919 	    location_t close_paren_loc;
9920 
9921 	    c_parser_consume_token (parser);
9922 	    if (!c_parser_get_builtin_args (parser,
9923 					    "__builtin_call_with_static_chain",
9924 					    &cexpr_list, false,
9925 					    &close_paren_loc))
9926 	      {
9927 		expr.set_error ();
9928 		break;
9929 	      }
9930 	    if (vec_safe_length (cexpr_list) != 2)
9931 	      {
9932 		error_at (loc, "wrong number of arguments to "
9933 			       "%<__builtin_call_with_static_chain%>");
9934 		expr.set_error ();
9935 		break;
9936 	      }
9937 
9938 	    expr = (*cexpr_list)[0];
9939 	    e2_p = &(*cexpr_list)[1];
9940 	    *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
9941 	    chain_value = e2_p->value;
9942 	    mark_exp_read (chain_value);
9943 
9944 	    if (TREE_CODE (expr.value) != CALL_EXPR)
9945 	      error_at (loc, "first argument to "
9946 			"%<__builtin_call_with_static_chain%> "
9947 			"must be a call expression");
9948 	    else if (TREE_CODE (TREE_TYPE (chain_value)) != POINTER_TYPE)
9949 	      error_at (loc, "second argument to "
9950 			"%<__builtin_call_with_static_chain%> "
9951 			"must be a pointer type");
9952 	    else
9953 	      CALL_EXPR_STATIC_CHAIN (expr.value) = chain_value;
9954 	    set_c_expr_source_range (&expr, loc, close_paren_loc);
9955 	    break;
9956 	  }
9957 	case RID_BUILTIN_COMPLEX:
9958 	  {
9959 	    vec<c_expr_t, va_gc> *cexpr_list;
9960 	    c_expr_t *e1_p, *e2_p;
9961 	    location_t close_paren_loc;
9962 
9963 	    c_parser_consume_token (parser);
9964 	    if (!c_parser_get_builtin_args (parser,
9965 					    "__builtin_complex",
9966 					    &cexpr_list, false,
9967 					    &close_paren_loc))
9968 	      {
9969 		expr.set_error ();
9970 		break;
9971 	      }
9972 
9973 	    if (vec_safe_length (cexpr_list) != 2)
9974 	      {
9975 		error_at (loc, "wrong number of arguments to "
9976 			       "%<__builtin_complex%>");
9977 		expr.set_error ();
9978 		break;
9979 	      }
9980 
9981 	    e1_p = &(*cexpr_list)[0];
9982 	    e2_p = &(*cexpr_list)[1];
9983 
9984 	    *e1_p = convert_lvalue_to_rvalue (loc, *e1_p, true, true);
9985 	    if (TREE_CODE (e1_p->value) == EXCESS_PRECISION_EXPR)
9986 	      e1_p->value = convert (TREE_TYPE (e1_p->value),
9987 				     TREE_OPERAND (e1_p->value, 0));
9988 	    *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
9989 	    if (TREE_CODE (e2_p->value) == EXCESS_PRECISION_EXPR)
9990 	      e2_p->value = convert (TREE_TYPE (e2_p->value),
9991 				     TREE_OPERAND (e2_p->value, 0));
9992 	    if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
9993 		|| DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
9994 		|| !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p->value))
9995 		|| DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p->value)))
9996 	      {
9997 		error_at (loc, "%<__builtin_complex%> operand "
9998 			  "not of real binary floating-point type");
9999 		expr.set_error ();
10000 		break;
10001 	      }
10002 	    if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p->value))
10003 		!= TYPE_MAIN_VARIANT (TREE_TYPE (e2_p->value)))
10004 	      {
10005 		error_at (loc,
10006 			  "%<__builtin_complex%> operands of different types");
10007 		expr.set_error ();
10008 		break;
10009 	      }
10010 	    pedwarn_c90 (loc, OPT_Wpedantic,
10011 			 "ISO C90 does not support complex types");
10012 	    expr.value = build2_loc (loc, COMPLEX_EXPR,
10013 				     build_complex_type
10014 				     (TYPE_MAIN_VARIANT
10015 				      (TREE_TYPE (e1_p->value))),
10016 				     e1_p->value, e2_p->value);
10017 	    set_c_expr_source_range (&expr, loc, close_paren_loc);
10018 	    break;
10019 	  }
10020 	case RID_BUILTIN_SHUFFLE:
10021 	  {
10022 	    vec<c_expr_t, va_gc> *cexpr_list;
10023 	    unsigned int i;
10024 	    c_expr_t *p;
10025 	    location_t close_paren_loc;
10026 
10027 	    c_parser_consume_token (parser);
10028 	    if (!c_parser_get_builtin_args (parser,
10029 					    "__builtin_shuffle",
10030 					    &cexpr_list, false,
10031 					    &close_paren_loc))
10032 	      {
10033 		expr.set_error ();
10034 		break;
10035 	      }
10036 
10037 	    FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
10038 	      *p = convert_lvalue_to_rvalue (loc, *p, true, true);
10039 
10040 	    if (vec_safe_length (cexpr_list) == 2)
10041 	      expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
10042 						  NULL_TREE,
10043 						  (*cexpr_list)[1].value);
10044 
10045 	    else if (vec_safe_length (cexpr_list) == 3)
10046 	      expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
10047 						  (*cexpr_list)[1].value,
10048 						  (*cexpr_list)[2].value);
10049 	    else
10050 	      {
10051 		error_at (loc, "wrong number of arguments to "
10052 			       "%<__builtin_shuffle%>");
10053 		expr.set_error ();
10054 	      }
10055 	    set_c_expr_source_range (&expr, loc, close_paren_loc);
10056 	    break;
10057 	  }
10058 	case RID_BUILTIN_SHUFFLEVECTOR:
10059 	  {
10060 	    vec<c_expr_t, va_gc> *cexpr_list;
10061 	    unsigned int i;
10062 	    c_expr_t *p;
10063 	    location_t close_paren_loc;
10064 
10065 	    c_parser_consume_token (parser);
10066 	    if (!c_parser_get_builtin_args (parser,
10067 					    "__builtin_shufflevector",
10068 					    &cexpr_list, false,
10069 					    &close_paren_loc))
10070 	      {
10071 		expr.set_error ();
10072 		break;
10073 	      }
10074 
10075 	    FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
10076 	      *p = convert_lvalue_to_rvalue (loc, *p, true, true);
10077 
10078 	    if (vec_safe_length (cexpr_list) < 3)
10079 	      {
10080 		error_at (loc, "wrong number of arguments to "
10081 			       "%<__builtin_shuffle%>");
10082 		expr.set_error ();
10083 	      }
10084 	    else
10085 	      {
10086 		auto_vec<tree, 16> mask;
10087 		for (i = 2; i < cexpr_list->length (); ++i)
10088 		  mask.safe_push ((*cexpr_list)[i].value);
10089 		expr.value = c_build_shufflevector (loc, (*cexpr_list)[0].value,
10090 						    (*cexpr_list)[1].value,
10091 						    mask);
10092 	      }
10093 	    set_c_expr_source_range (&expr, loc, close_paren_loc);
10094 	    break;
10095 	  }
10096 	case RID_BUILTIN_CONVERTVECTOR:
10097 	  {
10098 	    location_t start_loc = loc;
10099 	    c_parser_consume_token (parser);
10100 	    matching_parens parens;
10101 	    if (!parens.require_open (parser))
10102 	      {
10103 		expr.set_error ();
10104 		break;
10105 	      }
10106 	    e1 = c_parser_expr_no_commas (parser, NULL);
10107 	    mark_exp_read (e1.value);
10108 	    if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10109 	      {
10110 		c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10111 		expr.set_error ();
10112 		break;
10113 	      }
10114 	    loc = c_parser_peek_token (parser)->location;
10115 	    t1 = c_parser_type_name (parser);
10116 	    location_t end_loc = c_parser_peek_token (parser)->get_finish ();
10117 	    c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10118 				       "expected %<)%>");
10119 	    if (t1 == NULL)
10120 	      expr.set_error ();
10121 	    else
10122 	      {
10123 		tree type_expr = NULL_TREE;
10124 		expr.value = c_build_vec_convert (start_loc, e1.value, loc,
10125 						  groktypename (t1, &type_expr,
10126 								NULL));
10127 		set_c_expr_source_range (&expr, start_loc, end_loc);
10128 	      }
10129 	  }
10130 	  break;
10131 	case RID_BUILTIN_ASSOC_BARRIER:
10132 	  {
10133 	    location_t start_loc = loc;
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 	    e1 = c_parser_expr_no_commas (parser, NULL);
10142 	    mark_exp_read (e1.value);
10143 	    location_t end_loc = c_parser_peek_token (parser)->get_finish ();
10144 	    parens.skip_until_found_close (parser);
10145 	    expr = parser_build_unary_op (loc, PAREN_EXPR, e1);
10146 	    set_c_expr_source_range (&expr, start_loc, end_loc);
10147 	  }
10148 	  break;
10149 	case RID_AT_SELECTOR:
10150 	  {
10151 	    gcc_assert (c_dialect_objc ());
10152 	    c_parser_consume_token (parser);
10153 	    matching_parens parens;
10154 	    if (!parens.require_open (parser))
10155 	      {
10156 		expr.set_error ();
10157 		break;
10158 	      }
10159 	    tree sel = c_parser_objc_selector_arg (parser);
10160 	    location_t close_loc = c_parser_peek_token (parser)->location;
10161 	    parens.skip_until_found_close (parser);
10162 	    expr.value = objc_build_selector_expr (loc, sel);
10163 	    set_c_expr_source_range (&expr, loc, close_loc);
10164 	  }
10165 	  break;
10166 	case RID_AT_PROTOCOL:
10167 	  {
10168 	    gcc_assert (c_dialect_objc ());
10169 	    c_parser_consume_token (parser);
10170 	    matching_parens parens;
10171 	    if (!parens.require_open (parser))
10172 	      {
10173 		expr.set_error ();
10174 		break;
10175 	      }
10176 	    if (c_parser_next_token_is_not (parser, CPP_NAME))
10177 	      {
10178 		c_parser_error (parser, "expected identifier");
10179 		c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10180 		expr.set_error ();
10181 		break;
10182 	      }
10183 	    tree id = c_parser_peek_token (parser)->value;
10184 	    c_parser_consume_token (parser);
10185 	    location_t close_loc = c_parser_peek_token (parser)->location;
10186 	    parens.skip_until_found_close (parser);
10187 	    expr.value = objc_build_protocol_expr (id);
10188 	    set_c_expr_source_range (&expr, loc, close_loc);
10189 	  }
10190 	  break;
10191 	case RID_AT_ENCODE:
10192 	  {
10193 	    /* Extension to support C-structures in the archiver.  */
10194 	    gcc_assert (c_dialect_objc ());
10195 	    c_parser_consume_token (parser);
10196 	    matching_parens parens;
10197 	    if (!parens.require_open (parser))
10198 	      {
10199 		expr.set_error ();
10200 		break;
10201 	      }
10202 	    t1 = c_parser_type_name (parser);
10203 	    if (t1 == NULL)
10204 	      {
10205 		expr.set_error ();
10206 		c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10207 		break;
10208 	      }
10209 	    location_t close_loc = c_parser_peek_token (parser)->location;
10210 	    parens.skip_until_found_close (parser);
10211 	    tree type = groktypename (t1, NULL, NULL);
10212 	    expr.value = objc_build_encode_expr (type);
10213 	    set_c_expr_source_range (&expr, loc, close_loc);
10214 	  }
10215 	  break;
10216 	case RID_GENERIC:
10217 	  expr = c_parser_generic_selection (parser);
10218 	  break;
10219 	default:
10220 	  c_parser_error (parser, "expected expression");
10221 	  expr.set_error ();
10222 	  break;
10223 	}
10224       break;
10225     case CPP_OPEN_SQUARE:
10226       if (c_dialect_objc ())
10227 	{
10228 	  tree receiver, args;
10229 	  c_parser_consume_token (parser);
10230 	  receiver = c_parser_objc_receiver (parser);
10231 	  args = c_parser_objc_message_args (parser);
10232 	  location_t close_loc = c_parser_peek_token (parser)->location;
10233 	  c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10234 				     "expected %<]%>");
10235 	  expr.value = objc_build_message_expr (receiver, args);
10236 	  set_c_expr_source_range (&expr, loc, close_loc);
10237 	  break;
10238 	}
10239       /* Else fall through to report error.  */
10240       /* FALLTHRU */
10241     default:
10242       c_parser_error (parser, "expected expression");
10243       expr.set_error ();
10244       break;
10245     }
10246  out:
10247   return c_parser_postfix_expression_after_primary
10248     (parser, EXPR_LOC_OR_LOC (expr.value, loc), expr);
10249 }
10250 
10251 /* Parse a postfix expression after a parenthesized type name: the
10252    brace-enclosed initializer of a compound literal, possibly followed
10253    by some postfix operators.  This is separate because it is not
10254    possible to tell until after the type name whether a cast
10255    expression has a cast or a compound literal, or whether the operand
10256    of sizeof is a parenthesized type name or starts with a compound
10257    literal.  TYPE_LOC is the location where TYPE_NAME starts--the
10258    location of the first token after the parentheses around the type
10259    name.  */
10260 
10261 static struct c_expr
c_parser_postfix_expression_after_paren_type(c_parser * parser,struct c_type_name * type_name,location_t type_loc)10262 c_parser_postfix_expression_after_paren_type (c_parser *parser,
10263 					      struct c_type_name *type_name,
10264 					      location_t type_loc)
10265 {
10266   tree type;
10267   struct c_expr init;
10268   bool non_const;
10269   struct c_expr expr;
10270   location_t start_loc;
10271   tree type_expr = NULL_TREE;
10272   bool type_expr_const = true;
10273   check_compound_literal_type (type_loc, type_name);
10274   rich_location richloc (line_table, type_loc);
10275   start_init (NULL_TREE, NULL, 0, &richloc);
10276   type = groktypename (type_name, &type_expr, &type_expr_const);
10277   start_loc = c_parser_peek_token (parser)->location;
10278   if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type))
10279     {
10280       error_at (type_loc, "compound literal has variable size");
10281       type = error_mark_node;
10282     }
10283   init = c_parser_braced_init (parser, type, false, NULL);
10284   finish_init ();
10285   maybe_warn_string_init (type_loc, type, init);
10286 
10287   if (type != error_mark_node
10288       && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type))
10289       && current_function_decl)
10290     {
10291       error ("compound literal qualified by address-space qualifier");
10292       type = error_mark_node;
10293     }
10294 
10295   pedwarn_c90 (start_loc, OPT_Wpedantic, "ISO C90 forbids compound literals");
10296   non_const = ((init.value && TREE_CODE (init.value) == CONSTRUCTOR)
10297 	       ? CONSTRUCTOR_NON_CONST (init.value)
10298 	       : init.original_code == C_MAYBE_CONST_EXPR);
10299   non_const |= !type_expr_const;
10300   unsigned int alignas_align = 0;
10301   if (type != error_mark_node
10302       && type_name->specs->align_log != -1)
10303     {
10304       alignas_align = 1U << type_name->specs->align_log;
10305       if (alignas_align < min_align_of_type (type))
10306 	{
10307 	  error_at (type_name->specs->locations[cdw_alignas],
10308 		    "%<_Alignas%> specifiers cannot reduce "
10309 		    "alignment of compound literal");
10310 	  alignas_align = 0;
10311 	}
10312     }
10313   expr.value = build_compound_literal (start_loc, type, init.value, non_const,
10314 				       alignas_align);
10315   set_c_expr_source_range (&expr, init.src_range);
10316   expr.original_code = ERROR_MARK;
10317   expr.original_type = NULL;
10318   if (type != error_mark_node
10319       && expr.value != error_mark_node
10320       && type_expr)
10321     {
10322       if (TREE_CODE (expr.value) == C_MAYBE_CONST_EXPR)
10323 	{
10324 	  gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr.value) == NULL_TREE);
10325 	  C_MAYBE_CONST_EXPR_PRE (expr.value) = type_expr;
10326 	}
10327       else
10328 	{
10329 	  gcc_assert (!non_const);
10330 	  expr.value = build2 (C_MAYBE_CONST_EXPR, type,
10331 			       type_expr, expr.value);
10332 	}
10333     }
10334   return c_parser_postfix_expression_after_primary (parser, start_loc, expr);
10335 }
10336 
10337 /* Callback function for sizeof_pointer_memaccess_warning to compare
10338    types.  */
10339 
10340 static bool
sizeof_ptr_memacc_comptypes(tree type1,tree type2)10341 sizeof_ptr_memacc_comptypes (tree type1, tree type2)
10342 {
10343   return comptypes (type1, type2) == 1;
10344 }
10345 
10346 /* Warn for patterns where abs-like function appears to be used incorrectly,
10347    gracefully ignore any non-abs-like function.  The warning location should
10348    be LOC.  FNDECL is the declaration of called function, it must be a
10349    BUILT_IN_NORMAL function.  ARG is the first and only argument of the
10350    call.  */
10351 
10352 static void
warn_for_abs(location_t loc,tree fndecl,tree arg)10353 warn_for_abs (location_t loc, tree fndecl, tree arg)
10354 {
10355   /* Avoid warning in unreachable subexpressions.  */
10356   if (c_inhibit_evaluation_warnings)
10357     return;
10358 
10359   tree atype = TREE_TYPE (arg);
10360 
10361   /* Casts from pointers (and thus arrays and fndecls) will generate
10362      -Wint-conversion warnings.  Most other wrong types hopefully lead to type
10363      mismatch errors.  TODO: Think about what to do with FIXED_POINT_TYPE_P
10364      types and possibly other exotic types.  */
10365   if (!INTEGRAL_TYPE_P (atype)
10366       && !SCALAR_FLOAT_TYPE_P (atype)
10367       && TREE_CODE (atype) != COMPLEX_TYPE)
10368     return;
10369 
10370   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10371 
10372   switch (fcode)
10373     {
10374     case BUILT_IN_ABS:
10375     case BUILT_IN_LABS:
10376     case BUILT_IN_LLABS:
10377     case BUILT_IN_IMAXABS:
10378       if (!INTEGRAL_TYPE_P (atype))
10379 	{
10380 	  if (SCALAR_FLOAT_TYPE_P (atype))
10381 	    warning_at (loc, OPT_Wabsolute_value,
10382 			"using integer absolute value function %qD when "
10383 			"argument is of floating-point type %qT",
10384 			fndecl, atype);
10385 	  else if (TREE_CODE (atype) == COMPLEX_TYPE)
10386 	    warning_at (loc, OPT_Wabsolute_value,
10387 			"using integer absolute value function %qD when "
10388 			"argument is of complex type %qT", fndecl, atype);
10389 	  else
10390 	    gcc_unreachable ();
10391 	  return;
10392 	}
10393       if (TYPE_UNSIGNED (atype))
10394 	warning_at (loc, OPT_Wabsolute_value,
10395 		    "taking the absolute value of unsigned type %qT "
10396 		    "has no effect", atype);
10397       break;
10398 
10399     CASE_FLT_FN (BUILT_IN_FABS):
10400     CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS):
10401       if (!SCALAR_FLOAT_TYPE_P (atype)
10402 	  || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype)))
10403 	{
10404 	  if (INTEGRAL_TYPE_P (atype))
10405 	    warning_at (loc, OPT_Wabsolute_value,
10406 			"using floating-point absolute value function %qD "
10407 			"when argument is of integer type %qT", fndecl, atype);
10408 	  else if (DECIMAL_FLOAT_TYPE_P (atype))
10409 	    warning_at (loc, OPT_Wabsolute_value,
10410 			"using floating-point absolute value function %qD "
10411 			"when argument is of decimal floating-point type %qT",
10412 			fndecl, atype);
10413 	  else if (TREE_CODE (atype) == COMPLEX_TYPE)
10414 	    warning_at (loc, OPT_Wabsolute_value,
10415 			"using floating-point absolute value function %qD when "
10416 			"argument is of complex type %qT", fndecl, atype);
10417 	  else
10418 	    gcc_unreachable ();
10419 	  return;
10420 	}
10421       break;
10422 
10423     CASE_FLT_FN (BUILT_IN_CABS):
10424       if (TREE_CODE (atype) != COMPLEX_TYPE)
10425 	{
10426 	  if (INTEGRAL_TYPE_P (atype))
10427 	    warning_at (loc, OPT_Wabsolute_value,
10428 			"using complex absolute value function %qD when "
10429 			"argument is of integer type %qT", fndecl, atype);
10430 	  else if (SCALAR_FLOAT_TYPE_P (atype))
10431 	    warning_at (loc, OPT_Wabsolute_value,
10432 			"using complex absolute value function %qD when "
10433 			"argument is of floating-point type %qT",
10434 			fndecl, atype);
10435 	  else
10436 	    gcc_unreachable ();
10437 
10438 	  return;
10439 	}
10440       break;
10441 
10442     case BUILT_IN_FABSD32:
10443     case BUILT_IN_FABSD64:
10444     case BUILT_IN_FABSD128:
10445       if (!DECIMAL_FLOAT_TYPE_P (atype))
10446 	{
10447 	  if (INTEGRAL_TYPE_P (atype))
10448 	    warning_at (loc, OPT_Wabsolute_value,
10449 			"using decimal floating-point absolute value "
10450 			"function %qD when argument is of integer type %qT",
10451 			fndecl, atype);
10452 	  else if (SCALAR_FLOAT_TYPE_P (atype))
10453 	    warning_at (loc, OPT_Wabsolute_value,
10454 			"using decimal floating-point absolute value "
10455 			"function %qD when argument is of floating-point "
10456 			"type %qT", fndecl, atype);
10457 	  else if (TREE_CODE (atype) == COMPLEX_TYPE)
10458 	    warning_at (loc, OPT_Wabsolute_value,
10459 			"using decimal floating-point absolute value "
10460 			"function %qD when argument is of complex type %qT",
10461 			fndecl, atype);
10462 	  else
10463 	    gcc_unreachable ();
10464 	  return;
10465 	}
10466       break;
10467 
10468     default:
10469       return;
10470     }
10471 
10472   if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
10473     return;
10474 
10475   tree ftype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
10476   if (TREE_CODE (atype) == COMPLEX_TYPE)
10477     {
10478       gcc_assert (TREE_CODE (ftype) == COMPLEX_TYPE);
10479       atype = TREE_TYPE (atype);
10480       ftype = TREE_TYPE (ftype);
10481     }
10482 
10483   if (TYPE_PRECISION (ftype) < TYPE_PRECISION (atype))
10484     warning_at (loc, OPT_Wabsolute_value,
10485 		"absolute value function %qD given an argument of type %qT "
10486 		"but has parameter of type %qT which may cause truncation "
10487 		"of value", fndecl, atype, ftype);
10488 }
10489 
10490 
10491 /* Parse a postfix expression after the initial primary or compound
10492    literal; that is, parse a series of postfix operators.
10493 
10494    EXPR_LOC is the location of the primary expression.  */
10495 
10496 static struct c_expr
c_parser_postfix_expression_after_primary(c_parser * parser,location_t expr_loc,struct c_expr expr)10497 c_parser_postfix_expression_after_primary (c_parser *parser,
10498 					   location_t expr_loc,
10499 					   struct c_expr expr)
10500 {
10501   struct c_expr orig_expr;
10502   tree ident, idx;
10503   location_t sizeof_arg_loc[3], comp_loc;
10504   tree sizeof_arg[3];
10505   unsigned int literal_zero_mask;
10506   unsigned int i;
10507   vec<tree, va_gc> *exprlist;
10508   vec<tree, va_gc> *origtypes = NULL;
10509   vec<location_t> arg_loc = vNULL;
10510   location_t start;
10511   location_t finish;
10512 
10513   while (true)
10514     {
10515       location_t op_loc = c_parser_peek_token (parser)->location;
10516       switch (c_parser_peek_token (parser)->type)
10517 	{
10518 	case CPP_OPEN_SQUARE:
10519 	  /* Array reference.  */
10520 	  c_parser_consume_token (parser);
10521 	  idx = c_parser_expression (parser).value;
10522 	  c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10523 				     "expected %<]%>");
10524 	  start = expr.get_start ();
10525 	  finish = parser->tokens_buf[0].location;
10526 	  expr.value = build_array_ref (op_loc, expr.value, idx);
10527 	  set_c_expr_source_range (&expr, start, finish);
10528 	  expr.original_code = ERROR_MARK;
10529 	  expr.original_type = NULL;
10530 	  break;
10531 	case CPP_OPEN_PAREN:
10532 	  /* Function call.  */
10533 	  {
10534 	    matching_parens parens;
10535 	    parens.consume_open (parser);
10536 	    for (i = 0; i < 3; i++)
10537 	      {
10538 		sizeof_arg[i] = NULL_TREE;
10539 		sizeof_arg_loc[i] = UNKNOWN_LOCATION;
10540 	      }
10541 	    literal_zero_mask = 0;
10542 	    if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10543 	      exprlist = NULL;
10544 	    else
10545 	      exprlist = c_parser_expr_list (parser, true, false, &origtypes,
10546 					     sizeof_arg_loc, sizeof_arg,
10547 					     &arg_loc, &literal_zero_mask);
10548 	    parens.skip_until_found_close (parser);
10549 	  }
10550 	  orig_expr = expr;
10551 	  mark_exp_read (expr.value);
10552 	  if (warn_sizeof_pointer_memaccess)
10553 	    sizeof_pointer_memaccess_warning (sizeof_arg_loc,
10554 					      expr.value, exprlist,
10555 					      sizeof_arg,
10556 					      sizeof_ptr_memacc_comptypes);
10557 	  if (TREE_CODE (expr.value) == FUNCTION_DECL)
10558 	    {
10559 	      if (fndecl_built_in_p (expr.value, BUILT_IN_MEMSET)
10560 		  && vec_safe_length (exprlist) == 3)
10561 		{
10562 		  tree arg0 = (*exprlist)[0];
10563 		  tree arg2 = (*exprlist)[2];
10564 		  warn_for_memset (expr_loc, arg0, arg2, literal_zero_mask);
10565 		}
10566 	      if (warn_absolute_value
10567 		  && fndecl_built_in_p (expr.value, BUILT_IN_NORMAL)
10568 		  && vec_safe_length (exprlist) == 1)
10569 		warn_for_abs (expr_loc, expr.value, (*exprlist)[0]);
10570 	    }
10571 
10572 	  start = expr.get_start ();
10573 	  finish = parser->tokens_buf[0].get_finish ();
10574 	  expr.value
10575 	    = c_build_function_call_vec (expr_loc, arg_loc, expr.value,
10576 					 exprlist, origtypes);
10577 	  set_c_expr_source_range (&expr, start, finish);
10578 
10579 	  expr.original_code = ERROR_MARK;
10580 	  if (TREE_CODE (expr.value) == INTEGER_CST
10581 	      && TREE_CODE (orig_expr.value) == FUNCTION_DECL
10582 	      && fndecl_built_in_p (orig_expr.value, BUILT_IN_CONSTANT_P))
10583 	    expr.original_code = C_MAYBE_CONST_EXPR;
10584 	  expr.original_type = NULL;
10585 	  if (exprlist)
10586 	    {
10587 	      release_tree_vector (exprlist);
10588 	      release_tree_vector (origtypes);
10589 	    }
10590 	  arg_loc.release ();
10591 	  break;
10592 	case CPP_DOT:
10593 	  /* Structure element reference.  */
10594 	  c_parser_consume_token (parser);
10595 	  expr = default_function_array_conversion (expr_loc, expr);
10596 	  if (c_parser_next_token_is (parser, CPP_NAME))
10597 	    {
10598 	      c_token *comp_tok = c_parser_peek_token (parser);
10599 	      ident = comp_tok->value;
10600 	      comp_loc = comp_tok->location;
10601 	    }
10602 	  else
10603 	    {
10604 	      c_parser_error (parser, "expected identifier");
10605 	      expr.set_error ();
10606 	      expr.original_code = ERROR_MARK;
10607               expr.original_type = NULL;
10608 	      return expr;
10609 	    }
10610 	  start = expr.get_start ();
10611 	  finish = c_parser_peek_token (parser)->get_finish ();
10612 	  c_parser_consume_token (parser);
10613 	  expr.value = build_component_ref (op_loc, expr.value, ident,
10614 					    comp_loc);
10615 	  set_c_expr_source_range (&expr, start, finish);
10616 	  expr.original_code = ERROR_MARK;
10617 	  if (TREE_CODE (expr.value) != COMPONENT_REF)
10618 	    expr.original_type = NULL;
10619 	  else
10620 	    {
10621 	      /* Remember the original type of a bitfield.  */
10622 	      tree field = TREE_OPERAND (expr.value, 1);
10623 	      if (TREE_CODE (field) != FIELD_DECL)
10624 		expr.original_type = NULL;
10625 	      else
10626 		expr.original_type = DECL_BIT_FIELD_TYPE (field);
10627 	    }
10628 	  break;
10629 	case CPP_DEREF:
10630 	  /* Structure element reference.  */
10631 	  c_parser_consume_token (parser);
10632 	  expr = convert_lvalue_to_rvalue (expr_loc, expr, true, false);
10633 	  if (c_parser_next_token_is (parser, CPP_NAME))
10634 	    {
10635 	      c_token *comp_tok = c_parser_peek_token (parser);
10636 	      ident = comp_tok->value;
10637 	      comp_loc = comp_tok->location;
10638 	    }
10639 	  else
10640 	    {
10641 	      c_parser_error (parser, "expected identifier");
10642 	      expr.set_error ();
10643 	      expr.original_code = ERROR_MARK;
10644 	      expr.original_type = NULL;
10645 	      return expr;
10646 	    }
10647 	  start = expr.get_start ();
10648 	  finish = c_parser_peek_token (parser)->get_finish ();
10649 	  c_parser_consume_token (parser);
10650 	  expr.value = build_component_ref (op_loc,
10651 					    build_indirect_ref (op_loc,
10652 								expr.value,
10653 								RO_ARROW),
10654 					    ident, comp_loc);
10655 	  set_c_expr_source_range (&expr, start, finish);
10656 	  expr.original_code = ERROR_MARK;
10657 	  if (TREE_CODE (expr.value) != COMPONENT_REF)
10658 	    expr.original_type = NULL;
10659 	  else
10660 	    {
10661 	      /* Remember the original type of a bitfield.  */
10662 	      tree field = TREE_OPERAND (expr.value, 1);
10663 	      if (TREE_CODE (field) != FIELD_DECL)
10664 		expr.original_type = NULL;
10665 	      else
10666 		expr.original_type = DECL_BIT_FIELD_TYPE (field);
10667 	    }
10668 	  break;
10669 	case CPP_PLUS_PLUS:
10670 	  /* Postincrement.  */
10671 	  start = expr.get_start ();
10672 	  finish = c_parser_peek_token (parser)->get_finish ();
10673 	  c_parser_consume_token (parser);
10674 	  expr = default_function_array_read_conversion (expr_loc, expr);
10675 	  expr.value = build_unary_op (op_loc, POSTINCREMENT_EXPR,
10676 				       expr.value, false);
10677 	  set_c_expr_source_range (&expr, start, finish);
10678 	  expr.original_code = ERROR_MARK;
10679 	  expr.original_type = NULL;
10680 	  break;
10681 	case CPP_MINUS_MINUS:
10682 	  /* Postdecrement.  */
10683 	  start = expr.get_start ();
10684 	  finish = c_parser_peek_token (parser)->get_finish ();
10685 	  c_parser_consume_token (parser);
10686 	  expr = default_function_array_read_conversion (expr_loc, expr);
10687 	  expr.value = build_unary_op (op_loc, POSTDECREMENT_EXPR,
10688 				       expr.value, false);
10689 	  set_c_expr_source_range (&expr, start, finish);
10690 	  expr.original_code = ERROR_MARK;
10691 	  expr.original_type = NULL;
10692 	  break;
10693 	default:
10694 	  return expr;
10695 	}
10696     }
10697 }
10698 
10699 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
10700 
10701    expression:
10702      assignment-expression
10703      expression , assignment-expression
10704 */
10705 
10706 static struct c_expr
c_parser_expression(c_parser * parser)10707 c_parser_expression (c_parser *parser)
10708 {
10709   location_t tloc = c_parser_peek_token (parser)->location;
10710   struct c_expr expr;
10711   expr = c_parser_expr_no_commas (parser, NULL);
10712   if (c_parser_next_token_is (parser, CPP_COMMA))
10713     expr = convert_lvalue_to_rvalue (tloc, expr, true, false);
10714   while (c_parser_next_token_is (parser, CPP_COMMA))
10715     {
10716       struct c_expr next;
10717       tree lhsval;
10718       location_t loc = c_parser_peek_token (parser)->location;
10719       location_t expr_loc;
10720       c_parser_consume_token (parser);
10721       expr_loc = c_parser_peek_token (parser)->location;
10722       lhsval = expr.value;
10723       while (TREE_CODE (lhsval) == COMPOUND_EXPR
10724 	     || TREE_CODE (lhsval) == NOP_EXPR)
10725 	{
10726 	  if (TREE_CODE (lhsval) == COMPOUND_EXPR)
10727 	    lhsval = TREE_OPERAND (lhsval, 1);
10728 	  else
10729 	    lhsval = TREE_OPERAND (lhsval, 0);
10730 	}
10731       if (DECL_P (lhsval) || handled_component_p (lhsval))
10732 	mark_exp_read (lhsval);
10733       next = c_parser_expr_no_commas (parser, NULL);
10734       next = convert_lvalue_to_rvalue (expr_loc, next, true, false);
10735       expr.value = build_compound_expr (loc, expr.value, next.value);
10736       expr.original_code = COMPOUND_EXPR;
10737       expr.original_type = next.original_type;
10738     }
10739   return expr;
10740 }
10741 
10742 /* Parse an expression and convert functions or arrays to pointers and
10743    lvalues to rvalues.  */
10744 
10745 static struct c_expr
c_parser_expression_conv(c_parser * parser)10746 c_parser_expression_conv (c_parser *parser)
10747 {
10748   struct c_expr expr;
10749   location_t loc = c_parser_peek_token (parser)->location;
10750   expr = c_parser_expression (parser);
10751   expr = convert_lvalue_to_rvalue (loc, expr, true, false);
10752   return expr;
10753 }
10754 
10755 /* Helper function of c_parser_expr_list.  Check if IDXth (0 based)
10756    argument is a literal zero alone and if so, set it in literal_zero_mask.  */
10757 
10758 static inline void
c_parser_check_literal_zero(c_parser * parser,unsigned * literal_zero_mask,unsigned int idx)10759 c_parser_check_literal_zero (c_parser *parser, unsigned *literal_zero_mask,
10760 			     unsigned int idx)
10761 {
10762   if (idx >= HOST_BITS_PER_INT)
10763     return;
10764 
10765   c_token *tok = c_parser_peek_token (parser);
10766   switch (tok->type)
10767     {
10768     case CPP_NUMBER:
10769     case CPP_CHAR:
10770     case CPP_WCHAR:
10771     case CPP_CHAR16:
10772     case CPP_CHAR32:
10773     case CPP_UTF8CHAR:
10774       /* If a parameter is literal zero alone, remember it
10775 	 for -Wmemset-transposed-args warning.  */
10776       if (integer_zerop (tok->value)
10777 	  && !TREE_OVERFLOW (tok->value)
10778 	  && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
10779 	      || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
10780 	*literal_zero_mask |= 1U << idx;
10781     default:
10782       break;
10783     }
10784 }
10785 
10786 /* Parse a non-empty list of expressions.  If CONVERT_P, convert
10787    functions and arrays to pointers and lvalues to rvalues.  If
10788    FOLD_P, fold the expressions.  If LOCATIONS is non-NULL, save the
10789    locations of function arguments into this vector.
10790 
10791    nonempty-expr-list:
10792      assignment-expression
10793      nonempty-expr-list , assignment-expression
10794 */
10795 
10796 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)10797 c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
10798 		    vec<tree, va_gc> **p_orig_types,
10799 		    location_t *sizeof_arg_loc, tree *sizeof_arg,
10800 		    vec<location_t> *locations,
10801 		    unsigned int *literal_zero_mask)
10802 {
10803   vec<tree, va_gc> *ret;
10804   vec<tree, va_gc> *orig_types;
10805   struct c_expr expr;
10806   unsigned int idx = 0;
10807 
10808   ret = make_tree_vector ();
10809   if (p_orig_types == NULL)
10810     orig_types = NULL;
10811   else
10812     orig_types = make_tree_vector ();
10813 
10814   if (literal_zero_mask)
10815     c_parser_check_literal_zero (parser, literal_zero_mask, 0);
10816   expr = c_parser_expr_no_commas (parser, NULL);
10817   if (convert_p)
10818     expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true, true);
10819   if (fold_p)
10820     expr.value = c_fully_fold (expr.value, false, NULL);
10821   ret->quick_push (expr.value);
10822   if (orig_types)
10823     orig_types->quick_push (expr.original_type);
10824   if (locations)
10825     locations->safe_push (expr.get_location ());
10826   if (sizeof_arg != NULL
10827       && (expr.original_code == SIZEOF_EXPR
10828 	  || expr.original_code == PAREN_SIZEOF_EXPR))
10829     {
10830       sizeof_arg[0] = c_last_sizeof_arg;
10831       sizeof_arg_loc[0] = c_last_sizeof_loc;
10832     }
10833   while (c_parser_next_token_is (parser, CPP_COMMA))
10834     {
10835       c_parser_consume_token (parser);
10836       if (literal_zero_mask)
10837 	c_parser_check_literal_zero (parser, literal_zero_mask, idx + 1);
10838       expr = c_parser_expr_no_commas (parser, NULL);
10839       if (convert_p)
10840 	expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true,
10841 					 true);
10842       if (fold_p)
10843 	expr.value = c_fully_fold (expr.value, false, NULL);
10844       vec_safe_push (ret, expr.value);
10845       if (orig_types)
10846 	vec_safe_push (orig_types, expr.original_type);
10847       if (locations)
10848 	locations->safe_push (expr.get_location ());
10849       if (++idx < 3
10850 	  && sizeof_arg != NULL
10851 	  && (expr.original_code == SIZEOF_EXPR
10852 	      || expr.original_code == PAREN_SIZEOF_EXPR))
10853 	{
10854 	  sizeof_arg[idx] = c_last_sizeof_arg;
10855 	  sizeof_arg_loc[idx] = c_last_sizeof_loc;
10856 	}
10857     }
10858   if (orig_types)
10859     *p_orig_types = orig_types;
10860   return ret;
10861 }
10862 
10863 /* Parse Objective-C-specific constructs.  */
10864 
10865 /* Parse an objc-class-definition.
10866 
10867    objc-class-definition:
10868      @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
10869        objc-class-instance-variables[opt] objc-methodprotolist @end
10870      @implementation identifier objc-superclass[opt]
10871        objc-class-instance-variables[opt]
10872      @interface identifier ( identifier ) objc-protocol-refs[opt]
10873        objc-methodprotolist @end
10874      @interface identifier ( ) objc-protocol-refs[opt]
10875        objc-methodprotolist @end
10876      @implementation identifier ( identifier )
10877 
10878    objc-superclass:
10879      : identifier
10880 
10881    "@interface identifier (" must start "@interface identifier (
10882    identifier ) ...": objc-methodprotolist in the first production may
10883    not start with a parenthesized identifier as a declarator of a data
10884    definition with no declaration specifiers if the objc-superclass,
10885    objc-protocol-refs and objc-class-instance-variables are omitted.  */
10886 
10887 static void
c_parser_objc_class_definition(c_parser * parser,tree attributes)10888 c_parser_objc_class_definition (c_parser *parser, tree attributes)
10889 {
10890   bool iface_p;
10891   tree id1;
10892   tree superclass;
10893   if (c_parser_next_token_is_keyword (parser, RID_AT_INTERFACE))
10894     iface_p = true;
10895   else if (c_parser_next_token_is_keyword (parser, RID_AT_IMPLEMENTATION))
10896     iface_p = false;
10897   else
10898     gcc_unreachable ();
10899 
10900   c_parser_consume_token (parser);
10901   if (c_parser_next_token_is_not (parser, CPP_NAME))
10902     {
10903       c_parser_error (parser, "expected identifier");
10904       return;
10905     }
10906   id1 = c_parser_peek_token (parser)->value;
10907   location_t loc1 = c_parser_peek_token (parser)->location;
10908   c_parser_consume_token (parser);
10909   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
10910     {
10911       /* We have a category or class extension.  */
10912       tree id2;
10913       tree proto = NULL_TREE;
10914       matching_parens parens;
10915       parens.consume_open (parser);
10916       if (c_parser_next_token_is_not (parser, CPP_NAME))
10917 	{
10918 	  if (iface_p && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10919 	    {
10920 	      /* We have a class extension.  */
10921 	      id2 = NULL_TREE;
10922 	    }
10923 	  else
10924 	    {
10925 	      c_parser_error (parser, "expected identifier or %<)%>");
10926 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10927 	      return;
10928 	    }
10929 	}
10930       else
10931 	{
10932 	  id2 = c_parser_peek_token (parser)->value;
10933 	  c_parser_consume_token (parser);
10934 	}
10935       parens.skip_until_found_close (parser);
10936       if (!iface_p)
10937 	{
10938 	  objc_start_category_implementation (id1, id2);
10939 	  return;
10940 	}
10941       if (c_parser_next_token_is (parser, CPP_LESS))
10942 	proto = c_parser_objc_protocol_refs (parser);
10943       objc_start_category_interface (id1, id2, proto, attributes);
10944       c_parser_objc_methodprotolist (parser);
10945       c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
10946       objc_finish_interface ();
10947       return;
10948     }
10949   if (c_parser_next_token_is (parser, CPP_COLON))
10950     {
10951       c_parser_consume_token (parser);
10952       if (c_parser_next_token_is_not (parser, CPP_NAME))
10953 	{
10954 	  c_parser_error (parser, "expected identifier");
10955 	  return;
10956 	}
10957       superclass = c_parser_peek_token (parser)->value;
10958       c_parser_consume_token (parser);
10959     }
10960   else
10961     superclass = NULL_TREE;
10962   if (iface_p)
10963     {
10964       tree proto = NULL_TREE;
10965       if (c_parser_next_token_is (parser, CPP_LESS))
10966 	proto = c_parser_objc_protocol_refs (parser);
10967       objc_start_class_interface (id1, loc1, superclass, proto, attributes);
10968     }
10969   else
10970     objc_start_class_implementation (id1, superclass);
10971   if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
10972     c_parser_objc_class_instance_variables (parser);
10973   if (iface_p)
10974     {
10975       objc_continue_interface ();
10976       c_parser_objc_methodprotolist (parser);
10977       c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
10978       objc_finish_interface ();
10979     }
10980   else
10981     {
10982       objc_continue_implementation ();
10983       return;
10984     }
10985 }
10986 
10987 /* Parse objc-class-instance-variables.
10988 
10989    objc-class-instance-variables:
10990      { objc-instance-variable-decl-list[opt] }
10991 
10992    objc-instance-variable-decl-list:
10993      objc-visibility-spec
10994      objc-instance-variable-decl ;
10995      ;
10996      objc-instance-variable-decl-list objc-visibility-spec
10997      objc-instance-variable-decl-list objc-instance-variable-decl ;
10998      objc-instance-variable-decl-list ;
10999 
11000    objc-visibility-spec:
11001      @private
11002      @protected
11003      @public
11004 
11005    objc-instance-variable-decl:
11006      struct-declaration
11007 */
11008 
11009 static void
c_parser_objc_class_instance_variables(c_parser * parser)11010 c_parser_objc_class_instance_variables (c_parser *parser)
11011 {
11012   gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
11013   c_parser_consume_token (parser);
11014   while (c_parser_next_token_is_not (parser, CPP_EOF))
11015     {
11016       tree decls;
11017       /* Parse any stray semicolon.  */
11018       if (c_parser_next_token_is (parser, CPP_SEMICOLON))
11019 	{
11020 	  pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11021 		   "extra semicolon");
11022 	  c_parser_consume_token (parser);
11023 	  continue;
11024 	}
11025       /* Stop if at the end of the instance variables.  */
11026       if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
11027 	{
11028 	  c_parser_consume_token (parser);
11029 	  break;
11030 	}
11031       /* Parse any objc-visibility-spec.  */
11032       if (c_parser_next_token_is_keyword (parser, RID_AT_PRIVATE))
11033 	{
11034 	  c_parser_consume_token (parser);
11035 	  objc_set_visibility (OBJC_IVAR_VIS_PRIVATE);
11036 	  continue;
11037 	}
11038       else if (c_parser_next_token_is_keyword (parser, RID_AT_PROTECTED))
11039 	{
11040 	  c_parser_consume_token (parser);
11041 	  objc_set_visibility (OBJC_IVAR_VIS_PROTECTED);
11042 	  continue;
11043 	}
11044       else if (c_parser_next_token_is_keyword (parser, RID_AT_PUBLIC))
11045 	{
11046 	  c_parser_consume_token (parser);
11047 	  objc_set_visibility (OBJC_IVAR_VIS_PUBLIC);
11048 	  continue;
11049 	}
11050       else if (c_parser_next_token_is_keyword (parser, RID_AT_PACKAGE))
11051 	{
11052 	  c_parser_consume_token (parser);
11053 	  objc_set_visibility (OBJC_IVAR_VIS_PACKAGE);
11054 	  continue;
11055 	}
11056       else if (c_parser_next_token_is (parser, CPP_PRAGMA))
11057 	{
11058 	  c_parser_pragma (parser, pragma_external, NULL);
11059 	  continue;
11060 	}
11061 
11062       /* Parse some comma-separated declarations.  */
11063       decls = c_parser_struct_declaration (parser);
11064       if (decls == NULL)
11065 	{
11066 	  /* There is a syntax error.  We want to skip the offending
11067 	     tokens up to the next ';' (included) or '}'
11068 	     (excluded).  */
11069 
11070 	  /* First, skip manually a ')' or ']'.  This is because they
11071 	     reduce the nesting level, so c_parser_skip_until_found()
11072 	     wouldn't be able to skip past them.  */
11073 	  c_token *token = c_parser_peek_token (parser);
11074 	  if (token->type == CPP_CLOSE_PAREN || token->type == CPP_CLOSE_SQUARE)
11075 	    c_parser_consume_token (parser);
11076 
11077 	  /* Then, do the standard skipping.  */
11078 	  c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11079 
11080 	  /* We hopefully recovered.  Start normal parsing again.  */
11081 	  parser->error = false;
11082 	  continue;
11083 	}
11084       else
11085 	{
11086 	  /* Comma-separated instance variables are chained together
11087 	     in reverse order; add them one by one.  */
11088 	  tree ivar = nreverse (decls);
11089 	  for (; ivar; ivar = DECL_CHAIN (ivar))
11090 	    objc_add_instance_variable (copy_node (ivar));
11091 	}
11092       c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11093     }
11094 }
11095 
11096 /* Parse an objc-class-declaration.
11097 
11098    objc-class-declaration:
11099      @class identifier-list ;
11100 */
11101 
11102 static void
c_parser_objc_class_declaration(c_parser * parser)11103 c_parser_objc_class_declaration (c_parser *parser)
11104 {
11105   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_CLASS));
11106   c_parser_consume_token (parser);
11107   /* Any identifiers, including those declared as type names, are OK
11108      here.  */
11109   while (true)
11110     {
11111       tree id;
11112       if (c_parser_next_token_is_not (parser, CPP_NAME))
11113 	{
11114 	  c_parser_error (parser, "expected identifier");
11115 	  c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11116 	  parser->error = false;
11117 	  return;
11118 	}
11119       id = c_parser_peek_token (parser)->value;
11120       objc_declare_class (id);
11121       c_parser_consume_token (parser);
11122       if (c_parser_next_token_is (parser, CPP_COMMA))
11123 	c_parser_consume_token (parser);
11124       else
11125 	break;
11126     }
11127   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11128 }
11129 
11130 /* Parse an objc-alias-declaration.
11131 
11132    objc-alias-declaration:
11133      @compatibility_alias identifier identifier ;
11134 */
11135 
11136 static void
c_parser_objc_alias_declaration(c_parser * parser)11137 c_parser_objc_alias_declaration (c_parser *parser)
11138 {
11139   tree id1, id2;
11140   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_ALIAS));
11141   c_parser_consume_token (parser);
11142   if (c_parser_next_token_is_not (parser, CPP_NAME))
11143     {
11144       c_parser_error (parser, "expected identifier");
11145       c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11146       return;
11147     }
11148   id1 = c_parser_peek_token (parser)->value;
11149   c_parser_consume_token (parser);
11150   if (c_parser_next_token_is_not (parser, CPP_NAME))
11151     {
11152       c_parser_error (parser, "expected identifier");
11153       c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11154       return;
11155     }
11156   id2 = c_parser_peek_token (parser)->value;
11157   c_parser_consume_token (parser);
11158   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11159   objc_declare_alias (id1, id2);
11160 }
11161 
11162 /* Parse an objc-protocol-definition.
11163 
11164    objc-protocol-definition:
11165      @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
11166      @protocol identifier-list ;
11167 
11168    "@protocol identifier ;" should be resolved as "@protocol
11169    identifier-list ;": objc-methodprotolist may not start with a
11170    semicolon in the first alternative if objc-protocol-refs are
11171    omitted.  */
11172 
11173 static void
c_parser_objc_protocol_definition(c_parser * parser,tree attributes)11174 c_parser_objc_protocol_definition (c_parser *parser, tree attributes)
11175 {
11176   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROTOCOL));
11177 
11178   c_parser_consume_token (parser);
11179   if (c_parser_next_token_is_not (parser, CPP_NAME))
11180     {
11181       c_parser_error (parser, "expected identifier");
11182       return;
11183     }
11184   if (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
11185       || c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON)
11186     {
11187       /* Any identifiers, including those declared as type names, are
11188 	 OK here.  */
11189       while (true)
11190 	{
11191 	  tree id;
11192 	  if (c_parser_next_token_is_not (parser, CPP_NAME))
11193 	    {
11194 	      c_parser_error (parser, "expected identifier");
11195 	      break;
11196 	    }
11197 	  id = c_parser_peek_token (parser)->value;
11198 	  objc_declare_protocol (id, attributes);
11199 	  c_parser_consume_token (parser);
11200 	  if (c_parser_next_token_is (parser, CPP_COMMA))
11201 	    c_parser_consume_token (parser);
11202 	  else
11203 	    break;
11204 	}
11205       c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11206     }
11207   else
11208     {
11209       tree id = c_parser_peek_token (parser)->value;
11210       tree proto = NULL_TREE;
11211       c_parser_consume_token (parser);
11212       if (c_parser_next_token_is (parser, CPP_LESS))
11213 	proto = c_parser_objc_protocol_refs (parser);
11214       parser->objc_pq_context = true;
11215       objc_start_protocol (id, proto, attributes);
11216       c_parser_objc_methodprotolist (parser);
11217       c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
11218       parser->objc_pq_context = false;
11219       objc_finish_interface ();
11220     }
11221 }
11222 
11223 /* Parse an objc-method-type.
11224 
11225    objc-method-type:
11226      +
11227      -
11228 
11229    Return true if it is a class method (+) and false if it is
11230    an instance method (-).
11231 */
11232 static inline bool
c_parser_objc_method_type(c_parser * parser)11233 c_parser_objc_method_type (c_parser *parser)
11234 {
11235   switch (c_parser_peek_token (parser)->type)
11236     {
11237     case CPP_PLUS:
11238       c_parser_consume_token (parser);
11239       return true;
11240     case CPP_MINUS:
11241       c_parser_consume_token (parser);
11242       return false;
11243     default:
11244       gcc_unreachable ();
11245     }
11246 }
11247 
11248 /* Parse an objc-method-definition.
11249 
11250    objc-method-definition:
11251      objc-method-type objc-method-decl ;[opt] compound-statement
11252 */
11253 
11254 static void
c_parser_objc_method_definition(c_parser * parser)11255 c_parser_objc_method_definition (c_parser *parser)
11256 {
11257   bool is_class_method = c_parser_objc_method_type (parser);
11258   tree decl, attributes = NULL_TREE, expr = NULL_TREE;
11259   parser->objc_pq_context = true;
11260   decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
11261 				    &expr);
11262   if (decl == error_mark_node)
11263     return;  /* Bail here. */
11264 
11265   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
11266     {
11267       c_parser_consume_token (parser);
11268       pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11269 	       "extra semicolon in method definition specified");
11270     }
11271 
11272   if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11273     {
11274       c_parser_error (parser, "expected %<{%>");
11275       return;
11276     }
11277 
11278   parser->objc_pq_context = false;
11279   if (objc_start_method_definition (is_class_method, decl, attributes, expr))
11280     {
11281       add_stmt (c_parser_compound_statement (parser));
11282       objc_finish_method_definition (current_function_decl);
11283     }
11284   else
11285     {
11286       /* This code is executed when we find a method definition
11287 	 outside of an @implementation context (or invalid for other
11288 	 reasons).  Parse the method (to keep going) but do not emit
11289 	 any code.
11290       */
11291       c_parser_compound_statement (parser);
11292     }
11293 }
11294 
11295 /* Parse an objc-methodprotolist.
11296 
11297    objc-methodprotolist:
11298      empty
11299      objc-methodprotolist objc-methodproto
11300      objc-methodprotolist declaration
11301      objc-methodprotolist ;
11302      @optional
11303      @required
11304 
11305    The declaration is a data definition, which may be missing
11306    declaration specifiers under the same rules and diagnostics as
11307    other data definitions outside functions, and the stray semicolon
11308    is diagnosed the same way as a stray semicolon outside a
11309    function.  */
11310 
11311 static void
c_parser_objc_methodprotolist(c_parser * parser)11312 c_parser_objc_methodprotolist (c_parser *parser)
11313 {
11314   while (true)
11315     {
11316       /* The list is terminated by @end.  */
11317       switch (c_parser_peek_token (parser)->type)
11318 	{
11319 	case CPP_SEMICOLON:
11320 	  pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11321 		   "ISO C does not allow extra %<;%> outside of a function");
11322 	  c_parser_consume_token (parser);
11323 	  break;
11324 	case CPP_PLUS:
11325 	case CPP_MINUS:
11326 	  c_parser_objc_methodproto (parser);
11327 	  break;
11328 	case CPP_PRAGMA:
11329 	  c_parser_pragma (parser, pragma_external, NULL);
11330 	  break;
11331 	case CPP_EOF:
11332 	  return;
11333 	default:
11334 	  if (c_parser_next_token_is_keyword (parser, RID_AT_END))
11335 	    return;
11336 	  else if (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY))
11337 	    c_parser_objc_at_property_declaration (parser);
11338 	  else if (c_parser_next_token_is_keyword (parser, RID_AT_OPTIONAL))
11339 	    {
11340 	      objc_set_method_opt (true);
11341 	      c_parser_consume_token (parser);
11342 	    }
11343 	  else if (c_parser_next_token_is_keyword (parser, RID_AT_REQUIRED))
11344 	    {
11345 	      objc_set_method_opt (false);
11346 	      c_parser_consume_token (parser);
11347 	    }
11348 	  else
11349 	    c_parser_declaration_or_fndef (parser, false, false, true,
11350 					   false, true);
11351 	  break;
11352 	}
11353     }
11354 }
11355 
11356 /* Parse an objc-methodproto.
11357 
11358    objc-methodproto:
11359      objc-method-type objc-method-decl ;
11360 */
11361 
11362 static void
c_parser_objc_methodproto(c_parser * parser)11363 c_parser_objc_methodproto (c_parser *parser)
11364 {
11365   bool is_class_method = c_parser_objc_method_type (parser);
11366   tree decl, attributes = NULL_TREE;
11367 
11368   /* Remember protocol qualifiers in prototypes.  */
11369   parser->objc_pq_context = true;
11370   decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
11371 				    NULL);
11372   /* Forget protocol qualifiers now.  */
11373   parser->objc_pq_context = false;
11374 
11375   /* Do not allow the presence of attributes to hide an erroneous
11376      method implementation in the interface section.  */
11377   if (!c_parser_next_token_is (parser, CPP_SEMICOLON))
11378     {
11379       c_parser_error (parser, "expected %<;%>");
11380       return;
11381     }
11382 
11383   if (decl != error_mark_node)
11384     objc_add_method_declaration (is_class_method, decl, attributes);
11385 
11386   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11387 }
11388 
11389 /* If we are at a position that method attributes may be present, check that
11390    there are not any parsed already (a syntax error) and then collect any
11391    specified at the current location.  Finally, if new attributes were present,
11392    check that the next token is legal ( ';' for decls and '{' for defs).  */
11393 
11394 static bool
c_parser_objc_maybe_method_attributes(c_parser * parser,tree * attributes)11395 c_parser_objc_maybe_method_attributes (c_parser* parser, tree* attributes)
11396 {
11397   bool bad = false;
11398   if (*attributes)
11399     {
11400       c_parser_error (parser,
11401 		    "method attributes must be specified at the end only");
11402       *attributes = NULL_TREE;
11403       bad = true;
11404     }
11405 
11406   if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
11407     *attributes = c_parser_gnu_attributes (parser);
11408 
11409   /* If there were no attributes here, just report any earlier error.  */
11410   if (*attributes == NULL_TREE || bad)
11411     return bad;
11412 
11413   /* If the attributes are followed by a ; or {, then just report any earlier
11414      error.  */
11415   if (c_parser_next_token_is (parser, CPP_SEMICOLON)
11416       || c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11417     return bad;
11418 
11419   /* We've got attributes, but not at the end.  */
11420   c_parser_error (parser,
11421 		  "expected %<;%> or %<{%> after method attribute definition");
11422   return true;
11423 }
11424 
11425 /* Parse an objc-method-decl.
11426 
11427    objc-method-decl:
11428      ( objc-type-name ) objc-selector
11429      objc-selector
11430      ( objc-type-name ) objc-keyword-selector objc-optparmlist
11431      objc-keyword-selector objc-optparmlist
11432      gnu-attributes
11433 
11434    objc-keyword-selector:
11435      objc-keyword-decl
11436      objc-keyword-selector objc-keyword-decl
11437 
11438    objc-keyword-decl:
11439      objc-selector : ( objc-type-name ) identifier
11440      objc-selector : identifier
11441      : ( objc-type-name ) identifier
11442      : identifier
11443 
11444    objc-optparmlist:
11445      objc-optparms objc-optellipsis
11446 
11447    objc-optparms:
11448      empty
11449      objc-opt-parms , parameter-declaration
11450 
11451    objc-optellipsis:
11452      empty
11453      , ...
11454 */
11455 
11456 static tree
c_parser_objc_method_decl(c_parser * parser,bool is_class_method,tree * attributes,tree * expr)11457 c_parser_objc_method_decl (c_parser *parser, bool is_class_method,
11458 			   tree *attributes, tree *expr)
11459 {
11460   tree type = NULL_TREE;
11461   tree sel;
11462   tree parms = NULL_TREE;
11463   bool ellipsis = false;
11464   bool attr_err = false;
11465 
11466   *attributes = NULL_TREE;
11467   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11468     {
11469       matching_parens parens;
11470       parens.consume_open (parser);
11471       type = c_parser_objc_type_name (parser);
11472       parens.skip_until_found_close (parser);
11473     }
11474   sel = c_parser_objc_selector (parser);
11475   /* If there is no selector, or a colon follows, we have an
11476      objc-keyword-selector.  If there is a selector, and a colon does
11477      not follow, that selector ends the objc-method-decl.  */
11478   if (!sel || c_parser_next_token_is (parser, CPP_COLON))
11479     {
11480       tree tsel = sel;
11481       tree list = NULL_TREE;
11482       while (true)
11483 	{
11484 	  tree atype = NULL_TREE, id, keyworddecl;
11485 	  tree param_attr = NULL_TREE;
11486 	  if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11487 	    break;
11488 	  if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11489 	    {
11490 	      c_parser_consume_token (parser);
11491 	      atype = c_parser_objc_type_name (parser);
11492 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
11493 					 "expected %<)%>");
11494 	    }
11495 	  /* New ObjC allows attributes on method parameters.  */
11496 	  if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
11497 	    param_attr = c_parser_gnu_attributes (parser);
11498 	  if (c_parser_next_token_is_not (parser, CPP_NAME))
11499 	    {
11500 	      c_parser_error (parser, "expected identifier");
11501 	      return error_mark_node;
11502 	    }
11503 	  id = c_parser_peek_token (parser)->value;
11504 	  c_parser_consume_token (parser);
11505 	  keyworddecl = objc_build_keyword_decl (tsel, atype, id, param_attr);
11506 	  list = chainon (list, keyworddecl);
11507 	  tsel = c_parser_objc_selector (parser);
11508 	  if (!tsel && c_parser_next_token_is_not (parser, CPP_COLON))
11509 	    break;
11510 	}
11511 
11512       attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
11513 
11514       /* Parse the optional parameter list.  Optional Objective-C
11515 	 method parameters follow the C syntax, and may include '...'
11516 	 to denote a variable number of arguments.  */
11517       parms = make_node (TREE_LIST);
11518       while (c_parser_next_token_is (parser, CPP_COMMA))
11519 	{
11520 	  struct c_parm *parm;
11521 	  c_parser_consume_token (parser);
11522 	  if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
11523 	    {
11524 	      ellipsis = true;
11525 	      c_parser_consume_token (parser);
11526 	      attr_err |= c_parser_objc_maybe_method_attributes
11527 						(parser, attributes) ;
11528 	      break;
11529 	    }
11530 	  parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
11531 	  if (parm == NULL)
11532 	    break;
11533 	  parms = chainon (parms,
11534 			   build_tree_list (NULL_TREE, grokparm (parm, expr)));
11535 	}
11536       sel = list;
11537     }
11538   else
11539     attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
11540 
11541   if (sel == NULL)
11542     {
11543       c_parser_error (parser, "objective-c method declaration is expected");
11544       return error_mark_node;
11545     }
11546 
11547   if (attr_err)
11548     return error_mark_node;
11549 
11550   return objc_build_method_signature (is_class_method, type, sel, parms, ellipsis);
11551 }
11552 
11553 /* Parse an objc-type-name.
11554 
11555    objc-type-name:
11556      objc-type-qualifiers[opt] type-name
11557      objc-type-qualifiers[opt]
11558 
11559    objc-type-qualifiers:
11560      objc-type-qualifier
11561      objc-type-qualifiers objc-type-qualifier
11562 
11563    objc-type-qualifier: one of
11564      in out inout bycopy byref oneway
11565 */
11566 
11567 static tree
c_parser_objc_type_name(c_parser * parser)11568 c_parser_objc_type_name (c_parser *parser)
11569 {
11570   tree quals = NULL_TREE;
11571   struct c_type_name *type_name = NULL;
11572   tree type = NULL_TREE;
11573   while (true)
11574     {
11575       c_token *token = c_parser_peek_token (parser);
11576       if (token->type == CPP_KEYWORD
11577 	  && (token->keyword == RID_IN
11578 	      || token->keyword == RID_OUT
11579 	      || token->keyword == RID_INOUT
11580 	      || token->keyword == RID_BYCOPY
11581 	      || token->keyword == RID_BYREF
11582 	      || token->keyword == RID_ONEWAY))
11583 	{
11584 	  quals = chainon (build_tree_list (NULL_TREE, token->value), quals);
11585 	  c_parser_consume_token (parser);
11586 	}
11587       else
11588 	break;
11589     }
11590   if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
11591     type_name = c_parser_type_name (parser);
11592   if (type_name)
11593     type = groktypename (type_name, NULL, NULL);
11594 
11595   /* If the type is unknown, and error has already been produced and
11596      we need to recover from the error.  In that case, use NULL_TREE
11597      for the type, as if no type had been specified; this will use the
11598      default type ('id') which is good for error recovery.  */
11599   if (type == error_mark_node)
11600     type = NULL_TREE;
11601 
11602   return build_tree_list (quals, type);
11603 }
11604 
11605 /* Parse objc-protocol-refs.
11606 
11607    objc-protocol-refs:
11608      < identifier-list >
11609 */
11610 
11611 static tree
c_parser_objc_protocol_refs(c_parser * parser)11612 c_parser_objc_protocol_refs (c_parser *parser)
11613 {
11614   tree list = NULL_TREE;
11615   gcc_assert (c_parser_next_token_is (parser, CPP_LESS));
11616   c_parser_consume_token (parser);
11617   /* Any identifiers, including those declared as type names, are OK
11618      here.  */
11619   while (true)
11620     {
11621       tree id;
11622       if (c_parser_next_token_is_not (parser, CPP_NAME))
11623 	{
11624 	  c_parser_error (parser, "expected identifier");
11625 	  break;
11626 	}
11627       id = c_parser_peek_token (parser)->value;
11628       list = chainon (list, build_tree_list (NULL_TREE, id));
11629       c_parser_consume_token (parser);
11630       if (c_parser_next_token_is (parser, CPP_COMMA))
11631 	c_parser_consume_token (parser);
11632       else
11633 	break;
11634     }
11635   c_parser_require (parser, CPP_GREATER, "expected %<>%>");
11636   return list;
11637 }
11638 
11639 /* Parse an objc-try-catch-finally-statement.
11640 
11641    objc-try-catch-finally-statement:
11642      @try compound-statement objc-catch-list[opt]
11643      @try compound-statement objc-catch-list[opt] @finally compound-statement
11644 
11645    objc-catch-list:
11646      @catch ( objc-catch-parameter-declaration ) compound-statement
11647      objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
11648 
11649    objc-catch-parameter-declaration:
11650      parameter-declaration
11651      '...'
11652 
11653    where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
11654 
11655    PS: This function is identical to cp_parser_objc_try_catch_finally_statement
11656    for C++.  Keep them in sync.  */
11657 
11658 static void
c_parser_objc_try_catch_finally_statement(c_parser * parser)11659 c_parser_objc_try_catch_finally_statement (c_parser *parser)
11660 {
11661   location_t location;
11662   tree stmt;
11663 
11664   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_TRY));
11665   c_parser_consume_token (parser);
11666   location = c_parser_peek_token (parser)->location;
11667   objc_maybe_warn_exceptions (location);
11668   stmt = c_parser_compound_statement (parser);
11669   objc_begin_try_stmt (location, stmt);
11670 
11671   while (c_parser_next_token_is_keyword (parser, RID_AT_CATCH))
11672     {
11673       struct c_parm *parm;
11674       tree parameter_declaration = error_mark_node;
11675       bool seen_open_paren = false;
11676 
11677       c_parser_consume_token (parser);
11678       matching_parens parens;
11679       if (!parens.require_open (parser))
11680 	seen_open_paren = true;
11681       if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
11682 	{
11683 	  /* We have "@catch (...)" (where the '...' are literally
11684 	     what is in the code).  Skip the '...'.
11685 	     parameter_declaration is set to NULL_TREE, and
11686 	     objc_being_catch_clauses() knows that that means
11687 	     '...'.  */
11688 	  c_parser_consume_token (parser);
11689 	  parameter_declaration = NULL_TREE;
11690 	}
11691       else
11692 	{
11693 	  /* We have "@catch (NSException *exception)" or something
11694 	     like that.  Parse the parameter declaration.  */
11695 	  parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
11696 	  if (parm == NULL)
11697 	    parameter_declaration = error_mark_node;
11698 	  else
11699 	    parameter_declaration = grokparm (parm, NULL);
11700 	}
11701       if (seen_open_paren)
11702 	parens.require_close (parser);
11703       else
11704 	{
11705 	  /* If there was no open parenthesis, we are recovering from
11706 	     an error, and we are trying to figure out what mistake
11707 	     the user has made.  */
11708 
11709 	  /* If there is an immediate closing parenthesis, the user
11710 	     probably forgot the opening one (ie, they typed "@catch
11711 	     NSException *e)".  Parse the closing parenthesis and keep
11712 	     going.  */
11713 	  if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
11714 	    c_parser_consume_token (parser);
11715 
11716 	  /* If these is no immediate closing parenthesis, the user
11717 	     probably doesn't know that parenthesis are required at
11718 	     all (ie, they typed "@catch NSException *e").  So, just
11719 	     forget about the closing parenthesis and keep going.  */
11720 	}
11721       objc_begin_catch_clause (parameter_declaration);
11722       if (c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
11723 	c_parser_compound_statement_nostart (parser);
11724       objc_finish_catch_clause ();
11725     }
11726   if (c_parser_next_token_is_keyword (parser, RID_AT_FINALLY))
11727     {
11728       c_parser_consume_token (parser);
11729       location = c_parser_peek_token (parser)->location;
11730       stmt = c_parser_compound_statement (parser);
11731       objc_build_finally_clause (location, stmt);
11732     }
11733   objc_finish_try_stmt ();
11734 }
11735 
11736 /* Parse an objc-synchronized-statement.
11737 
11738    objc-synchronized-statement:
11739      @synchronized ( expression ) compound-statement
11740 */
11741 
11742 static void
c_parser_objc_synchronized_statement(c_parser * parser)11743 c_parser_objc_synchronized_statement (c_parser *parser)
11744 {
11745   location_t loc;
11746   tree expr, stmt;
11747   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNCHRONIZED));
11748   c_parser_consume_token (parser);
11749   loc = c_parser_peek_token (parser)->location;
11750   objc_maybe_warn_exceptions (loc);
11751   matching_parens parens;
11752   if (parens.require_open (parser))
11753     {
11754       struct c_expr ce = c_parser_expression (parser);
11755       ce = convert_lvalue_to_rvalue (loc, ce, false, false);
11756       expr = ce.value;
11757       expr = c_fully_fold (expr, false, NULL);
11758       parens.skip_until_found_close (parser);
11759     }
11760   else
11761     expr = error_mark_node;
11762   stmt = c_parser_compound_statement (parser);
11763   objc_build_synchronized (loc, expr, stmt);
11764 }
11765 
11766 /* Parse an objc-selector; return NULL_TREE without an error if the
11767    next token is not an objc-selector.
11768 
11769    objc-selector:
11770      identifier
11771      one of
11772        enum struct union if else while do for switch case default
11773        break continue return goto asm sizeof typeof __alignof
11774        unsigned long const short volatile signed restrict _Complex
11775        in out inout bycopy byref oneway int char float double void _Bool
11776        _Atomic
11777 
11778    ??? Why this selection of keywords but not, for example, storage
11779    class specifiers?  */
11780 
11781 static tree
c_parser_objc_selector(c_parser * parser)11782 c_parser_objc_selector (c_parser *parser)
11783 {
11784   c_token *token = c_parser_peek_token (parser);
11785   tree value = token->value;
11786   if (token->type == CPP_NAME)
11787     {
11788       c_parser_consume_token (parser);
11789       return value;
11790     }
11791   if (token->type != CPP_KEYWORD)
11792     return NULL_TREE;
11793   switch (token->keyword)
11794     {
11795     case RID_ENUM:
11796     case RID_STRUCT:
11797     case RID_UNION:
11798     case RID_IF:
11799     case RID_ELSE:
11800     case RID_WHILE:
11801     case RID_DO:
11802     case RID_FOR:
11803     case RID_SWITCH:
11804     case RID_CASE:
11805     case RID_DEFAULT:
11806     case RID_BREAK:
11807     case RID_CONTINUE:
11808     case RID_RETURN:
11809     case RID_GOTO:
11810     case RID_ASM:
11811     case RID_SIZEOF:
11812     case RID_TYPEOF:
11813     case RID_ALIGNOF:
11814     case RID_UNSIGNED:
11815     case RID_LONG:
11816     case RID_CONST:
11817     case RID_SHORT:
11818     case RID_VOLATILE:
11819     case RID_SIGNED:
11820     case RID_RESTRICT:
11821     case RID_COMPLEX:
11822     case RID_IN:
11823     case RID_OUT:
11824     case RID_INOUT:
11825     case RID_BYCOPY:
11826     case RID_BYREF:
11827     case RID_ONEWAY:
11828     case RID_INT:
11829     case RID_CHAR:
11830     case RID_FLOAT:
11831     case RID_DOUBLE:
11832     CASE_RID_FLOATN_NX:
11833     case RID_VOID:
11834     case RID_BOOL:
11835     case RID_ATOMIC:
11836     case RID_AUTO_TYPE:
11837     case RID_INT_N_0:
11838     case RID_INT_N_1:
11839     case RID_INT_N_2:
11840     case RID_INT_N_3:
11841       c_parser_consume_token (parser);
11842       return value;
11843     default:
11844       return NULL_TREE;
11845     }
11846 }
11847 
11848 /* Parse an objc-selector-arg.
11849 
11850    objc-selector-arg:
11851      objc-selector
11852      objc-keywordname-list
11853 
11854    objc-keywordname-list:
11855      objc-keywordname
11856      objc-keywordname-list objc-keywordname
11857 
11858    objc-keywordname:
11859      objc-selector :
11860      :
11861 */
11862 
11863 static tree
c_parser_objc_selector_arg(c_parser * parser)11864 c_parser_objc_selector_arg (c_parser *parser)
11865 {
11866   tree sel = c_parser_objc_selector (parser);
11867   tree list = NULL_TREE;
11868   if (sel
11869       && c_parser_next_token_is_not (parser, CPP_COLON)
11870       && c_parser_next_token_is_not (parser, CPP_SCOPE))
11871     return sel;
11872   while (true)
11873     {
11874       if (c_parser_next_token_is (parser, CPP_SCOPE))
11875 	{
11876 	  c_parser_consume_token (parser);
11877 	  list = chainon (list, build_tree_list (sel, NULL_TREE));
11878 	  list = chainon (list, build_tree_list (NULL_TREE, NULL_TREE));
11879 	}
11880       else
11881 	{
11882 	  if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11883 	    return list;
11884 	  list = chainon (list, build_tree_list (sel, NULL_TREE));
11885 	}
11886       sel = c_parser_objc_selector (parser);
11887       if (!sel
11888 	  && c_parser_next_token_is_not (parser, CPP_COLON)
11889 	  && c_parser_next_token_is_not (parser, CPP_SCOPE))
11890 	break;
11891     }
11892   return list;
11893 }
11894 
11895 /* Parse an objc-receiver.
11896 
11897    objc-receiver:
11898      expression
11899      class-name
11900      type-name
11901 */
11902 
11903 static tree
c_parser_objc_receiver(c_parser * parser)11904 c_parser_objc_receiver (c_parser *parser)
11905 {
11906   location_t loc = c_parser_peek_token (parser)->location;
11907 
11908   if (c_parser_peek_token (parser)->type == CPP_NAME
11909       && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
11910 	  || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
11911     {
11912       tree id = c_parser_peek_token (parser)->value;
11913       c_parser_consume_token (parser);
11914       return objc_get_class_reference (id);
11915     }
11916   struct c_expr ce = c_parser_expression (parser);
11917   ce = convert_lvalue_to_rvalue (loc, ce, false, false);
11918   return c_fully_fold (ce.value, false, NULL);
11919 }
11920 
11921 /* Parse objc-message-args.
11922 
11923    objc-message-args:
11924      objc-selector
11925      objc-keywordarg-list
11926 
11927    objc-keywordarg-list:
11928      objc-keywordarg
11929      objc-keywordarg-list objc-keywordarg
11930 
11931    objc-keywordarg:
11932      objc-selector : objc-keywordexpr
11933      : objc-keywordexpr
11934 */
11935 
11936 static tree
c_parser_objc_message_args(c_parser * parser)11937 c_parser_objc_message_args (c_parser *parser)
11938 {
11939   tree sel = c_parser_objc_selector (parser);
11940   tree list = NULL_TREE;
11941   if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
11942     return sel;
11943   while (true)
11944     {
11945       tree keywordexpr;
11946       if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11947 	return error_mark_node;
11948       keywordexpr = c_parser_objc_keywordexpr (parser);
11949       list = chainon (list, build_tree_list (sel, keywordexpr));
11950       sel = c_parser_objc_selector (parser);
11951       if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
11952 	break;
11953     }
11954   return list;
11955 }
11956 
11957 /* Parse an objc-keywordexpr.
11958 
11959    objc-keywordexpr:
11960      nonempty-expr-list
11961 */
11962 
11963 static tree
c_parser_objc_keywordexpr(c_parser * parser)11964 c_parser_objc_keywordexpr (c_parser *parser)
11965 {
11966   tree ret;
11967   vec<tree, va_gc> *expr_list = c_parser_expr_list (parser, true, true,
11968 						NULL, NULL, NULL, NULL);
11969   if (vec_safe_length (expr_list) == 1)
11970     {
11971       /* Just return the expression, remove a level of
11972 	 indirection.  */
11973       ret = (*expr_list)[0];
11974     }
11975   else
11976     {
11977       /* We have a comma expression, we will collapse later.  */
11978       ret = build_tree_list_vec (expr_list);
11979     }
11980   release_tree_vector (expr_list);
11981   return ret;
11982 }
11983 
11984 /* A check, needed in several places, that ObjC interface, implementation or
11985    method definitions are not prefixed by incorrect items.  */
11986 static bool
c_parser_objc_diagnose_bad_element_prefix(c_parser * parser,struct c_declspecs * specs)11987 c_parser_objc_diagnose_bad_element_prefix (c_parser *parser,
11988 					   struct c_declspecs *specs)
11989 {
11990   if (!specs->declspecs_seen_p || specs->non_sc_seen_p
11991       || specs->typespec_kind != ctsk_none)
11992     {
11993       c_parser_error (parser,
11994       		      "no type or storage class may be specified here,");
11995       c_parser_skip_to_end_of_block_or_statement (parser);
11996       return true;
11997     }
11998   return false;
11999 }
12000 
12001 /* Parse an Objective-C @property declaration.  The syntax is:
12002 
12003    objc-property-declaration:
12004      '@property' objc-property-attributes[opt] struct-declaration ;
12005 
12006    objc-property-attributes:
12007     '(' objc-property-attribute-list ')'
12008 
12009    objc-property-attribute-list:
12010      objc-property-attribute
12011      objc-property-attribute-list, objc-property-attribute
12012 
12013    objc-property-attribute
12014      'getter' = identifier
12015      'setter' = identifier
12016      'readonly'
12017      'readwrite'
12018      'assign'
12019      'retain'
12020      'copy'
12021      'nonatomic'
12022 
12023   For example:
12024     @property NSString *name;
12025     @property (readonly) id object;
12026     @property (retain, nonatomic, getter=getTheName) id name;
12027     @property int a, b, c;
12028 
12029   PS: This function is identical to cp_parser_objc_at_propery_declaration
12030   for C++.  Keep them in sync.  */
12031 static void
c_parser_objc_at_property_declaration(c_parser * parser)12032 c_parser_objc_at_property_declaration (c_parser *parser)
12033 {
12034   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY));
12035   location_t loc = c_parser_peek_token (parser)->location;
12036   c_parser_consume_token (parser);  /* Eat '@property'.  */
12037 
12038   /* Parse the optional attribute list.
12039 
12040      A list of parsed, but not verified, attributes.  */
12041   vec<property_attribute_info *> prop_attr_list = vNULL;
12042 
12043   bool syntax_error = false;
12044   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
12045     {
12046       matching_parens parens;
12047 
12048       location_t attr_start = c_parser_peek_token (parser)->location;
12049       /* Eat the '(' */
12050       parens.consume_open (parser);
12051 
12052       /* Property attribute keywords are valid now.  */
12053       parser->objc_property_attr_context = true;
12054 
12055       /* Allow @property (), with a warning.  */
12056       location_t attr_end = c_parser_peek_token (parser)->location;
12057 
12058       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
12059 	{
12060 	  location_t attr_comb = make_location (attr_end, attr_start, attr_end);
12061 	  warning_at (attr_comb, OPT_Wattributes,
12062 		      "empty property attribute list");
12063 	}
12064       else
12065 	while (true)
12066 	  {
12067 	    c_token *token = c_parser_peek_token (parser);
12068 	    attr_start = token->location;
12069 	    attr_end = get_finish (token->location);
12070 	    location_t attr_comb = make_location (attr_start, attr_start,
12071 						  attr_end);
12072 
12073 	    if (token->type == CPP_CLOSE_PAREN || token->type == CPP_COMMA)
12074 	      {
12075 		warning_at (attr_comb, OPT_Wattributes,
12076 			    "missing property attribute");
12077 		if (token->type == CPP_CLOSE_PAREN)
12078 		  break;
12079 		c_parser_consume_token (parser);
12080 		continue;
12081 	      }
12082 
12083 	    tree attr_name = NULL_TREE;
12084 	    enum rid keyword = RID_MAX; /* Not a valid property attribute.  */
12085 	    bool add_at = false;
12086 	    if (token->type == CPP_KEYWORD)
12087 	      {
12088 		keyword = token->keyword;
12089 		if (OBJC_IS_AT_KEYWORD (keyword))
12090 		  {
12091 		    /* For '@' keywords the token value has the keyword,
12092 		       prepend the '@' for diagnostics.  */
12093 		    attr_name = token->value;
12094 		    add_at = true;
12095 		  }
12096 		else
12097 		  attr_name = ridpointers[(int)keyword];
12098 	      }
12099 	    else if (token->type == CPP_NAME)
12100 	      attr_name = token->value;
12101 	    c_parser_consume_token (parser);
12102 
12103 	    enum objc_property_attribute_kind prop_kind
12104 	      = objc_prop_attr_kind_for_rid (keyword);
12105 	    property_attribute_info *prop
12106 	      = new property_attribute_info (attr_name, attr_comb, prop_kind);
12107 	    prop_attr_list.safe_push (prop);
12108 
12109 	    tree meth_name;
12110 	    switch (prop->prop_kind)
12111 	      {
12112 	      default: break;
12113 	      case OBJC_PROPERTY_ATTR_UNKNOWN:
12114 		if (attr_name)
12115 		  error_at (attr_comb, "unknown property attribute %<%s%s%>",
12116 			    add_at ? "@" : "", IDENTIFIER_POINTER (attr_name));
12117 		else
12118 		  error_at (attr_comb, "unknown property attribute");
12119 		prop->parse_error = syntax_error = true;
12120 		break;
12121 
12122 	      case OBJC_PROPERTY_ATTR_GETTER:
12123 	      case OBJC_PROPERTY_ATTR_SETTER:
12124 		if (c_parser_next_token_is_not (parser, CPP_EQ))
12125 		  {
12126 		    attr_comb = make_location (attr_end, attr_start, attr_end);
12127 		    error_at (attr_comb, "expected %<=%> after Objective-C %qE",
12128 			      attr_name);
12129 		    prop->parse_error = syntax_error = true;
12130 		    break;
12131 		  }
12132 		token = c_parser_peek_token (parser);
12133 		attr_end = token->location;
12134 		c_parser_consume_token (parser); /* eat the = */
12135 		if (c_parser_next_token_is_not (parser, CPP_NAME))
12136 		  {
12137 		    attr_comb = make_location (attr_end, attr_start, attr_end);
12138 		    error_at (attr_comb, "expected %qE selector name",
12139 			      attr_name);
12140 		    prop->parse_error = syntax_error = true;
12141 		    break;
12142 		  }
12143 		/* Get the end of the method name, and consume the name.  */
12144 		token = c_parser_peek_token (parser);
12145 		attr_end = get_finish (token->location);
12146 		meth_name = token->value;
12147 		c_parser_consume_token (parser);
12148 		if (prop->prop_kind == OBJC_PROPERTY_ATTR_SETTER)
12149 		  {
12150 		    if (c_parser_next_token_is_not (parser, CPP_COLON))
12151 		      {
12152 			attr_comb = make_location (attr_end, attr_start,
12153 						   attr_end);
12154 			error_at (attr_comb, "setter method names must"
12155 				  " terminate with %<:%>");
12156 			prop->parse_error = syntax_error = true;
12157 		      }
12158 		    else
12159 		      {
12160 			attr_end = get_finish (c_parser_peek_token
12161 					       (parser)->location);
12162 			c_parser_consume_token (parser);
12163 		      }
12164 		    attr_comb = make_location (attr_start, attr_start,
12165 					       attr_end);
12166 		  }
12167 		else
12168 		  attr_comb = make_location (attr_start, attr_start,
12169 					       attr_end);
12170 		prop->ident = meth_name;
12171 		/* Updated location including all that was successfully
12172 		   parsed.  */
12173 		prop->prop_loc = attr_comb;
12174 		break;
12175 	    }
12176 
12177 	  /* If we see a comma here, then keep going - even if we already
12178 	     saw a syntax error.  For simple mistakes e.g. (asign, getter=x)
12179 	     this makes a more useful output and avoid spurious warnings about
12180 	     missing attributes that are, in fact, specified after the one with
12181 	     the syntax error.  */
12182 	  if (c_parser_next_token_is (parser, CPP_COMMA))
12183 	    c_parser_consume_token (parser);
12184 	  else
12185 	    break;
12186 	}
12187       parser->objc_property_attr_context = false;
12188 
12189       if (syntax_error && c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
12190 	/* We don't really want to chew the whole of the file looking for a
12191 	   matching closing parenthesis, so we will try to read the decl and
12192 	   let the error handling for that close out the statement.  */
12193 	;
12194       else
12195 	syntax_error = false, parens.skip_until_found_close (parser);
12196     }
12197 
12198   /* 'properties' is the list of properties that we read.  Usually a
12199      single one, but maybe more (eg, in "@property int a, b, c;" there
12200      are three).  */
12201   tree properties = c_parser_struct_declaration (parser);
12202 
12203   if (properties == error_mark_node)
12204     c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12205   else
12206     {
12207       if (properties == NULL_TREE)
12208 	c_parser_error (parser, "expected identifier");
12209       else
12210 	{
12211 	  /* Comma-separated properties are chained together in reverse order;
12212 	     add them one by one.  */
12213 	  properties = nreverse (properties);
12214 	  for (; properties; properties = TREE_CHAIN (properties))
12215 	    objc_add_property_declaration (loc, copy_node (properties),
12216 					    prop_attr_list);
12217 	}
12218       c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12219     }
12220 
12221   while (!prop_attr_list.is_empty())
12222     delete prop_attr_list.pop ();
12223   prop_attr_list.release ();
12224   parser->error = false;
12225 }
12226 
12227 /* Parse an Objective-C @synthesize declaration.  The syntax is:
12228 
12229    objc-synthesize-declaration:
12230      @synthesize objc-synthesize-identifier-list ;
12231 
12232    objc-synthesize-identifier-list:
12233      objc-synthesize-identifier
12234      objc-synthesize-identifier-list, objc-synthesize-identifier
12235 
12236    objc-synthesize-identifier
12237      identifier
12238      identifier = identifier
12239 
12240   For example:
12241     @synthesize MyProperty;
12242     @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
12243 
12244   PS: This function is identical to cp_parser_objc_at_synthesize_declaration
12245   for C++.  Keep them in sync.
12246 */
12247 static void
c_parser_objc_at_synthesize_declaration(c_parser * parser)12248 c_parser_objc_at_synthesize_declaration (c_parser *parser)
12249 {
12250   tree list = NULL_TREE;
12251   location_t loc;
12252   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNTHESIZE));
12253   loc = c_parser_peek_token (parser)->location;
12254 
12255   c_parser_consume_token (parser);
12256   while (true)
12257     {
12258       tree property, ivar;
12259       if (c_parser_next_token_is_not (parser, CPP_NAME))
12260 	{
12261 	  c_parser_error (parser, "expected identifier");
12262 	  c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12263 	  /* Once we find the semicolon, we can resume normal parsing.
12264 	     We have to reset parser->error manually because
12265 	     c_parser_skip_until_found() won't reset it for us if the
12266 	     next token is precisely a semicolon.  */
12267 	  parser->error = false;
12268 	  return;
12269 	}
12270       property = c_parser_peek_token (parser)->value;
12271       c_parser_consume_token (parser);
12272       if (c_parser_next_token_is (parser, CPP_EQ))
12273 	{
12274 	  c_parser_consume_token (parser);
12275 	  if (c_parser_next_token_is_not (parser, CPP_NAME))
12276 	    {
12277 	      c_parser_error (parser, "expected identifier");
12278 	      c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12279 	      parser->error = false;
12280 	      return;
12281 	    }
12282 	  ivar = c_parser_peek_token (parser)->value;
12283 	  c_parser_consume_token (parser);
12284 	}
12285       else
12286 	ivar = NULL_TREE;
12287       list = chainon (list, build_tree_list (ivar, property));
12288       if (c_parser_next_token_is (parser, CPP_COMMA))
12289 	c_parser_consume_token (parser);
12290       else
12291 	break;
12292     }
12293   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12294   objc_add_synthesize_declaration (loc, list);
12295 }
12296 
12297 /* Parse an Objective-C @dynamic declaration.  The syntax is:
12298 
12299    objc-dynamic-declaration:
12300      @dynamic identifier-list ;
12301 
12302    For example:
12303      @dynamic MyProperty;
12304      @dynamic MyProperty, AnotherProperty;
12305 
12306   PS: This function is identical to cp_parser_objc_at_dynamic_declaration
12307   for C++.  Keep them in sync.
12308 */
12309 static void
c_parser_objc_at_dynamic_declaration(c_parser * parser)12310 c_parser_objc_at_dynamic_declaration (c_parser *parser)
12311 {
12312   tree list = NULL_TREE;
12313   location_t loc;
12314   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_DYNAMIC));
12315   loc = c_parser_peek_token (parser)->location;
12316 
12317   c_parser_consume_token (parser);
12318   while (true)
12319     {
12320       tree property;
12321       if (c_parser_next_token_is_not (parser, CPP_NAME))
12322 	{
12323 	  c_parser_error (parser, "expected identifier");
12324 	  c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12325 	  parser->error = false;
12326 	  return;
12327 	}
12328       property = c_parser_peek_token (parser)->value;
12329       list = chainon (list, build_tree_list (NULL_TREE, property));
12330       c_parser_consume_token (parser);
12331       if (c_parser_next_token_is (parser, CPP_COMMA))
12332 	c_parser_consume_token (parser);
12333       else
12334 	break;
12335     }
12336   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12337   objc_add_dynamic_declaration (loc, list);
12338 }
12339 
12340 
12341 /* Parse a pragma GCC ivdep.  */
12342 
12343 static bool
c_parse_pragma_ivdep(c_parser * parser)12344 c_parse_pragma_ivdep (c_parser *parser)
12345 {
12346   c_parser_consume_pragma (parser);
12347   c_parser_skip_to_pragma_eol (parser);
12348   return true;
12349 }
12350 
12351 /* Parse a pragma GCC unroll.  */
12352 
12353 static unsigned short
c_parser_pragma_unroll(c_parser * parser)12354 c_parser_pragma_unroll (c_parser *parser)
12355 {
12356   unsigned short unroll;
12357   c_parser_consume_pragma (parser);
12358   location_t location = c_parser_peek_token (parser)->location;
12359   tree expr = c_parser_expr_no_commas (parser, NULL).value;
12360   mark_exp_read (expr);
12361   expr = c_fully_fold (expr, false, NULL);
12362   HOST_WIDE_INT lunroll = 0;
12363   if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
12364       || TREE_CODE (expr) != INTEGER_CST
12365       || (lunroll = tree_to_shwi (expr)) < 0
12366       || lunroll >= USHRT_MAX)
12367     {
12368       error_at (location, "%<#pragma GCC unroll%> requires an"
12369 		" assignment-expression that evaluates to a non-negative"
12370 		" integral constant less than %u", USHRT_MAX);
12371       unroll = 0;
12372     }
12373   else
12374     {
12375       unroll = (unsigned short)lunroll;
12376       if (unroll == 0)
12377 	unroll = 1;
12378     }
12379 
12380   c_parser_skip_to_pragma_eol (parser);
12381   return unroll;
12382 }
12383 
12384 /* Handle pragmas.  Some OpenMP pragmas are associated with, and therefore
12385    should be considered, statements.  ALLOW_STMT is true if we're within
12386    the context of a function and such pragmas are to be allowed.  Returns
12387    true if we actually parsed such a pragma.  */
12388 
12389 static bool
c_parser_pragma(c_parser * parser,enum pragma_context context,bool * if_p)12390 c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p)
12391 {
12392   unsigned int id;
12393   const char *construct = NULL;
12394 
12395   input_location = c_parser_peek_token (parser)->location;
12396   id = c_parser_peek_token (parser)->pragma_kind;
12397   gcc_assert (id != PRAGMA_NONE);
12398 
12399   switch (id)
12400     {
12401     case PRAGMA_OACC_DECLARE:
12402       c_parser_oacc_declare (parser);
12403       return false;
12404 
12405     case PRAGMA_OACC_ENTER_DATA:
12406       if (context != pragma_compound)
12407 	{
12408 	  construct = "acc enter data";
12409 	in_compound:
12410 	  if (context == pragma_stmt)
12411 	    {
12412 	      error_at (c_parser_peek_token (parser)->location,
12413 			"%<#pragma %s%> may only be used in compound "
12414 			"statements", construct);
12415 	      c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12416 	      return true;
12417 	    }
12418 	  goto bad_stmt;
12419 	}
12420       c_parser_oacc_enter_exit_data (parser, true);
12421       return false;
12422 
12423     case PRAGMA_OACC_EXIT_DATA:
12424       if (context != pragma_compound)
12425 	{
12426 	  construct = "acc exit data";
12427 	  goto in_compound;
12428 	}
12429       c_parser_oacc_enter_exit_data (parser, false);
12430       return false;
12431 
12432     case PRAGMA_OACC_ROUTINE:
12433       if (context != pragma_external)
12434 	{
12435 	  error_at (c_parser_peek_token (parser)->location,
12436 		    "%<#pragma acc routine%> must be at file scope");
12437 	  c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12438 	  return false;
12439 	}
12440       c_parser_oacc_routine (parser, context);
12441       return false;
12442 
12443     case PRAGMA_OACC_UPDATE:
12444       if (context != pragma_compound)
12445 	{
12446 	  construct = "acc update";
12447 	  goto in_compound;
12448 	}
12449       c_parser_oacc_update (parser);
12450       return false;
12451 
12452     case PRAGMA_OMP_BARRIER:
12453       if (context != pragma_compound)
12454 	{
12455 	  construct = "omp barrier";
12456 	  goto in_compound;
12457 	}
12458       c_parser_omp_barrier (parser);
12459       return false;
12460 
12461     case PRAGMA_OMP_DEPOBJ:
12462       if (context != pragma_compound)
12463 	{
12464 	  construct = "omp depobj";
12465 	  goto in_compound;
12466 	}
12467       c_parser_omp_depobj (parser);
12468       return false;
12469 
12470     case PRAGMA_OMP_FLUSH:
12471       if (context != pragma_compound)
12472 	{
12473 	  construct = "omp flush";
12474 	  goto in_compound;
12475 	}
12476       c_parser_omp_flush (parser);
12477       return false;
12478 
12479     case PRAGMA_OMP_TASKWAIT:
12480       if (context != pragma_compound)
12481 	{
12482 	  construct = "omp taskwait";
12483 	  goto in_compound;
12484 	}
12485       c_parser_omp_taskwait (parser);
12486       return false;
12487 
12488     case PRAGMA_OMP_TASKYIELD:
12489       if (context != pragma_compound)
12490 	{
12491 	  construct = "omp taskyield";
12492 	  goto in_compound;
12493 	}
12494       c_parser_omp_taskyield (parser);
12495       return false;
12496 
12497     case PRAGMA_OMP_CANCEL:
12498       if (context != pragma_compound)
12499 	{
12500 	  construct = "omp cancel";
12501 	  goto in_compound;
12502 	}
12503       c_parser_omp_cancel (parser);
12504       return false;
12505 
12506     case PRAGMA_OMP_CANCELLATION_POINT:
12507       return c_parser_omp_cancellation_point (parser, context);
12508 
12509     case PRAGMA_OMP_THREADPRIVATE:
12510       c_parser_omp_threadprivate (parser);
12511       return false;
12512 
12513     case PRAGMA_OMP_TARGET:
12514       return c_parser_omp_target (parser, context, if_p);
12515 
12516     case PRAGMA_OMP_END_DECLARE_TARGET:
12517       c_parser_omp_end_declare_target (parser);
12518       return false;
12519 
12520     case PRAGMA_OMP_SCAN:
12521       error_at (c_parser_peek_token (parser)->location,
12522 		"%<#pragma omp scan%> may only be used in "
12523 		"a loop construct with %<inscan%> %<reduction%> clause");
12524       c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12525       return false;
12526 
12527     case PRAGMA_OMP_SECTION:
12528       error_at (c_parser_peek_token (parser)->location,
12529 		"%<#pragma omp section%> may only be used in "
12530 		"%<#pragma omp sections%> construct");
12531       c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12532       return false;
12533 
12534     case PRAGMA_OMP_DECLARE:
12535       return c_parser_omp_declare (parser, context);
12536 
12537     case PRAGMA_OMP_REQUIRES:
12538       if (context != pragma_external)
12539 	{
12540 	  error_at (c_parser_peek_token (parser)->location,
12541 		    "%<#pragma omp requires%> may only be used at file scope");
12542 	  c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12543 	  return false;
12544 	}
12545       c_parser_omp_requires (parser);
12546       return false;
12547 
12548     case PRAGMA_OMP_NOTHING:
12549       c_parser_omp_nothing (parser);
12550       return false;
12551 
12552     case PRAGMA_OMP_ERROR:
12553       return c_parser_omp_error (parser, context);
12554 
12555     case PRAGMA_OMP_ORDERED:
12556       return c_parser_omp_ordered (parser, context, if_p);
12557 
12558     case PRAGMA_IVDEP:
12559       {
12560 	const bool ivdep = c_parse_pragma_ivdep (parser);
12561 	unsigned short unroll;
12562 	if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_UNROLL)
12563 	  unroll = c_parser_pragma_unroll (parser);
12564 	else
12565 	  unroll = 0;
12566 	if (!c_parser_next_token_is_keyword (parser, RID_FOR)
12567 	    && !c_parser_next_token_is_keyword (parser, RID_WHILE)
12568 	    && !c_parser_next_token_is_keyword (parser, RID_DO))
12569 	  {
12570 	    c_parser_error (parser, "for, while or do statement expected");
12571 	    return false;
12572 	  }
12573 	if (c_parser_next_token_is_keyword (parser, RID_FOR))
12574 	  c_parser_for_statement (parser, ivdep, unroll, if_p);
12575 	else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
12576 	  c_parser_while_statement (parser, ivdep, unroll, if_p);
12577 	else
12578 	  c_parser_do_statement (parser, ivdep, unroll);
12579       }
12580       return true;
12581 
12582     case PRAGMA_UNROLL:
12583       {
12584 	unsigned short unroll = c_parser_pragma_unroll (parser);
12585 	bool ivdep;
12586 	if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_IVDEP)
12587 	  ivdep = c_parse_pragma_ivdep (parser);
12588 	else
12589 	  ivdep = false;
12590 	if (!c_parser_next_token_is_keyword (parser, RID_FOR)
12591 	    && !c_parser_next_token_is_keyword (parser, RID_WHILE)
12592 	    && !c_parser_next_token_is_keyword (parser, RID_DO))
12593 	  {
12594 	    c_parser_error (parser, "for, while or do statement expected");
12595 	    return false;
12596 	  }
12597 	if (c_parser_next_token_is_keyword (parser, RID_FOR))
12598 	  c_parser_for_statement (parser, ivdep, unroll, if_p);
12599 	else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
12600 	  c_parser_while_statement (parser, ivdep, unroll, if_p);
12601 	else
12602 	  c_parser_do_statement (parser, ivdep, unroll);
12603       }
12604       return true;
12605 
12606     case PRAGMA_GCC_PCH_PREPROCESS:
12607       c_parser_error (parser, "%<#pragma GCC pch_preprocess%> must be first");
12608       c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12609       return false;
12610 
12611     case PRAGMA_OACC_WAIT:
12612       if (context != pragma_compound)
12613 	{
12614 	  construct = "acc wait";
12615 	  goto in_compound;
12616 	}
12617 	/* FALL THROUGH.  */
12618 
12619     default:
12620       if (id < PRAGMA_FIRST_EXTERNAL)
12621 	{
12622 	  if (context != pragma_stmt && context != pragma_compound)
12623 	    {
12624 	    bad_stmt:
12625 	      c_parser_error (parser, "expected declaration specifiers");
12626 	      c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12627 	      return false;
12628 	    }
12629 	  c_parser_omp_construct (parser, if_p);
12630 	  return true;
12631 	}
12632       break;
12633     }
12634 
12635   c_parser_consume_pragma (parser);
12636   c_invoke_pragma_handler (id);
12637 
12638   /* Skip to EOL, but suppress any error message.  Those will have been
12639      generated by the handler routine through calling error, as opposed
12640      to calling c_parser_error.  */
12641   parser->error = true;
12642   c_parser_skip_to_pragma_eol (parser);
12643 
12644   return false;
12645 }
12646 
12647 /* The interface the pragma parsers have to the lexer.  */
12648 
12649 enum cpp_ttype
pragma_lex(tree * value,location_t * loc)12650 pragma_lex (tree *value, location_t *loc)
12651 {
12652   c_token *tok = c_parser_peek_token (the_parser);
12653   enum cpp_ttype ret = tok->type;
12654 
12655   *value = tok->value;
12656   if (loc)
12657     *loc = tok->location;
12658 
12659   if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF)
12660     ret = CPP_EOF;
12661   else if (ret == CPP_STRING)
12662     *value = c_parser_string_literal (the_parser, false, false).value;
12663   else
12664     {
12665       if (ret == CPP_KEYWORD)
12666 	ret = CPP_NAME;
12667       c_parser_consume_token (the_parser);
12668     }
12669 
12670   return ret;
12671 }
12672 
12673 static void
c_parser_pragma_pch_preprocess(c_parser * parser)12674 c_parser_pragma_pch_preprocess (c_parser *parser)
12675 {
12676   tree name = NULL;
12677 
12678   parser->lex_joined_string = true;
12679   c_parser_consume_pragma (parser);
12680   if (c_parser_next_token_is (parser, CPP_STRING))
12681     {
12682       name = c_parser_peek_token (parser)->value;
12683       c_parser_consume_token (parser);
12684     }
12685   else
12686     c_parser_error (parser, "expected string literal");
12687   c_parser_skip_to_pragma_eol (parser);
12688   parser->lex_joined_string = false;
12689 
12690   if (name)
12691     c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name));
12692 }
12693 
12694 /* OpenACC and OpenMP parsing routines.  */
12695 
12696 /* Returns name of the next clause.
12697    If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
12698    the token is not consumed.  Otherwise appropriate pragma_omp_clause is
12699    returned and the token is consumed.  */
12700 
12701 static pragma_omp_clause
c_parser_omp_clause_name(c_parser * parser)12702 c_parser_omp_clause_name (c_parser *parser)
12703 {
12704   pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;
12705 
12706   if (c_parser_next_token_is_keyword (parser, RID_AUTO))
12707     result = PRAGMA_OACC_CLAUSE_AUTO;
12708   else if (c_parser_next_token_is_keyword (parser, RID_IF))
12709     result = PRAGMA_OMP_CLAUSE_IF;
12710   else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
12711     result = PRAGMA_OMP_CLAUSE_DEFAULT;
12712   else if (c_parser_next_token_is_keyword (parser, RID_FOR))
12713     result = PRAGMA_OMP_CLAUSE_FOR;
12714   else if (c_parser_next_token_is (parser, CPP_NAME))
12715     {
12716       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
12717 
12718       switch (p[0])
12719 	{
12720 	case 'a':
12721 	  if (!strcmp ("affinity", p))
12722 	    result = PRAGMA_OMP_CLAUSE_AFFINITY;
12723 	  else if (!strcmp ("aligned", p))
12724 	    result = PRAGMA_OMP_CLAUSE_ALIGNED;
12725 	  else if (!strcmp ("allocate", p))
12726 	    result = PRAGMA_OMP_CLAUSE_ALLOCATE;
12727 	  else if (!strcmp ("async", p))
12728 	    result = PRAGMA_OACC_CLAUSE_ASYNC;
12729 	  else if (!strcmp ("attach", p))
12730 	    result = PRAGMA_OACC_CLAUSE_ATTACH;
12731 	  break;
12732 	case 'b':
12733 	  if (!strcmp ("bind", p))
12734 	    result = PRAGMA_OMP_CLAUSE_BIND;
12735 	  break;
12736 	case 'c':
12737 	  if (!strcmp ("collapse", p))
12738 	    result = PRAGMA_OMP_CLAUSE_COLLAPSE;
12739 	  else if (!strcmp ("copy", p))
12740 	    result = PRAGMA_OACC_CLAUSE_COPY;
12741 	  else if (!strcmp ("copyin", p))
12742 	    result = PRAGMA_OMP_CLAUSE_COPYIN;
12743 	  else if (!strcmp ("copyout", p))
12744 	    result = PRAGMA_OACC_CLAUSE_COPYOUT;
12745           else if (!strcmp ("copyprivate", p))
12746 	    result = PRAGMA_OMP_CLAUSE_COPYPRIVATE;
12747 	  else if (!strcmp ("create", p))
12748 	    result = PRAGMA_OACC_CLAUSE_CREATE;
12749 	  break;
12750 	case 'd':
12751 	  if (!strcmp ("defaultmap", p))
12752 	    result = PRAGMA_OMP_CLAUSE_DEFAULTMAP;
12753 	  else if (!strcmp ("delete", p))
12754 	    result = PRAGMA_OACC_CLAUSE_DELETE;
12755 	  else if (!strcmp ("depend", p))
12756 	    result = PRAGMA_OMP_CLAUSE_DEPEND;
12757 	  else if (!strcmp ("detach", p))
12758 	    result = PRAGMA_OACC_CLAUSE_DETACH;
12759 	  else if (!strcmp ("device", p))
12760 	    result = PRAGMA_OMP_CLAUSE_DEVICE;
12761 	  else if (!strcmp ("deviceptr", p))
12762 	    result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
12763 	  else if (!strcmp ("device_resident", p))
12764 	    result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
12765 	  else if (!strcmp ("device_type", p))
12766 	    result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
12767 	  else if (!strcmp ("dist_schedule", p))
12768 	    result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
12769 	  break;
12770 	case 'f':
12771 	  if (!strcmp ("filter", p))
12772 	    result = PRAGMA_OMP_CLAUSE_FILTER;
12773 	  else if (!strcmp ("final", p))
12774 	    result = PRAGMA_OMP_CLAUSE_FINAL;
12775 	  else if (!strcmp ("finalize", p))
12776 	    result = PRAGMA_OACC_CLAUSE_FINALIZE;
12777 	  else if (!strcmp ("firstprivate", p))
12778 	    result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
12779 	  else if (!strcmp ("from", p))
12780 	    result = PRAGMA_OMP_CLAUSE_FROM;
12781 	  break;
12782 	case 'g':
12783 	  if (!strcmp ("gang", p))
12784 	    result = PRAGMA_OACC_CLAUSE_GANG;
12785 	  else if (!strcmp ("grainsize", p))
12786 	    result = PRAGMA_OMP_CLAUSE_GRAINSIZE;
12787 	  break;
12788 	case 'h':
12789 	  if (!strcmp ("has_device_addr", p))
12790 	    result = PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR;
12791 	  else if (!strcmp ("hint", p))
12792 	    result = PRAGMA_OMP_CLAUSE_HINT;
12793 	  else if (!strcmp ("host", p))
12794 	    result = PRAGMA_OACC_CLAUSE_HOST;
12795 	  break;
12796 	case 'i':
12797 	  if (!strcmp ("if_present", p))
12798 	    result = PRAGMA_OACC_CLAUSE_IF_PRESENT;
12799 	  else if (!strcmp ("in_reduction", p))
12800 	    result = PRAGMA_OMP_CLAUSE_IN_REDUCTION;
12801 	  else if (!strcmp ("inbranch", p))
12802 	    result = PRAGMA_OMP_CLAUSE_INBRANCH;
12803 	  else if (!strcmp ("independent", p))
12804 	    result = PRAGMA_OACC_CLAUSE_INDEPENDENT;
12805 	  else if (!strcmp ("is_device_ptr", p))
12806 	    result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR;
12807 	  break;
12808 	case 'l':
12809 	  if (!strcmp ("lastprivate", p))
12810 	    result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
12811 	  else if (!strcmp ("linear", p))
12812 	    result = PRAGMA_OMP_CLAUSE_LINEAR;
12813 	  else if (!strcmp ("link", p))
12814 	    result = PRAGMA_OMP_CLAUSE_LINK;
12815 	  break;
12816 	case 'm':
12817 	  if (!strcmp ("map", p))
12818 	    result = PRAGMA_OMP_CLAUSE_MAP;
12819 	  else if (!strcmp ("mergeable", p))
12820 	    result = PRAGMA_OMP_CLAUSE_MERGEABLE;
12821 	  break;
12822 	case 'n':
12823 	  if (!strcmp ("no_create", p))
12824 	    result = PRAGMA_OACC_CLAUSE_NO_CREATE;
12825 	  else if (!strcmp ("nogroup", p))
12826 	    result = PRAGMA_OMP_CLAUSE_NOGROUP;
12827 	  else if (!strcmp ("nohost", p))
12828 	    result = PRAGMA_OACC_CLAUSE_NOHOST;
12829 	  else if (!strcmp ("nontemporal", p))
12830 	    result = PRAGMA_OMP_CLAUSE_NONTEMPORAL;
12831 	  else if (!strcmp ("notinbranch", p))
12832 	    result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
12833 	  else if (!strcmp ("nowait", p))
12834 	    result = PRAGMA_OMP_CLAUSE_NOWAIT;
12835 	  else if (!strcmp ("num_gangs", p))
12836 	    result = PRAGMA_OACC_CLAUSE_NUM_GANGS;
12837 	  else if (!strcmp ("num_tasks", p))
12838 	    result = PRAGMA_OMP_CLAUSE_NUM_TASKS;
12839 	  else if (!strcmp ("num_teams", p))
12840 	    result = PRAGMA_OMP_CLAUSE_NUM_TEAMS;
12841 	  else if (!strcmp ("num_threads", p))
12842 	    result = PRAGMA_OMP_CLAUSE_NUM_THREADS;
12843 	  else if (!strcmp ("num_workers", p))
12844 	    result = PRAGMA_OACC_CLAUSE_NUM_WORKERS;
12845 	  break;
12846 	case 'o':
12847 	  if (!strcmp ("ordered", p))
12848 	    result = PRAGMA_OMP_CLAUSE_ORDERED;
12849 	  else if (!strcmp ("order", p))
12850 	    result = PRAGMA_OMP_CLAUSE_ORDER;
12851 	  break;
12852 	case 'p':
12853 	  if (!strcmp ("parallel", p))
12854 	    result = PRAGMA_OMP_CLAUSE_PARALLEL;
12855 	  else if (!strcmp ("present", p))
12856 	    result = PRAGMA_OACC_CLAUSE_PRESENT;
12857 	  /* As of OpenACC 2.5, these are now aliases of the non-present_or
12858 	     clauses.  */
12859 	  else if (!strcmp ("present_or_copy", p)
12860 		   || !strcmp ("pcopy", p))
12861 	    result = PRAGMA_OACC_CLAUSE_COPY;
12862 	  else if (!strcmp ("present_or_copyin", p)
12863 		   || !strcmp ("pcopyin", p))
12864 	    result = PRAGMA_OACC_CLAUSE_COPYIN;
12865 	  else if (!strcmp ("present_or_copyout", p)
12866 		   || !strcmp ("pcopyout", p))
12867 	    result = PRAGMA_OACC_CLAUSE_COPYOUT;
12868 	  else if (!strcmp ("present_or_create", p)
12869 		   || !strcmp ("pcreate", p))
12870 	    result = PRAGMA_OACC_CLAUSE_CREATE;
12871 	  else if (!strcmp ("priority", p))
12872 	    result = PRAGMA_OMP_CLAUSE_PRIORITY;
12873 	  else if (!strcmp ("private", p))
12874 	    result = PRAGMA_OMP_CLAUSE_PRIVATE;
12875 	  else if (!strcmp ("proc_bind", p))
12876 	    result = PRAGMA_OMP_CLAUSE_PROC_BIND;
12877 	  break;
12878 	case 'r':
12879 	  if (!strcmp ("reduction", p))
12880 	    result = PRAGMA_OMP_CLAUSE_REDUCTION;
12881 	  break;
12882 	case 's':
12883 	  if (!strcmp ("safelen", p))
12884 	    result = PRAGMA_OMP_CLAUSE_SAFELEN;
12885 	  else if (!strcmp ("schedule", p))
12886 	    result = PRAGMA_OMP_CLAUSE_SCHEDULE;
12887 	  else if (!strcmp ("sections", p))
12888 	    result = PRAGMA_OMP_CLAUSE_SECTIONS;
12889 	  else if (!strcmp ("self", p)) /* "self" is a synonym for "host".  */
12890 	    result = PRAGMA_OACC_CLAUSE_HOST;
12891 	  else if (!strcmp ("seq", p))
12892 	    result = PRAGMA_OACC_CLAUSE_SEQ;
12893 	  else if (!strcmp ("shared", p))
12894 	    result = PRAGMA_OMP_CLAUSE_SHARED;
12895 	  else if (!strcmp ("simd", p))
12896 	    result = PRAGMA_OMP_CLAUSE_SIMD;
12897 	  else if (!strcmp ("simdlen", p))
12898 	    result = PRAGMA_OMP_CLAUSE_SIMDLEN;
12899 	  break;
12900 	case 't':
12901 	  if (!strcmp ("task_reduction", p))
12902 	    result = PRAGMA_OMP_CLAUSE_TASK_REDUCTION;
12903 	  else if (!strcmp ("taskgroup", p))
12904 	    result = PRAGMA_OMP_CLAUSE_TASKGROUP;
12905 	  else if (!strcmp ("thread_limit", p))
12906 	    result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT;
12907 	  else if (!strcmp ("threads", p))
12908 	    result = PRAGMA_OMP_CLAUSE_THREADS;
12909 	  else if (!strcmp ("tile", p))
12910 	    result = PRAGMA_OACC_CLAUSE_TILE;
12911 	  else if (!strcmp ("to", p))
12912 	    result = PRAGMA_OMP_CLAUSE_TO;
12913 	  break;
12914 	case 'u':
12915 	  if (!strcmp ("uniform", p))
12916 	    result = PRAGMA_OMP_CLAUSE_UNIFORM;
12917 	  else if (!strcmp ("untied", p))
12918 	    result = PRAGMA_OMP_CLAUSE_UNTIED;
12919 	  else if (!strcmp ("use_device", p))
12920 	    result = PRAGMA_OACC_CLAUSE_USE_DEVICE;
12921 	  else if (!strcmp ("use_device_addr", p))
12922 	    result = PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR;
12923 	  else if (!strcmp ("use_device_ptr", p))
12924 	    result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR;
12925 	  break;
12926 	case 'v':
12927 	  if (!strcmp ("vector", p))
12928 	    result = PRAGMA_OACC_CLAUSE_VECTOR;
12929 	  else if (!strcmp ("vector_length", p))
12930 	    result = PRAGMA_OACC_CLAUSE_VECTOR_LENGTH;
12931 	  break;
12932 	case 'w':
12933 	  if (!strcmp ("wait", p))
12934 	    result = PRAGMA_OACC_CLAUSE_WAIT;
12935 	  else if (!strcmp ("worker", p))
12936 	    result = PRAGMA_OACC_CLAUSE_WORKER;
12937 	  break;
12938 	}
12939     }
12940 
12941   if (result != PRAGMA_OMP_CLAUSE_NONE)
12942     c_parser_consume_token (parser);
12943 
12944   return result;
12945 }
12946 
12947 /* Validate that a clause of the given type does not already exist.  */
12948 
12949 static void
check_no_duplicate_clause(tree clauses,enum omp_clause_code code,const char * name)12950 check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
12951 			   const char *name)
12952 {
12953   if (tree c = omp_find_clause (clauses, code))
12954     error_at (OMP_CLAUSE_LOCATION (c), "too many %qs clauses", name);
12955 }
12956 
12957 /* OpenACC 2.0
12958    Parse wait clause or wait directive parameters.  */
12959 
12960 static tree
c_parser_oacc_wait_list(c_parser * parser,location_t clause_loc,tree list)12961 c_parser_oacc_wait_list (c_parser *parser, location_t clause_loc, tree list)
12962 {
12963   vec<tree, va_gc> *args;
12964   tree t, args_tree;
12965 
12966   matching_parens parens;
12967   if (!parens.require_open (parser))
12968     return list;
12969 
12970   args = c_parser_expr_list (parser, false, true, NULL, NULL, NULL, NULL);
12971   args_tree = build_tree_list_vec (args);
12972 
12973   for (t = args_tree; t; t = TREE_CHAIN (t))
12974     {
12975       tree targ = TREE_VALUE (t);
12976 
12977       if (targ != error_mark_node)
12978 	{
12979 	  if (!INTEGRAL_TYPE_P (TREE_TYPE (targ)))
12980 	    {
12981 	      c_parser_error (parser, "expression must be integral");
12982 	      targ = error_mark_node;
12983 	    }
12984 	  else
12985 	    {
12986 	      tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
12987 
12988 	      OMP_CLAUSE_DECL (c) = targ;
12989 	      OMP_CLAUSE_CHAIN (c) = list;
12990 	      list = c;
12991 	    }
12992 	}
12993     }
12994 
12995   release_tree_vector (args);
12996   parens.require_close (parser);
12997   return list;
12998 }
12999 
13000 /* OpenACC 2.0, OpenMP 2.5:
13001    variable-list:
13002      identifier
13003      variable-list , identifier
13004 
13005    If KIND is nonzero, create the appropriate node and install the
13006    decl in OMP_CLAUSE_DECL and add the node to the head of the list.
13007    If KIND is nonzero, CLAUSE_LOC is the location of the clause.
13008 
13009    If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
13010    return the list created.
13011 
13012    The optional ALLOW_DEREF argument is true if list items can use the deref
13013    (->) operator.  */
13014 
13015 struct omp_dim
13016 {
13017   tree low_bound, length;
13018   location_t loc;
13019   bool no_colon;
omp_dimomp_dim13020   omp_dim (tree lb, tree len, location_t lo, bool nc)
13021   : low_bound (lb), length (len), loc (lo), no_colon (nc) {}
13022 };
13023 
13024 static tree
c_parser_omp_variable_list(c_parser * parser,location_t clause_loc,enum omp_clause_code kind,tree list,bool allow_deref=false)13025 c_parser_omp_variable_list (c_parser *parser,
13026 			    location_t clause_loc,
13027 			    enum omp_clause_code kind, tree list,
13028 			    bool allow_deref = false)
13029 {
13030   auto_vec<omp_dim> dims;
13031   bool array_section_p;
13032   auto_vec<c_token> tokens;
13033   unsigned int tokens_avail = 0;
13034   bool first = true;
13035 
13036   while (1)
13037     {
13038       if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
13039 	{
13040 	  if (c_parser_next_token_is_not (parser, CPP_NAME)
13041 	      || c_parser_peek_token (parser)->id_kind != C_ID_ID)
13042 	    {
13043 	      struct c_expr expr = c_parser_expr_no_commas (parser, NULL);
13044 	      if (expr.value != error_mark_node)
13045 		{
13046 		  tree u = build_omp_clause (clause_loc, kind);
13047 		  OMP_CLAUSE_DECL (u) = expr.value;
13048 		  OMP_CLAUSE_CHAIN (u) = list;
13049 		  list = u;
13050 		}
13051 
13052 	      if (c_parser_next_token_is_not (parser, CPP_COMMA))
13053 		break;
13054 
13055 	      c_parser_consume_token (parser);
13056 	      first = false;
13057 	      continue;
13058 	    }
13059 
13060 	  tokens.truncate (0);
13061 	  unsigned int nesting_depth = 0;
13062 	  while (1)
13063 	    {
13064 	      c_token *token = c_parser_peek_token (parser);
13065 	      switch (token->type)
13066 		{
13067 		case CPP_EOF:
13068 		case CPP_PRAGMA_EOL:
13069 		  break;
13070 		case CPP_OPEN_BRACE:
13071 		case CPP_OPEN_PAREN:
13072 		case CPP_OPEN_SQUARE:
13073 		  ++nesting_depth;
13074 		  goto add;
13075 		case CPP_CLOSE_BRACE:
13076 		case CPP_CLOSE_PAREN:
13077 		case CPP_CLOSE_SQUARE:
13078 		  if (nesting_depth-- == 0)
13079 		    break;
13080 		  goto add;
13081 		case CPP_COMMA:
13082 		  if (nesting_depth == 0)
13083 		    break;
13084 		  goto add;
13085 		default:
13086 		add:
13087 		  tokens.safe_push (*token);
13088 		  c_parser_consume_token (parser);
13089 		  continue;
13090 		}
13091 	      break;
13092 	    }
13093 
13094 	  /* Make sure nothing tries to read past the end of the tokens.  */
13095 	  c_token eof_token;
13096 	  memset (&eof_token, 0, sizeof (eof_token));
13097 	  eof_token.type = CPP_EOF;
13098 	  tokens.safe_push (eof_token);
13099 	  tokens.safe_push (eof_token);
13100 
13101 	  tokens_avail = parser->tokens_avail;
13102 	  gcc_assert (parser->tokens == &parser->tokens_buf[0]);
13103 	  parser->tokens = tokens.address ();
13104 	  parser->tokens_avail = tokens.length ();
13105 	}
13106 
13107       tree t = NULL_TREE;
13108 
13109       if (c_parser_next_token_is (parser, CPP_NAME)
13110 	  && c_parser_peek_token (parser)->id_kind == C_ID_ID)
13111 	{
13112 	  t = lookup_name (c_parser_peek_token (parser)->value);
13113 
13114 	  if (t == NULL_TREE)
13115 	    {
13116 	      undeclared_variable (c_parser_peek_token (parser)->location,
13117 	      c_parser_peek_token (parser)->value);
13118 	      t = error_mark_node;
13119 	    }
13120 
13121 	  c_parser_consume_token (parser);
13122 	}
13123       else if (c_parser_next_token_is (parser, CPP_KEYWORD)
13124 	       && (c_parser_peek_token (parser)->keyword == RID_FUNCTION_NAME
13125 		   || (c_parser_peek_token (parser)->keyword
13126 		       == RID_PRETTY_FUNCTION_NAME)
13127 		   || (c_parser_peek_token (parser)->keyword
13128 		       == RID_C99_FUNCTION_NAME)))
13129 	t = c_parser_predefined_identifier (parser).value;
13130       else
13131 	{
13132 	  if (first)
13133 	    c_parser_error (parser, "expected identifier");
13134 	  break;
13135 	}
13136 
13137       if (t == error_mark_node)
13138 	;
13139       else if (kind != 0)
13140 	{
13141 	  switch (kind)
13142 	    {
13143 	    case OMP_CLAUSE__CACHE_:
13144 	      /* The OpenACC cache directive explicitly only allows "array
13145 		 elements or subarrays".  */
13146 	      if (c_parser_peek_token (parser)->type != CPP_OPEN_SQUARE)
13147 		{
13148 		  c_parser_error (parser, "expected %<[%>");
13149 		  t = error_mark_node;
13150 		  break;
13151 		}
13152 	      /* FALLTHROUGH  */
13153 	    case OMP_CLAUSE_MAP:
13154 	    case OMP_CLAUSE_FROM:
13155 	    case OMP_CLAUSE_TO:
13156 	    start_component_ref:
13157 	      while (c_parser_next_token_is (parser, CPP_DOT)
13158 		     || (allow_deref
13159 			 && c_parser_next_token_is (parser, CPP_DEREF)))
13160 		{
13161 		  location_t op_loc = c_parser_peek_token (parser)->location;
13162 		  if (c_parser_next_token_is (parser, CPP_DEREF))
13163 		    {
13164 		      c_expr t_expr;
13165 		      t_expr.value = t;
13166 		      t_expr.original_code = ERROR_MARK;
13167 		      t_expr.original_type = NULL;
13168 		      set_c_expr_source_range (&t_expr, op_loc, op_loc);
13169 		      t_expr = convert_lvalue_to_rvalue (op_loc, t_expr,
13170 							 true, false);
13171 		      t = build_indirect_ref (op_loc, t_expr.value, RO_ARROW);
13172 		    }
13173 		  c_parser_consume_token (parser);
13174 		  if (!c_parser_next_token_is (parser, CPP_NAME))
13175 		    {
13176 		      c_parser_error (parser, "expected identifier");
13177 		      t = error_mark_node;
13178 		      break;
13179 		    }
13180 
13181 		  c_token *comp_tok = c_parser_peek_token (parser);
13182 		  tree ident = comp_tok->value;
13183 		  location_t comp_loc = comp_tok->location;
13184 		  c_parser_consume_token (parser);
13185 		  t = build_component_ref (op_loc, t, ident, comp_loc);
13186 		}
13187 	      /* FALLTHROUGH  */
13188 	    case OMP_CLAUSE_AFFINITY:
13189 	    case OMP_CLAUSE_DEPEND:
13190 	    case OMP_CLAUSE_REDUCTION:
13191 	    case OMP_CLAUSE_IN_REDUCTION:
13192 	    case OMP_CLAUSE_TASK_REDUCTION:
13193 	    case OMP_CLAUSE_HAS_DEVICE_ADDR:
13194 	      array_section_p = false;
13195 	      dims.truncate (0);
13196 	      while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
13197 		{
13198 		  location_t loc = UNKNOWN_LOCATION;
13199 		  tree low_bound = NULL_TREE, length = NULL_TREE;
13200 		  bool no_colon = false;
13201 
13202 		  c_parser_consume_token (parser);
13203 		  if (!c_parser_next_token_is (parser, CPP_COLON))
13204 		    {
13205 		      location_t expr_loc
13206 			= c_parser_peek_token (parser)->location;
13207 		      c_expr expr = c_parser_expression (parser);
13208 		      expr = convert_lvalue_to_rvalue (expr_loc, expr,
13209 						       false, true);
13210 		      low_bound = expr.value;
13211 		      loc = expr_loc;
13212 		    }
13213 		  if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
13214 		    {
13215 		      length = integer_one_node;
13216 		      no_colon = true;
13217 		    }
13218 		  else
13219 		    {
13220 		      /* Look for `:'.  */
13221 		      if (!c_parser_require (parser, CPP_COLON,
13222 					     "expected %<:%>"))
13223 			{
13224 			  t = error_mark_node;
13225 			  break;
13226 			}
13227 		      array_section_p = true;
13228 		      if (!c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
13229 			{
13230 			  location_t expr_loc
13231 			    = c_parser_peek_token (parser)->location;
13232 			  c_expr expr = c_parser_expression (parser);
13233 			  expr = convert_lvalue_to_rvalue (expr_loc, expr,
13234 							   false, true);
13235 			  length = expr.value;
13236 			}
13237 		    }
13238 		  /* Look for the closing `]'.  */
13239 		  if (!c_parser_require (parser, CPP_CLOSE_SQUARE,
13240 					 "expected %<]%>"))
13241 		    {
13242 		      t = error_mark_node;
13243 		      break;
13244 		    }
13245 
13246 		  dims.safe_push (omp_dim (low_bound, length, loc, no_colon));
13247 		}
13248 
13249 	      if (t != error_mark_node)
13250 		{
13251 		  if ((kind == OMP_CLAUSE_MAP
13252 		       || kind == OMP_CLAUSE_FROM
13253 		       || kind == OMP_CLAUSE_TO)
13254 		      && !array_section_p
13255 		      && (c_parser_next_token_is (parser, CPP_DOT)
13256 			  || (allow_deref
13257 			      && c_parser_next_token_is (parser,
13258 							 CPP_DEREF))))
13259 		    {
13260 		      for (unsigned i = 0; i < dims.length (); i++)
13261 			{
13262 			  gcc_assert (dims[i].length == integer_one_node);
13263 			  t = build_array_ref (dims[i].loc,
13264 					       t, dims[i].low_bound);
13265 			}
13266 		      goto start_component_ref;
13267 		    }
13268 		  else
13269 		    for (unsigned i = 0; i < dims.length (); i++)
13270 		      t = tree_cons (dims[i].low_bound, dims[i].length, t);
13271 		}
13272 
13273 	      if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
13274 		  && t != error_mark_node
13275 		  && parser->tokens_avail != 2)
13276 		{
13277 		  if (array_section_p)
13278 		    {
13279 		      error_at (c_parser_peek_token (parser)->location,
13280 				"expected %<)%> or %<,%>");
13281 		      t = error_mark_node;
13282 		    }
13283 		  else
13284 		    {
13285 		      parser->tokens = tokens.address ();
13286 		      parser->tokens_avail = tokens.length ();
13287 
13288 		      t = c_parser_expr_no_commas (parser, NULL).value;
13289 		      if (t != error_mark_node && parser->tokens_avail != 2)
13290 			{
13291 			  error_at (c_parser_peek_token (parser)->location,
13292 				    "expected %<)%> or %<,%>");
13293 			  t = error_mark_node;
13294 			}
13295 		    }
13296 		}
13297 	      break;
13298 	    default:
13299 	      break;
13300 	    }
13301 
13302 	  if (t != error_mark_node)
13303 	    {
13304 	      tree u = build_omp_clause (clause_loc, kind);
13305 	      OMP_CLAUSE_DECL (u) = t;
13306 	      OMP_CLAUSE_CHAIN (u) = list;
13307 	      list = u;
13308 	    }
13309 	}
13310       else
13311 	list = tree_cons (t, NULL_TREE, list);
13312 
13313       if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
13314 	{
13315 	  parser->tokens = &parser->tokens_buf[0];
13316 	  parser->tokens_avail = tokens_avail;
13317 	}
13318       if (c_parser_next_token_is_not (parser, CPP_COMMA))
13319 	break;
13320 
13321       c_parser_consume_token (parser);
13322       first = false;
13323     }
13324 
13325   return list;
13326 }
13327 
13328 /* Similarly, but expect leading and trailing parenthesis.  This is a very
13329    common case for OpenACC and OpenMP clauses.  The optional ALLOW_DEREF
13330    argument is true if list items can use the deref (->) operator.  */
13331 
13332 static tree
c_parser_omp_var_list_parens(c_parser * parser,enum omp_clause_code kind,tree list,bool allow_deref=false)13333 c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind,
13334 			      tree list, bool allow_deref = false)
13335 {
13336   /* The clauses location.  */
13337   location_t loc = c_parser_peek_token (parser)->location;
13338 
13339   matching_parens parens;
13340   if (parens.require_open (parser))
13341     {
13342       list = c_parser_omp_variable_list (parser, loc, kind, list, allow_deref);
13343       parens.skip_until_found_close (parser);
13344     }
13345   return list;
13346 }
13347 
13348 /* OpenACC 2.0:
13349    copy ( variable-list )
13350    copyin ( variable-list )
13351    copyout ( variable-list )
13352    create ( variable-list )
13353    delete ( variable-list )
13354    present ( variable-list )
13355 
13356    OpenACC 2.6:
13357    no_create ( variable-list )
13358    attach ( variable-list )
13359    detach ( variable-list ) */
13360 
13361 static tree
c_parser_oacc_data_clause(c_parser * parser,pragma_omp_clause c_kind,tree list)13362 c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind,
13363 			   tree list)
13364 {
13365   enum gomp_map_kind kind;
13366   switch (c_kind)
13367     {
13368     case PRAGMA_OACC_CLAUSE_ATTACH:
13369       kind = GOMP_MAP_ATTACH;
13370       break;
13371     case PRAGMA_OACC_CLAUSE_COPY:
13372       kind = GOMP_MAP_TOFROM;
13373       break;
13374     case PRAGMA_OACC_CLAUSE_COPYIN:
13375       kind = GOMP_MAP_TO;
13376       break;
13377     case PRAGMA_OACC_CLAUSE_COPYOUT:
13378       kind = GOMP_MAP_FROM;
13379       break;
13380     case PRAGMA_OACC_CLAUSE_CREATE:
13381       kind = GOMP_MAP_ALLOC;
13382       break;
13383     case PRAGMA_OACC_CLAUSE_DELETE:
13384       kind = GOMP_MAP_RELEASE;
13385       break;
13386     case PRAGMA_OACC_CLAUSE_DETACH:
13387       kind = GOMP_MAP_DETACH;
13388       break;
13389     case PRAGMA_OACC_CLAUSE_DEVICE:
13390       kind = GOMP_MAP_FORCE_TO;
13391       break;
13392     case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
13393       kind = GOMP_MAP_DEVICE_RESIDENT;
13394       break;
13395     case PRAGMA_OACC_CLAUSE_HOST:
13396       kind = GOMP_MAP_FORCE_FROM;
13397       break;
13398     case PRAGMA_OACC_CLAUSE_LINK:
13399       kind = GOMP_MAP_LINK;
13400       break;
13401     case PRAGMA_OACC_CLAUSE_NO_CREATE:
13402       kind = GOMP_MAP_IF_PRESENT;
13403       break;
13404     case PRAGMA_OACC_CLAUSE_PRESENT:
13405       kind = GOMP_MAP_FORCE_PRESENT;
13406       break;
13407     default:
13408       gcc_unreachable ();
13409     }
13410   tree nl, c;
13411   nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_MAP, list, true);
13412 
13413   for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
13414     OMP_CLAUSE_SET_MAP_KIND (c, kind);
13415 
13416   return nl;
13417 }
13418 
13419 /* OpenACC 2.0:
13420    deviceptr ( variable-list ) */
13421 
13422 static tree
c_parser_oacc_data_clause_deviceptr(c_parser * parser,tree list)13423 c_parser_oacc_data_clause_deviceptr (c_parser *parser, tree list)
13424 {
13425   location_t loc = c_parser_peek_token (parser)->location;
13426   tree vars, t;
13427 
13428   /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
13429      c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
13430      variable-list must only allow for pointer variables.  */
13431   vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
13432   for (t = vars; t && t; t = TREE_CHAIN (t))
13433     {
13434       tree v = TREE_PURPOSE (t);
13435 
13436       /* FIXME diagnostics: Ideally we should keep individual
13437 	 locations for all the variables in the var list to make the
13438 	 following errors more precise.  Perhaps
13439 	 c_parser_omp_var_list_parens() should construct a list of
13440 	 locations to go along with the var list.  */
13441 
13442       if (!VAR_P (v) && TREE_CODE (v) != PARM_DECL)
13443 	error_at (loc, "%qD is not a variable", v);
13444       else if (TREE_TYPE (v) == error_mark_node)
13445 	;
13446       else if (!POINTER_TYPE_P (TREE_TYPE (v)))
13447 	error_at (loc, "%qD is not a pointer variable", v);
13448 
13449       tree u = build_omp_clause (loc, OMP_CLAUSE_MAP);
13450       OMP_CLAUSE_SET_MAP_KIND (u, GOMP_MAP_FORCE_DEVICEPTR);
13451       OMP_CLAUSE_DECL (u) = v;
13452       OMP_CLAUSE_CHAIN (u) = list;
13453       list = u;
13454     }
13455 
13456   return list;
13457 }
13458 
13459 /* OpenACC 2.0, OpenMP 3.0:
13460    collapse ( constant-expression ) */
13461 
13462 static tree
c_parser_omp_clause_collapse(c_parser * parser,tree list)13463 c_parser_omp_clause_collapse (c_parser *parser, tree list)
13464 {
13465   tree c, num = error_mark_node;
13466   HOST_WIDE_INT n;
13467   location_t loc;
13468 
13469   check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
13470   check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
13471 
13472   loc = c_parser_peek_token (parser)->location;
13473   matching_parens parens;
13474   if (parens.require_open (parser))
13475     {
13476       num = c_parser_expr_no_commas (parser, NULL).value;
13477       parens.skip_until_found_close (parser);
13478     }
13479   if (num == error_mark_node)
13480     return list;
13481   mark_exp_read (num);
13482   num = c_fully_fold (num, false, NULL);
13483   if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
13484       || !tree_fits_shwi_p (num)
13485       || (n = tree_to_shwi (num)) <= 0
13486       || (int) n != n)
13487     {
13488       error_at (loc,
13489 		"collapse argument needs positive constant integer expression");
13490       return list;
13491     }
13492   c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE);
13493   OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
13494   OMP_CLAUSE_CHAIN (c) = list;
13495   return c;
13496 }
13497 
13498 /* OpenMP 2.5:
13499    copyin ( variable-list ) */
13500 
13501 static tree
c_parser_omp_clause_copyin(c_parser * parser,tree list)13502 c_parser_omp_clause_copyin (c_parser *parser, tree list)
13503 {
13504   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYIN, list);
13505 }
13506 
13507 /* OpenMP 2.5:
13508    copyprivate ( variable-list ) */
13509 
13510 static tree
c_parser_omp_clause_copyprivate(c_parser * parser,tree list)13511 c_parser_omp_clause_copyprivate (c_parser *parser, tree list)
13512 {
13513   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYPRIVATE, list);
13514 }
13515 
13516 /* OpenMP 2.5:
13517    default ( none | shared )
13518 
13519    OpenMP 5.1:
13520    default ( private | firstprivate )
13521 
13522    OpenACC:
13523    default ( none | present ) */
13524 
13525 static tree
c_parser_omp_clause_default(c_parser * parser,tree list,bool is_oacc)13526 c_parser_omp_clause_default (c_parser *parser, tree list, bool is_oacc)
13527 {
13528   enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
13529   location_t loc = c_parser_peek_token (parser)->location;
13530   tree c;
13531 
13532   matching_parens parens;
13533   if (!parens.require_open (parser))
13534     return list;
13535   if (c_parser_next_token_is (parser, CPP_NAME))
13536     {
13537       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13538 
13539       switch (p[0])
13540 	{
13541 	case 'n':
13542 	  if (strcmp ("none", p) != 0)
13543 	    goto invalid_kind;
13544 	  kind = OMP_CLAUSE_DEFAULT_NONE;
13545 	  break;
13546 
13547 	case 'p':
13548 	  if (is_oacc)
13549 	    {
13550 	      if (strcmp ("present", p) != 0)
13551 		goto invalid_kind;
13552 	      kind = OMP_CLAUSE_DEFAULT_PRESENT;
13553 	    }
13554 	  else
13555 	    {
13556 	      if (strcmp ("private", p) != 0)
13557 		goto invalid_kind;
13558 	      kind = OMP_CLAUSE_DEFAULT_PRIVATE;
13559 	    }
13560 	  break;
13561 
13562 	case 'f':
13563 	  if (strcmp ("firstprivate", p) != 0 || is_oacc)
13564 	    goto invalid_kind;
13565 	  kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
13566 	  break;
13567 
13568 	case 's':
13569 	  if (strcmp ("shared", p) != 0 || is_oacc)
13570 	    goto invalid_kind;
13571 	  kind = OMP_CLAUSE_DEFAULT_SHARED;
13572 	  break;
13573 
13574 	default:
13575 	  goto invalid_kind;
13576 	}
13577 
13578       c_parser_consume_token (parser);
13579     }
13580   else
13581     {
13582     invalid_kind:
13583       if (is_oacc)
13584 	c_parser_error (parser, "expected %<none%> or %<present%>");
13585       else
13586 	c_parser_error (parser, "expected %<none%>, %<shared%>, "
13587 				"%<private%> or %<firstprivate%>");
13588     }
13589   parens.skip_until_found_close (parser);
13590 
13591   if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED)
13592     return list;
13593 
13594   check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default");
13595   c = build_omp_clause (loc, OMP_CLAUSE_DEFAULT);
13596   OMP_CLAUSE_CHAIN (c) = list;
13597   OMP_CLAUSE_DEFAULT_KIND (c) = kind;
13598 
13599   return c;
13600 }
13601 
13602 /* OpenMP 2.5:
13603    firstprivate ( variable-list ) */
13604 
13605 static tree
c_parser_omp_clause_firstprivate(c_parser * parser,tree list)13606 c_parser_omp_clause_firstprivate (c_parser *parser, tree list)
13607 {
13608   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FIRSTPRIVATE, list);
13609 }
13610 
13611 /* OpenMP 3.1:
13612    final ( expression ) */
13613 
13614 static tree
c_parser_omp_clause_final(c_parser * parser,tree list)13615 c_parser_omp_clause_final (c_parser *parser, tree list)
13616 {
13617   location_t loc = c_parser_peek_token (parser)->location;
13618   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
13619     {
13620       matching_parens parens;
13621       tree t, c;
13622       if (!parens.require_open (parser))
13623 	t = error_mark_node;
13624       else
13625 	{
13626 	  location_t eloc = c_parser_peek_token (parser)->location;
13627 	  c_expr expr = c_parser_expr_no_commas (parser, NULL);
13628 	  t = convert_lvalue_to_rvalue (eloc, expr, true, true).value;
13629 	  t = c_objc_common_truthvalue_conversion (eloc, t);
13630 	  t = c_fully_fold (t, false, NULL);
13631 	  parens.skip_until_found_close (parser);
13632 	}
13633 
13634       check_no_duplicate_clause (list, OMP_CLAUSE_FINAL, "final");
13635 
13636       c = build_omp_clause (loc, OMP_CLAUSE_FINAL);
13637       OMP_CLAUSE_FINAL_EXPR (c) = t;
13638       OMP_CLAUSE_CHAIN (c) = list;
13639       list = c;
13640     }
13641   else
13642     c_parser_error (parser, "expected %<(%>");
13643 
13644   return list;
13645 }
13646 
13647 /* OpenACC, OpenMP 2.5:
13648    if ( expression )
13649 
13650    OpenMP 4.5:
13651    if ( directive-name-modifier : expression )
13652 
13653    directive-name-modifier:
13654      parallel | task | taskloop | target data | target | target update
13655      | target enter data | target exit data
13656 
13657    OpenMP 5.0:
13658    directive-name-modifier:
13659      ... | simd | cancel  */
13660 
13661 static tree
c_parser_omp_clause_if(c_parser * parser,tree list,bool is_omp)13662 c_parser_omp_clause_if (c_parser *parser, tree list, bool is_omp)
13663 {
13664   location_t location = c_parser_peek_token (parser)->location;
13665   enum tree_code if_modifier = ERROR_MARK;
13666 
13667   matching_parens parens;
13668   if (!parens.require_open (parser))
13669     return list;
13670 
13671   if (is_omp && c_parser_next_token_is (parser, CPP_NAME))
13672     {
13673       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13674       int n = 2;
13675       if (strcmp (p, "cancel") == 0)
13676 	if_modifier = VOID_CST;
13677       else if (strcmp (p, "parallel") == 0)
13678 	if_modifier = OMP_PARALLEL;
13679       else if (strcmp (p, "simd") == 0)
13680 	if_modifier = OMP_SIMD;
13681       else if (strcmp (p, "task") == 0)
13682 	if_modifier = OMP_TASK;
13683       else if (strcmp (p, "taskloop") == 0)
13684 	if_modifier = OMP_TASKLOOP;
13685       else if (strcmp (p, "target") == 0)
13686 	{
13687 	  if_modifier = OMP_TARGET;
13688 	  if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
13689 	    {
13690 	      p = IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser)->value);
13691 	      if (strcmp ("data", p) == 0)
13692 		if_modifier = OMP_TARGET_DATA;
13693 	      else if (strcmp ("update", p) == 0)
13694 		if_modifier = OMP_TARGET_UPDATE;
13695 	      else if (strcmp ("enter", p) == 0)
13696 		if_modifier = OMP_TARGET_ENTER_DATA;
13697 	      else if (strcmp ("exit", p) == 0)
13698 		if_modifier = OMP_TARGET_EXIT_DATA;
13699 	      if (if_modifier != OMP_TARGET)
13700 		{
13701 		  n = 3;
13702 		  c_parser_consume_token (parser);
13703 		}
13704 	      else
13705 		{
13706 		  location_t loc = c_parser_peek_2nd_token (parser)->location;
13707 		  error_at (loc, "expected %<data%>, %<update%>, %<enter%> "
13708 				 "or %<exit%>");
13709 		  if_modifier = ERROR_MARK;
13710 		}
13711 	      if (if_modifier == OMP_TARGET_ENTER_DATA
13712 		  || if_modifier == OMP_TARGET_EXIT_DATA)
13713 		{
13714 		  if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
13715 		    {
13716 		      p = IDENTIFIER_POINTER
13717 				(c_parser_peek_2nd_token (parser)->value);
13718 		      if (strcmp ("data", p) == 0)
13719 			n = 4;
13720 		    }
13721 		  if (n == 4)
13722 		    c_parser_consume_token (parser);
13723 		  else
13724 		    {
13725 		      location_t loc
13726 			= c_parser_peek_2nd_token (parser)->location;
13727 		      error_at (loc, "expected %<data%>");
13728 		      if_modifier = ERROR_MARK;
13729 		    }
13730 		}
13731 	    }
13732 	}
13733       if (if_modifier != ERROR_MARK)
13734 	{
13735 	  if (c_parser_peek_2nd_token (parser)->type == CPP_COLON)
13736 	    {
13737 	      c_parser_consume_token (parser);
13738 	      c_parser_consume_token (parser);
13739 	    }
13740 	  else
13741 	    {
13742 	      if (n > 2)
13743 		{
13744 		  location_t loc = c_parser_peek_2nd_token (parser)->location;
13745 		  error_at (loc, "expected %<:%>");
13746 		}
13747 	      if_modifier = ERROR_MARK;
13748 	    }
13749 	}
13750     }
13751 
13752   location_t loc = c_parser_peek_token (parser)->location;
13753   c_expr expr = c_parser_expr_no_commas (parser, NULL);
13754   expr = convert_lvalue_to_rvalue (loc, expr, true, true);
13755   tree t = c_objc_common_truthvalue_conversion (loc, expr.value), c;
13756   t = c_fully_fold (t, false, NULL);
13757   parens.skip_until_found_close (parser);
13758 
13759   for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
13760     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF)
13761       {
13762 	if (if_modifier != ERROR_MARK
13763 	    && OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
13764 	  {
13765 	    const char *p = NULL;
13766 	    switch (if_modifier)
13767 	      {
13768 	      case VOID_CST: p = "cancel"; break;
13769 	      case OMP_PARALLEL: p = "parallel"; break;
13770 	      case OMP_SIMD: p = "simd"; break;
13771 	      case OMP_TASK: p = "task"; break;
13772 	      case OMP_TASKLOOP: p = "taskloop"; break;
13773 	      case OMP_TARGET_DATA: p = "target data"; break;
13774 	      case OMP_TARGET: p = "target"; break;
13775 	      case OMP_TARGET_UPDATE: p = "target update"; break;
13776 	      case OMP_TARGET_ENTER_DATA: p = "target enter data"; break;
13777 	      case OMP_TARGET_EXIT_DATA: p = "target exit data"; break;
13778 	      default: gcc_unreachable ();
13779 	      }
13780 	    error_at (location, "too many %<if%> clauses with %qs modifier",
13781 		      p);
13782 	    return list;
13783 	  }
13784 	else if (OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
13785 	  {
13786 	    if (!is_omp)
13787 	      error_at (location, "too many %<if%> clauses");
13788 	    else
13789 	      error_at (location, "too many %<if%> clauses without modifier");
13790 	    return list;
13791 	  }
13792 	else if (if_modifier == ERROR_MARK
13793 		 || OMP_CLAUSE_IF_MODIFIER (c) == ERROR_MARK)
13794 	  {
13795 	    error_at (location, "if any %<if%> clause has modifier, then all "
13796 				"%<if%> clauses have to use modifier");
13797 	    return list;
13798 	  }
13799       }
13800 
13801   c = build_omp_clause (location, OMP_CLAUSE_IF);
13802   OMP_CLAUSE_IF_MODIFIER (c) = if_modifier;
13803   OMP_CLAUSE_IF_EXPR (c) = t;
13804   OMP_CLAUSE_CHAIN (c) = list;
13805   return c;
13806 }
13807 
13808 /* OpenMP 2.5:
13809    lastprivate ( variable-list )
13810 
13811    OpenMP 5.0:
13812    lastprivate ( [ lastprivate-modifier : ] variable-list ) */
13813 
13814 static tree
c_parser_omp_clause_lastprivate(c_parser * parser,tree list)13815 c_parser_omp_clause_lastprivate (c_parser *parser, tree list)
13816 {
13817   /* The clauses location.  */
13818   location_t loc = c_parser_peek_token (parser)->location;
13819 
13820   if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
13821     {
13822       bool conditional = false;
13823       if (c_parser_next_token_is (parser, CPP_NAME)
13824 	  && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
13825 	{
13826 	  const char *p
13827 	    = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13828 	  if (strcmp (p, "conditional") == 0)
13829 	    {
13830 	      conditional = true;
13831 	      c_parser_consume_token (parser);
13832 	      c_parser_consume_token (parser);
13833 	    }
13834 	}
13835       tree nlist = c_parser_omp_variable_list (parser, loc,
13836 					       OMP_CLAUSE_LASTPRIVATE, list);
13837       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
13838       if (conditional)
13839 	for (tree c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
13840 	  OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 1;
13841       return nlist;
13842     }
13843   return list;
13844 }
13845 
13846 /* OpenMP 3.1:
13847    mergeable */
13848 
13849 static tree
c_parser_omp_clause_mergeable(c_parser * parser ATTRIBUTE_UNUSED,tree list)13850 c_parser_omp_clause_mergeable (c_parser *parser ATTRIBUTE_UNUSED, tree list)
13851 {
13852   tree c;
13853 
13854   /* FIXME: Should we allow duplicates?  */
13855   check_no_duplicate_clause (list, OMP_CLAUSE_MERGEABLE, "mergeable");
13856 
13857   c = build_omp_clause (c_parser_peek_token (parser)->location,
13858 			OMP_CLAUSE_MERGEABLE);
13859   OMP_CLAUSE_CHAIN (c) = list;
13860 
13861   return c;
13862 }
13863 
13864 /* OpenMP 2.5:
13865    nowait */
13866 
13867 static tree
c_parser_omp_clause_nowait(c_parser * parser ATTRIBUTE_UNUSED,tree list)13868 c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list)
13869 {
13870   tree c;
13871   location_t loc = c_parser_peek_token (parser)->location;
13872 
13873   check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait");
13874 
13875   c = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
13876   OMP_CLAUSE_CHAIN (c) = list;
13877   return c;
13878 }
13879 
13880 /* OpenMP 2.5:
13881    num_threads ( expression ) */
13882 
13883 static tree
c_parser_omp_clause_num_threads(c_parser * parser,tree list)13884 c_parser_omp_clause_num_threads (c_parser *parser, tree list)
13885 {
13886   location_t num_threads_loc = c_parser_peek_token (parser)->location;
13887   matching_parens parens;
13888   if (parens.require_open (parser))
13889     {
13890       location_t expr_loc = c_parser_peek_token (parser)->location;
13891       c_expr expr = c_parser_expr_no_commas (parser, NULL);
13892       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13893       tree c, t = expr.value;
13894       t = c_fully_fold (t, false, NULL);
13895 
13896       parens.skip_until_found_close (parser);
13897 
13898       if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13899 	{
13900 	  c_parser_error (parser, "expected integer expression");
13901 	  return list;
13902 	}
13903 
13904       /* Attempt to statically determine when the number isn't positive.  */
13905       c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13906 		       build_int_cst (TREE_TYPE (t), 0));
13907       protected_set_expr_location (c, expr_loc);
13908       if (c == boolean_true_node)
13909 	{
13910 	  warning_at (expr_loc, 0,
13911 		      "%<num_threads%> value must be positive");
13912 	  t = integer_one_node;
13913 	}
13914 
13915       check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads");
13916 
13917       c = build_omp_clause (num_threads_loc, OMP_CLAUSE_NUM_THREADS);
13918       OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
13919       OMP_CLAUSE_CHAIN (c) = list;
13920       list = c;
13921     }
13922 
13923   return list;
13924 }
13925 
13926 /* OpenMP 4.5:
13927    num_tasks ( expression )
13928 
13929    OpenMP 5.1:
13930    num_tasks ( strict : expression ) */
13931 
13932 static tree
c_parser_omp_clause_num_tasks(c_parser * parser,tree list)13933 c_parser_omp_clause_num_tasks (c_parser *parser, tree list)
13934 {
13935   location_t num_tasks_loc = c_parser_peek_token (parser)->location;
13936   matching_parens parens;
13937   if (parens.require_open (parser))
13938     {
13939       bool strict = false;
13940       if (c_parser_next_token_is (parser, CPP_NAME)
13941 	  && c_parser_peek_2nd_token (parser)->type == CPP_COLON
13942 	  && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
13943 		     "strict") == 0)
13944 	{
13945 	  strict = true;
13946 	  c_parser_consume_token (parser);
13947 	  c_parser_consume_token (parser);
13948 	}
13949 
13950       location_t expr_loc = c_parser_peek_token (parser)->location;
13951       c_expr expr = c_parser_expr_no_commas (parser, NULL);
13952       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13953       tree c, t = expr.value;
13954       t = c_fully_fold (t, false, NULL);
13955 
13956       parens.skip_until_found_close (parser);
13957 
13958       if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13959 	{
13960 	  c_parser_error (parser, "expected integer expression");
13961 	  return list;
13962 	}
13963 
13964       /* Attempt to statically determine when the number isn't positive.  */
13965       c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13966 			   build_int_cst (TREE_TYPE (t), 0));
13967       if (CAN_HAVE_LOCATION_P (c))
13968 	SET_EXPR_LOCATION (c, expr_loc);
13969       if (c == boolean_true_node)
13970 	{
13971 	  warning_at (expr_loc, 0, "%<num_tasks%> value must be positive");
13972 	  t = integer_one_node;
13973 	}
13974 
13975       check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TASKS, "num_tasks");
13976 
13977       c = build_omp_clause (num_tasks_loc, OMP_CLAUSE_NUM_TASKS);
13978       OMP_CLAUSE_NUM_TASKS_EXPR (c) = t;
13979       OMP_CLAUSE_NUM_TASKS_STRICT (c) = strict;
13980       OMP_CLAUSE_CHAIN (c) = list;
13981       list = c;
13982     }
13983 
13984   return list;
13985 }
13986 
13987 /* OpenMP 4.5:
13988    grainsize ( expression )
13989 
13990    OpenMP 5.1:
13991    grainsize ( strict : expression ) */
13992 
13993 static tree
c_parser_omp_clause_grainsize(c_parser * parser,tree list)13994 c_parser_omp_clause_grainsize (c_parser *parser, tree list)
13995 {
13996   location_t grainsize_loc = c_parser_peek_token (parser)->location;
13997   matching_parens parens;
13998   if (parens.require_open (parser))
13999     {
14000       bool strict = false;
14001       if (c_parser_next_token_is (parser, CPP_NAME)
14002 	  && c_parser_peek_2nd_token (parser)->type == CPP_COLON
14003 	  && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
14004 		     "strict") == 0)
14005 	{
14006 	  strict = true;
14007 	  c_parser_consume_token (parser);
14008 	  c_parser_consume_token (parser);
14009 	}
14010 
14011       location_t expr_loc = c_parser_peek_token (parser)->location;
14012       c_expr expr = c_parser_expr_no_commas (parser, NULL);
14013       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14014       tree c, t = expr.value;
14015       t = c_fully_fold (t, false, NULL);
14016 
14017       parens.skip_until_found_close (parser);
14018 
14019       if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14020 	{
14021 	  c_parser_error (parser, "expected integer expression");
14022 	  return list;
14023 	}
14024 
14025       /* Attempt to statically determine when the number isn't positive.  */
14026       c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14027 			   build_int_cst (TREE_TYPE (t), 0));
14028       if (CAN_HAVE_LOCATION_P (c))
14029 	SET_EXPR_LOCATION (c, expr_loc);
14030       if (c == boolean_true_node)
14031 	{
14032 	  warning_at (expr_loc, 0, "%<grainsize%> value must be positive");
14033 	  t = integer_one_node;
14034 	}
14035 
14036       check_no_duplicate_clause (list, OMP_CLAUSE_GRAINSIZE, "grainsize");
14037 
14038       c = build_omp_clause (grainsize_loc, OMP_CLAUSE_GRAINSIZE);
14039       OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
14040       OMP_CLAUSE_GRAINSIZE_STRICT (c) = strict;
14041       OMP_CLAUSE_CHAIN (c) = list;
14042       list = c;
14043     }
14044 
14045   return list;
14046 }
14047 
14048 /* OpenMP 4.5:
14049    priority ( expression ) */
14050 
14051 static tree
c_parser_omp_clause_priority(c_parser * parser,tree list)14052 c_parser_omp_clause_priority (c_parser *parser, tree list)
14053 {
14054   location_t priority_loc = c_parser_peek_token (parser)->location;
14055   matching_parens parens;
14056   if (parens.require_open (parser))
14057     {
14058       location_t expr_loc = c_parser_peek_token (parser)->location;
14059       c_expr expr = c_parser_expr_no_commas (parser, NULL);
14060       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14061       tree c, t = expr.value;
14062       t = c_fully_fold (t, false, NULL);
14063 
14064       parens.skip_until_found_close (parser);
14065 
14066       if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14067 	{
14068 	  c_parser_error (parser, "expected integer expression");
14069 	  return list;
14070 	}
14071 
14072       /* Attempt to statically determine when the number isn't
14073 	 non-negative.  */
14074       c = fold_build2_loc (expr_loc, LT_EXPR, boolean_type_node, t,
14075 			   build_int_cst (TREE_TYPE (t), 0));
14076       if (CAN_HAVE_LOCATION_P (c))
14077 	SET_EXPR_LOCATION (c, expr_loc);
14078       if (c == boolean_true_node)
14079 	{
14080 	  warning_at (expr_loc, 0, "%<priority%> value must be non-negative");
14081 	  t = integer_one_node;
14082 	}
14083 
14084       check_no_duplicate_clause (list, OMP_CLAUSE_PRIORITY, "priority");
14085 
14086       c = build_omp_clause (priority_loc, OMP_CLAUSE_PRIORITY);
14087       OMP_CLAUSE_PRIORITY_EXPR (c) = t;
14088       OMP_CLAUSE_CHAIN (c) = list;
14089       list = c;
14090     }
14091 
14092   return list;
14093 }
14094 
14095 /* OpenMP 4.5:
14096    hint ( expression ) */
14097 
14098 static tree
c_parser_omp_clause_hint(c_parser * parser,tree list)14099 c_parser_omp_clause_hint (c_parser *parser, tree list)
14100 {
14101   location_t hint_loc = c_parser_peek_token (parser)->location;
14102   matching_parens parens;
14103   if (parens.require_open (parser))
14104     {
14105       location_t expr_loc = c_parser_peek_token (parser)->location;
14106       c_expr expr = c_parser_expr_no_commas (parser, NULL);
14107       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14108       tree c, t = expr.value;
14109       t = c_fully_fold (t, false, NULL);
14110       if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
14111 	  || TREE_CODE (t) != INTEGER_CST
14112 	  || tree_int_cst_sgn (t) == -1)
14113 	{
14114 	  c_parser_error (parser, "expected constant integer expression "
14115 				  "with valid sync-hint value");
14116 	  return list;
14117 	}
14118       parens.skip_until_found_close (parser);
14119       check_no_duplicate_clause (list, OMP_CLAUSE_HINT, "hint");
14120 
14121       c = build_omp_clause (hint_loc, OMP_CLAUSE_HINT);
14122       OMP_CLAUSE_HINT_EXPR (c) = t;
14123       OMP_CLAUSE_CHAIN (c) = list;
14124       list = c;
14125     }
14126 
14127   return list;
14128 }
14129 
14130 /* OpenMP 5.1:
14131    filter ( integer-expression ) */
14132 
14133 static tree
c_parser_omp_clause_filter(c_parser * parser,tree list)14134 c_parser_omp_clause_filter (c_parser *parser, tree list)
14135 {
14136   location_t hint_loc = c_parser_peek_token (parser)->location;
14137   matching_parens parens;
14138   if (parens.require_open (parser))
14139     {
14140       location_t expr_loc = c_parser_peek_token (parser)->location;
14141       c_expr expr = c_parser_expr_no_commas (parser, NULL);
14142       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14143       tree c, t = expr.value;
14144       t = c_fully_fold (t, false, NULL);
14145       if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14146 	{
14147 	  c_parser_error (parser, "expected integer expression");
14148 	  return list;
14149 	}
14150       parens.skip_until_found_close (parser);
14151       check_no_duplicate_clause (list, OMP_CLAUSE_FILTER, "filter");
14152 
14153       c = build_omp_clause (hint_loc, OMP_CLAUSE_FILTER);
14154       OMP_CLAUSE_FILTER_EXPR (c) = t;
14155       OMP_CLAUSE_CHAIN (c) = list;
14156       list = c;
14157     }
14158 
14159   return list;
14160 }
14161 
14162 /* OpenMP 4.5:
14163    defaultmap ( tofrom : scalar )
14164 
14165    OpenMP 5.0:
14166    defaultmap ( implicit-behavior [ : variable-category ] ) */
14167 
14168 static tree
c_parser_omp_clause_defaultmap(c_parser * parser,tree list)14169 c_parser_omp_clause_defaultmap (c_parser *parser, tree list)
14170 {
14171   location_t loc = c_parser_peek_token (parser)->location;
14172   tree c;
14173   const char *p;
14174   enum omp_clause_defaultmap_kind behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
14175   enum omp_clause_defaultmap_kind category
14176     = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
14177 
14178   matching_parens parens;
14179   if (!parens.require_open (parser))
14180     return list;
14181   if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
14182     p = "default";
14183   else if (!c_parser_next_token_is (parser, CPP_NAME))
14184     {
14185     invalid_behavior:
14186       c_parser_error (parser, "expected %<alloc%>, %<to%>, %<from%>, "
14187 			      "%<tofrom%>, %<firstprivate%>, %<none%> "
14188 			      "or %<default%>");
14189       goto out_err;
14190     }
14191   else
14192     p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14193 
14194   switch (p[0])
14195     {
14196     case 'a':
14197       if (strcmp ("alloc", p) == 0)
14198 	behavior = OMP_CLAUSE_DEFAULTMAP_ALLOC;
14199       else
14200 	goto invalid_behavior;
14201       break;
14202 
14203     case 'd':
14204       if (strcmp ("default", p) == 0)
14205 	behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
14206       else
14207 	goto invalid_behavior;
14208       break;
14209 
14210     case 'f':
14211       if (strcmp ("firstprivate", p) == 0)
14212 	behavior = OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
14213       else if (strcmp ("from", p) == 0)
14214 	behavior = OMP_CLAUSE_DEFAULTMAP_FROM;
14215       else
14216 	goto invalid_behavior;
14217       break;
14218 
14219     case 'n':
14220       if (strcmp ("none", p) == 0)
14221 	behavior = OMP_CLAUSE_DEFAULTMAP_NONE;
14222       else
14223 	goto invalid_behavior;
14224       break;
14225 
14226     case 't':
14227       if (strcmp ("tofrom", p) == 0)
14228 	behavior = OMP_CLAUSE_DEFAULTMAP_TOFROM;
14229       else if (strcmp ("to", p) == 0)
14230 	behavior = OMP_CLAUSE_DEFAULTMAP_TO;
14231       else
14232 	goto invalid_behavior;
14233       break;
14234 
14235     default:
14236       goto invalid_behavior;
14237     }
14238   c_parser_consume_token (parser);
14239 
14240   if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
14241     {
14242       if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14243 	goto out_err;
14244       if (!c_parser_next_token_is (parser, CPP_NAME))
14245 	{
14246 	invalid_category:
14247 	  c_parser_error (parser, "expected %<scalar%>, %<aggregate%> or "
14248 				  "%<pointer%>");
14249 	  goto out_err;
14250 	}
14251       p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14252       switch (p[0])
14253 	{
14254 	case 'a':
14255 	  if (strcmp ("aggregate", p) == 0)
14256 	    category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE;
14257 	  else
14258 	    goto invalid_category;
14259 	  break;
14260 
14261 	case 'p':
14262 	  if (strcmp ("pointer", p) == 0)
14263 	    category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER;
14264 	  else
14265 	    goto invalid_category;
14266 	  break;
14267 
14268 	case 's':
14269 	  if (strcmp ("scalar", p) == 0)
14270 	    category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR;
14271 	  else
14272 	    goto invalid_category;
14273 	  break;
14274 
14275 	default:
14276 	  goto invalid_category;
14277 	}
14278 
14279       c_parser_consume_token (parser);
14280     }
14281   parens.skip_until_found_close (parser);
14282 
14283   for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
14284     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEFAULTMAP
14285 	&& (category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
14286 	    || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c) == category
14287 	    || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
14288 		== OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)))
14289       {
14290 	enum omp_clause_defaultmap_kind cat = category;
14291 	location_t loc = OMP_CLAUSE_LOCATION (c);
14292 	if (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
14293 	  cat = OMP_CLAUSE_DEFAULTMAP_CATEGORY (c);
14294 	p = NULL;
14295 	switch (cat)
14296 	  {
14297 	  case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
14298 	    p = NULL;
14299 	    break;
14300 	  case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
14301 	    p = "aggregate";
14302 	    break;
14303 	  case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
14304 	    p = "pointer";
14305 	    break;
14306 	  case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
14307 	    p = "scalar";
14308 	    break;
14309 	  default:
14310 	    gcc_unreachable ();
14311 	  }
14312 	if (p)
14313 	  error_at (loc, "too many %<defaultmap%> clauses with %qs category",
14314 		    p);
14315 	else
14316 	  error_at (loc, "too many %<defaultmap%> clauses with unspecified "
14317 			 "category");
14318 	break;
14319       }
14320 
14321   c = build_omp_clause (loc, OMP_CLAUSE_DEFAULTMAP);
14322   OMP_CLAUSE_DEFAULTMAP_SET_KIND (c, behavior, category);
14323   OMP_CLAUSE_CHAIN (c) = list;
14324   return c;
14325 
14326  out_err:
14327   parens.skip_until_found_close (parser);
14328   return list;
14329 }
14330 
14331 /* OpenACC 2.0:
14332    use_device ( variable-list )
14333 
14334    OpenMP 4.5:
14335    use_device_ptr ( variable-list ) */
14336 
14337 static tree
c_parser_omp_clause_use_device_ptr(c_parser * parser,tree list)14338 c_parser_omp_clause_use_device_ptr (c_parser *parser, tree list)
14339 {
14340   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_PTR,
14341 				       list);
14342 }
14343 
14344 /* OpenMP 5.0:
14345    use_device_addr ( variable-list ) */
14346 
14347 static tree
c_parser_omp_clause_use_device_addr(c_parser * parser,tree list)14348 c_parser_omp_clause_use_device_addr (c_parser *parser, tree list)
14349 {
14350   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_ADDR,
14351 				       list);
14352 }
14353 
14354 /* OpenMP 5.1:
14355    has_device_addr ( variable-list ) */
14356 
14357 static tree
c_parser_omp_clause_has_device_addr(c_parser * parser,tree list)14358 c_parser_omp_clause_has_device_addr (c_parser *parser, tree list)
14359 {
14360   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_HAS_DEVICE_ADDR,
14361 				       list);
14362 }
14363 
14364 /* OpenMP 4.5:
14365    is_device_ptr ( variable-list ) */
14366 
14367 static tree
c_parser_omp_clause_is_device_ptr(c_parser * parser,tree list)14368 c_parser_omp_clause_is_device_ptr (c_parser *parser, tree list)
14369 {
14370   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_IS_DEVICE_PTR, list);
14371 }
14372 
14373 /* OpenACC:
14374    num_gangs ( expression )
14375    num_workers ( expression )
14376    vector_length ( expression )  */
14377 
14378 static tree
c_parser_oacc_single_int_clause(c_parser * parser,omp_clause_code code,tree list)14379 c_parser_oacc_single_int_clause (c_parser *parser, omp_clause_code code,
14380 				 tree list)
14381 {
14382   location_t loc = c_parser_peek_token (parser)->location;
14383 
14384   matching_parens parens;
14385   if (!parens.require_open (parser))
14386     return list;
14387 
14388   location_t expr_loc = c_parser_peek_token (parser)->location;
14389   c_expr expr = c_parser_expression (parser);
14390   expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14391   tree c, t = expr.value;
14392   t = c_fully_fold (t, false, NULL);
14393 
14394   parens.skip_until_found_close (parser);
14395 
14396   if (t == error_mark_node)
14397     return list;
14398   else if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14399     {
14400       error_at (expr_loc, "%qs expression must be integral",
14401 		omp_clause_code_name[code]);
14402       return list;
14403     }
14404 
14405   /* Attempt to statically determine when the number isn't positive.  */
14406   c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14407 		       build_int_cst (TREE_TYPE (t), 0));
14408   protected_set_expr_location (c, expr_loc);
14409   if (c == boolean_true_node)
14410     {
14411       warning_at (expr_loc, 0,
14412 		  "%qs value must be positive",
14413 		  omp_clause_code_name[code]);
14414       t = integer_one_node;
14415     }
14416 
14417   check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14418 
14419   c = build_omp_clause (loc, code);
14420   OMP_CLAUSE_OPERAND (c, 0) = t;
14421   OMP_CLAUSE_CHAIN (c) = list;
14422   return c;
14423 }
14424 
14425 /* OpenACC:
14426 
14427     gang [( gang-arg-list )]
14428     worker [( [num:] int-expr )]
14429     vector [( [length:] int-expr )]
14430 
14431   where gang-arg is one of:
14432 
14433     [num:] int-expr
14434     static: size-expr
14435 
14436   and size-expr may be:
14437 
14438     *
14439     int-expr
14440 */
14441 
14442 static tree
c_parser_oacc_shape_clause(c_parser * parser,location_t loc,omp_clause_code kind,const char * str,tree list)14443 c_parser_oacc_shape_clause (c_parser *parser, location_t loc,
14444 			    omp_clause_code kind,
14445 			    const char *str, tree list)
14446 {
14447   const char *id = "num";
14448   tree ops[2] = { NULL_TREE, NULL_TREE }, c;
14449 
14450   if (kind == OMP_CLAUSE_VECTOR)
14451     id = "length";
14452 
14453   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14454     {
14455       c_parser_consume_token (parser);
14456 
14457       do
14458 	{
14459 	  c_token *next = c_parser_peek_token (parser);
14460 	  int idx = 0;
14461 
14462 	  /* Gang static argument.  */
14463 	  if (kind == OMP_CLAUSE_GANG
14464 	      && c_parser_next_token_is_keyword (parser, RID_STATIC))
14465 	    {
14466 	      c_parser_consume_token (parser);
14467 
14468 	      if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14469 		goto cleanup_error;
14470 
14471 	      idx = 1;
14472 	      if (ops[idx] != NULL_TREE)
14473 		{
14474 		  c_parser_error (parser, "too many %<static%> arguments");
14475 		  goto cleanup_error;
14476 		}
14477 
14478 	      /* Check for the '*' argument.  */
14479 	      if (c_parser_next_token_is (parser, CPP_MULT)
14480 		  && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
14481 		      || c_parser_peek_2nd_token (parser)->type
14482 		         == CPP_CLOSE_PAREN))
14483 		{
14484 		  c_parser_consume_token (parser);
14485 		  ops[idx] = integer_minus_one_node;
14486 
14487 		  if (c_parser_next_token_is (parser, CPP_COMMA))
14488 		    {
14489 		      c_parser_consume_token (parser);
14490 		      continue;
14491 		    }
14492 		  else
14493 		    break;
14494 		}
14495 	    }
14496 	  /* Worker num: argument and vector length: arguments.  */
14497 	  else if (c_parser_next_token_is (parser, CPP_NAME)
14498 		   && strcmp (id, IDENTIFIER_POINTER (next->value)) == 0
14499 		   && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
14500 	    {
14501 	      c_parser_consume_token (parser);  /* id  */
14502 	      c_parser_consume_token (parser);  /* ':'  */
14503 	    }
14504 
14505 	  /* Now collect the actual argument.  */
14506 	  if (ops[idx] != NULL_TREE)
14507 	    {
14508 	      c_parser_error (parser, "unexpected argument");
14509 	      goto cleanup_error;
14510 	    }
14511 
14512 	  location_t expr_loc = c_parser_peek_token (parser)->location;
14513 	  c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
14514 	  cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
14515 	  tree expr = cexpr.value;
14516 	  if (expr == error_mark_node)
14517 	    goto cleanup_error;
14518 
14519 	  expr = c_fully_fold (expr, false, NULL);
14520 
14521 	  /* Attempt to statically determine when the number isn't a
14522 	     positive integer.  */
14523 
14524 	  if (!INTEGRAL_TYPE_P (TREE_TYPE (expr)))
14525 	    {
14526 	      c_parser_error (parser, "expected integer expression");
14527 	      return list;
14528 	    }
14529 
14530 	  tree c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, expr,
14531 				    build_int_cst (TREE_TYPE (expr), 0));
14532 	  if (c == boolean_true_node)
14533 	    {
14534 	      warning_at (loc, 0,
14535 			  "%qs value must be positive", str);
14536 	      expr = integer_one_node;
14537 	    }
14538 
14539 	  ops[idx] = expr;
14540 
14541 	  if (kind == OMP_CLAUSE_GANG
14542 	      && c_parser_next_token_is (parser, CPP_COMMA))
14543 	    {
14544 	      c_parser_consume_token (parser);
14545 	      continue;
14546 	    }
14547 	  break;
14548 	}
14549       while (1);
14550 
14551       if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
14552 	goto cleanup_error;
14553     }
14554 
14555   check_no_duplicate_clause (list, kind, str);
14556 
14557   c = build_omp_clause (loc, kind);
14558 
14559   if (ops[1])
14560     OMP_CLAUSE_OPERAND (c, 1) = ops[1];
14561 
14562   OMP_CLAUSE_OPERAND (c, 0) = ops[0];
14563   OMP_CLAUSE_CHAIN (c) = list;
14564 
14565   return c;
14566 
14567  cleanup_error:
14568   c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
14569   return list;
14570 }
14571 
14572 /* OpenACC 2.5:
14573    auto
14574    finalize
14575    independent
14576    nohost
14577    seq */
14578 
14579 static tree
c_parser_oacc_simple_clause(location_t loc,enum omp_clause_code code,tree list)14580 c_parser_oacc_simple_clause (location_t loc, enum omp_clause_code code,
14581 			     tree list)
14582 {
14583   check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14584 
14585   tree c = build_omp_clause (loc, code);
14586   OMP_CLAUSE_CHAIN (c) = list;
14587 
14588   return c;
14589 }
14590 
14591 /* OpenACC:
14592    async [( int-expr )] */
14593 
14594 static tree
c_parser_oacc_clause_async(c_parser * parser,tree list)14595 c_parser_oacc_clause_async (c_parser *parser, tree list)
14596 {
14597   tree c, t;
14598   location_t loc = c_parser_peek_token (parser)->location;
14599 
14600   t = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
14601 
14602   if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
14603     {
14604       c_parser_consume_token (parser);
14605 
14606       t = c_parser_expr_no_commas (parser, NULL).value;
14607       if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14608 	c_parser_error (parser, "expected integer expression");
14609       else if (t == error_mark_node
14610 	  || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
14611 	return list;
14612     }
14613   else
14614     t = c_fully_fold (t, false, NULL);
14615 
14616   check_no_duplicate_clause (list, OMP_CLAUSE_ASYNC, "async");
14617 
14618   c = build_omp_clause (loc, OMP_CLAUSE_ASYNC);
14619   OMP_CLAUSE_ASYNC_EXPR (c) = t;
14620   OMP_CLAUSE_CHAIN (c) = list;
14621   list = c;
14622 
14623   return list;
14624 }
14625 
14626 /* OpenACC 2.0:
14627    tile ( size-expr-list ) */
14628 
14629 static tree
c_parser_oacc_clause_tile(c_parser * parser,tree list)14630 c_parser_oacc_clause_tile (c_parser *parser, tree list)
14631 {
14632   tree c, expr = error_mark_node;
14633   location_t loc;
14634   tree tile = NULL_TREE;
14635 
14636   check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
14637   check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
14638 
14639   loc = c_parser_peek_token (parser)->location;
14640   if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
14641     return list;
14642 
14643   do
14644     {
14645       if (tile && !c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
14646 	return list;
14647 
14648       if (c_parser_next_token_is (parser, CPP_MULT)
14649 	  && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
14650 	      || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
14651 	{
14652 	  c_parser_consume_token (parser);
14653 	  expr = integer_zero_node;
14654 	}
14655       else
14656 	{
14657 	  location_t expr_loc = c_parser_peek_token (parser)->location;
14658 	  c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
14659 	  cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
14660 	  expr = cexpr.value;
14661 
14662 	  if (expr == error_mark_node)
14663 	    {
14664 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
14665 					 "expected %<)%>");
14666 	      return list;
14667 	    }
14668 
14669 	  expr = c_fully_fold (expr, false, NULL);
14670 
14671 	  if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
14672 	      || !tree_fits_shwi_p (expr)
14673 	      || tree_to_shwi (expr) <= 0)
14674 	    {
14675 	      error_at (expr_loc, "%<tile%> argument needs positive"
14676 			" integral constant");
14677 	      expr = integer_zero_node;
14678 	    }
14679 	}
14680 
14681       tile = tree_cons (NULL_TREE, expr, tile);
14682     }
14683   while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN));
14684 
14685   /* Consume the trailing ')'.  */
14686   c_parser_consume_token (parser);
14687 
14688   c = build_omp_clause (loc, OMP_CLAUSE_TILE);
14689   tile = nreverse (tile);
14690   OMP_CLAUSE_TILE_LIST (c) = tile;
14691   OMP_CLAUSE_CHAIN (c) = list;
14692   return c;
14693 }
14694 
14695 /* OpenACC:
14696    wait [( int-expr-list )] */
14697 
14698 static tree
c_parser_oacc_clause_wait(c_parser * parser,tree list)14699 c_parser_oacc_clause_wait (c_parser *parser, tree list)
14700 {
14701   location_t clause_loc = c_parser_peek_token (parser)->location;
14702 
14703   if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
14704     list = c_parser_oacc_wait_list (parser, clause_loc, list);
14705   else
14706     {
14707       tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
14708 
14709       OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
14710       OMP_CLAUSE_CHAIN (c) = list;
14711       list = c;
14712     }
14713 
14714   return list;
14715 }
14716 
14717 
14718 /* OpenMP 5.0:
14719    order ( concurrent )
14720 
14721    OpenMP 5.1:
14722    order ( order-modifier : concurrent )
14723 
14724    order-modifier:
14725      reproducible
14726      unconstrained  */
14727 
14728 static tree
c_parser_omp_clause_order(c_parser * parser,tree list)14729 c_parser_omp_clause_order (c_parser *parser, tree list)
14730 {
14731   location_t loc = c_parser_peek_token (parser)->location;
14732   tree c;
14733   const char *p;
14734   bool unconstrained = false;
14735   bool reproducible = false;
14736 
14737   matching_parens parens;
14738   if (!parens.require_open (parser))
14739     return list;
14740   if (c_parser_next_token_is (parser, CPP_NAME)
14741       && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
14742     {
14743       p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14744       if (strcmp (p, "unconstrained") == 0)
14745 	unconstrained = true;
14746       else if (strcmp (p, "reproducible") == 0)
14747 	reproducible = true;
14748       else
14749 	{
14750 	  c_parser_error (parser, "expected %<reproducible%> or "
14751 				  "%<unconstrained%>");
14752 	  goto out_err;
14753 	}
14754       c_parser_consume_token (parser);
14755       c_parser_consume_token (parser);
14756     }
14757   if (!c_parser_next_token_is (parser, CPP_NAME))
14758     {
14759       c_parser_error (parser, "expected %<concurrent%>");
14760       goto out_err;
14761     }
14762   p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14763   if (strcmp (p, "concurrent") != 0)
14764     {
14765       c_parser_error (parser, "expected %<concurrent%>");
14766       goto out_err;
14767     }
14768   c_parser_consume_token (parser);
14769   parens.skip_until_found_close (parser);
14770   check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order");
14771   c = build_omp_clause (loc, OMP_CLAUSE_ORDER);
14772   OMP_CLAUSE_ORDER_UNCONSTRAINED (c) = unconstrained;
14773   OMP_CLAUSE_ORDER_REPRODUCIBLE (c) = reproducible;
14774   OMP_CLAUSE_CHAIN (c) = list;
14775   return c;
14776 
14777  out_err:
14778   parens.skip_until_found_close (parser);
14779   return list;
14780 }
14781 
14782 
14783 /* OpenMP 5.0:
14784    bind ( teams | parallel | thread ) */
14785 
14786 static tree
c_parser_omp_clause_bind(c_parser * parser,tree list)14787 c_parser_omp_clause_bind (c_parser *parser, tree list)
14788 {
14789   location_t loc = c_parser_peek_token (parser)->location;
14790   tree c;
14791   const char *p;
14792   enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
14793 
14794   matching_parens parens;
14795   if (!parens.require_open (parser))
14796     return list;
14797   if (!c_parser_next_token_is (parser, CPP_NAME))
14798     {
14799      invalid:
14800       c_parser_error (parser,
14801 		      "expected %<teams%>, %<parallel%> or %<thread%>");
14802       parens.skip_until_found_close (parser);
14803       return list;
14804     }
14805   p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14806   if (strcmp (p, "teams") == 0)
14807     kind = OMP_CLAUSE_BIND_TEAMS;
14808   else if (strcmp (p, "parallel") == 0)
14809     kind = OMP_CLAUSE_BIND_PARALLEL;
14810   else if (strcmp (p, "thread") != 0)
14811     goto invalid;
14812   c_parser_consume_token (parser);
14813   parens.skip_until_found_close (parser);
14814   /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
14815   c = build_omp_clause (loc, OMP_CLAUSE_BIND);
14816   OMP_CLAUSE_BIND_KIND (c) = kind;
14817   OMP_CLAUSE_CHAIN (c) = list;
14818   return c;
14819 }
14820 
14821 
14822 /* OpenMP 2.5:
14823    ordered
14824 
14825    OpenMP 4.5:
14826    ordered ( constant-expression ) */
14827 
14828 static tree
c_parser_omp_clause_ordered(c_parser * parser,tree list)14829 c_parser_omp_clause_ordered (c_parser *parser, tree list)
14830 {
14831   check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered");
14832 
14833   tree c, num = NULL_TREE;
14834   HOST_WIDE_INT n;
14835   location_t loc = c_parser_peek_token (parser)->location;
14836   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14837     {
14838       matching_parens parens;
14839       parens.consume_open (parser);
14840       num = c_parser_expr_no_commas (parser, NULL).value;
14841       parens.skip_until_found_close (parser);
14842     }
14843   if (num == error_mark_node)
14844     return list;
14845   if (num)
14846     {
14847       mark_exp_read (num);
14848       num = c_fully_fold (num, false, NULL);
14849       if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
14850 	  || !tree_fits_shwi_p (num)
14851 	  || (n = tree_to_shwi (num)) <= 0
14852 	  || (int) n != n)
14853 	{
14854 	  error_at (loc, "ordered argument needs positive "
14855 			 "constant integer expression");
14856 	  return list;
14857 	}
14858     }
14859   c = build_omp_clause (loc, OMP_CLAUSE_ORDERED);
14860   OMP_CLAUSE_ORDERED_EXPR (c) = num;
14861   OMP_CLAUSE_CHAIN (c) = list;
14862   return c;
14863 }
14864 
14865 /* OpenMP 2.5:
14866    private ( variable-list ) */
14867 
14868 static tree
c_parser_omp_clause_private(c_parser * parser,tree list)14869 c_parser_omp_clause_private (c_parser *parser, tree list)
14870 {
14871   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_PRIVATE, list);
14872 }
14873 
14874 /* OpenMP 2.5:
14875    reduction ( reduction-operator : variable-list )
14876 
14877    reduction-operator:
14878      One of: + * - & ^ | && ||
14879 
14880    OpenMP 3.1:
14881 
14882    reduction-operator:
14883      One of: + * - & ^ | && || max min
14884 
14885    OpenMP 4.0:
14886 
14887    reduction-operator:
14888      One of: + * - & ^ | && ||
14889      identifier
14890 
14891    OpenMP 5.0:
14892    reduction ( reduction-modifier, reduction-operator : variable-list )
14893    in_reduction ( reduction-operator : variable-list )
14894    task_reduction ( reduction-operator : variable-list )  */
14895 
14896 static tree
c_parser_omp_clause_reduction(c_parser * parser,enum omp_clause_code kind,bool is_omp,tree list)14897 c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind,
14898 			       bool is_omp, tree list)
14899 {
14900   location_t clause_loc = c_parser_peek_token (parser)->location;
14901   matching_parens parens;
14902   if (parens.require_open (parser))
14903     {
14904       bool task = false;
14905       bool inscan = false;
14906       enum tree_code code = ERROR_MARK;
14907       tree reduc_id = NULL_TREE;
14908 
14909       if (kind == OMP_CLAUSE_REDUCTION && is_omp)
14910 	{
14911 	  if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)
14912 	      && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
14913 	    {
14914 	      c_parser_consume_token (parser);
14915 	      c_parser_consume_token (parser);
14916 	    }
14917 	  else if (c_parser_next_token_is (parser, CPP_NAME)
14918 		   && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
14919 	    {
14920 	      const char *p
14921 		= IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14922 	      if (strcmp (p, "task") == 0)
14923 		task = true;
14924 	      else if (strcmp (p, "inscan") == 0)
14925 		inscan = true;
14926 	      if (task || inscan)
14927 		{
14928 		  c_parser_consume_token (parser);
14929 		  c_parser_consume_token (parser);
14930 		}
14931 	    }
14932 	}
14933 
14934       switch (c_parser_peek_token (parser)->type)
14935 	{
14936 	case CPP_PLUS:
14937 	  code = PLUS_EXPR;
14938 	  break;
14939 	case CPP_MULT:
14940 	  code = MULT_EXPR;
14941 	  break;
14942 	case CPP_MINUS:
14943 	  code = MINUS_EXPR;
14944 	  break;
14945 	case CPP_AND:
14946 	  code = BIT_AND_EXPR;
14947 	  break;
14948 	case CPP_XOR:
14949 	  code = BIT_XOR_EXPR;
14950 	  break;
14951 	case CPP_OR:
14952 	  code = BIT_IOR_EXPR;
14953 	  break;
14954 	case CPP_AND_AND:
14955 	  code = TRUTH_ANDIF_EXPR;
14956 	  break;
14957 	case CPP_OR_OR:
14958 	  code = TRUTH_ORIF_EXPR;
14959 	  break;
14960         case CPP_NAME:
14961 	  {
14962 	    const char *p
14963 	      = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14964 	    if (strcmp (p, "min") == 0)
14965 	      {
14966 		code = MIN_EXPR;
14967 		break;
14968 	      }
14969 	    if (strcmp (p, "max") == 0)
14970 	      {
14971 		code = MAX_EXPR;
14972 		break;
14973 	      }
14974 	    reduc_id = c_parser_peek_token (parser)->value;
14975 	    break;
14976 	  }
14977 	default:
14978 	  c_parser_error (parser,
14979 			  "expected %<+%>, %<*%>, %<-%>, %<&%>, "
14980 			  "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
14981 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
14982 	  return list;
14983 	}
14984       c_parser_consume_token (parser);
14985       reduc_id = c_omp_reduction_id (code, reduc_id);
14986       if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14987 	{
14988 	  tree nl, c;
14989 
14990 	  nl = c_parser_omp_variable_list (parser, clause_loc, kind, list);
14991 	  for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
14992 	    {
14993 	      tree d = OMP_CLAUSE_DECL (c), type;
14994 	      if (TREE_CODE (d) != TREE_LIST)
14995 		type = TREE_TYPE (d);
14996 	      else
14997 		{
14998 		  int cnt = 0;
14999 		  tree t;
15000 		  for (t = d; TREE_CODE (t) == TREE_LIST; t = TREE_CHAIN (t))
15001 		    cnt++;
15002 		  type = TREE_TYPE (t);
15003 		  while (cnt > 0)
15004 		    {
15005 		      if (TREE_CODE (type) != POINTER_TYPE
15006 			  && TREE_CODE (type) != ARRAY_TYPE)
15007 			break;
15008 		      type = TREE_TYPE (type);
15009 		      cnt--;
15010 		    }
15011 		}
15012 	      while (TREE_CODE (type) == ARRAY_TYPE)
15013 		type = TREE_TYPE (type);
15014 	      OMP_CLAUSE_REDUCTION_CODE (c) = code;
15015 	      if (task)
15016 		OMP_CLAUSE_REDUCTION_TASK (c) = 1;
15017 	      else if (inscan)
15018 		OMP_CLAUSE_REDUCTION_INSCAN (c) = 1;
15019 	      if (code == ERROR_MARK
15020 		  || !(INTEGRAL_TYPE_P (type)
15021 		       || TREE_CODE (type) == REAL_TYPE
15022 		       || TREE_CODE (type) == COMPLEX_TYPE))
15023 		OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
15024 		  = c_omp_reduction_lookup (reduc_id,
15025 					    TYPE_MAIN_VARIANT (type));
15026 	    }
15027 
15028 	  list = nl;
15029 	}
15030       parens.skip_until_found_close (parser);
15031     }
15032   return list;
15033 }
15034 
15035 /* OpenMP 2.5:
15036    schedule ( schedule-kind )
15037    schedule ( schedule-kind , expression )
15038 
15039    schedule-kind:
15040      static | dynamic | guided | runtime | auto
15041 
15042    OpenMP 4.5:
15043    schedule ( schedule-modifier : schedule-kind )
15044    schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
15045 
15046    schedule-modifier:
15047      simd
15048      monotonic
15049      nonmonotonic  */
15050 
15051 static tree
c_parser_omp_clause_schedule(c_parser * parser,tree list)15052 c_parser_omp_clause_schedule (c_parser *parser, tree list)
15053 {
15054   tree c, t;
15055   location_t loc = c_parser_peek_token (parser)->location;
15056   int modifiers = 0, nmodifiers = 0;
15057 
15058   matching_parens parens;
15059   if (!parens.require_open (parser))
15060     return list;
15061 
15062   c = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE);
15063 
15064   location_t comma = UNKNOWN_LOCATION;
15065   while (c_parser_next_token_is (parser, CPP_NAME))
15066     {
15067       tree kind = c_parser_peek_token (parser)->value;
15068       const char *p = IDENTIFIER_POINTER (kind);
15069       if (strcmp ("simd", p) == 0)
15070 	OMP_CLAUSE_SCHEDULE_SIMD (c) = 1;
15071       else if (strcmp ("monotonic", p) == 0)
15072 	modifiers |= OMP_CLAUSE_SCHEDULE_MONOTONIC;
15073       else if (strcmp ("nonmonotonic", p) == 0)
15074 	modifiers |= OMP_CLAUSE_SCHEDULE_NONMONOTONIC;
15075       else
15076 	break;
15077       comma = UNKNOWN_LOCATION;
15078       c_parser_consume_token (parser);
15079       if (nmodifiers++ == 0
15080 	  && c_parser_next_token_is (parser, CPP_COMMA))
15081 	{
15082 	  comma = c_parser_peek_token (parser)->location;
15083 	  c_parser_consume_token (parser);
15084 	}
15085       else
15086 	{
15087 	  c_parser_require (parser, CPP_COLON, "expected %<:%>");
15088 	  break;
15089 	}
15090     }
15091   if (comma != UNKNOWN_LOCATION)
15092     error_at (comma, "expected %<:%>");
15093 
15094   if ((modifiers & (OMP_CLAUSE_SCHEDULE_MONOTONIC
15095 		    | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
15096       == (OMP_CLAUSE_SCHEDULE_MONOTONIC
15097 	  | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
15098     {
15099       error_at (loc, "both %<monotonic%> and %<nonmonotonic%> modifiers "
15100 		     "specified");
15101       modifiers = 0;
15102     }
15103 
15104   if (c_parser_next_token_is (parser, CPP_NAME))
15105     {
15106       tree kind = c_parser_peek_token (parser)->value;
15107       const char *p = IDENTIFIER_POINTER (kind);
15108 
15109       switch (p[0])
15110 	{
15111 	case 'd':
15112 	  if (strcmp ("dynamic", p) != 0)
15113 	    goto invalid_kind;
15114 	  OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
15115 	  break;
15116 
15117         case 'g':
15118 	  if (strcmp ("guided", p) != 0)
15119 	    goto invalid_kind;
15120 	  OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
15121 	  break;
15122 
15123 	case 'r':
15124 	  if (strcmp ("runtime", p) != 0)
15125 	    goto invalid_kind;
15126 	  OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
15127 	  break;
15128 
15129 	default:
15130 	  goto invalid_kind;
15131 	}
15132     }
15133   else if (c_parser_next_token_is_keyword (parser, RID_STATIC))
15134     OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
15135   else if (c_parser_next_token_is_keyword (parser, RID_AUTO))
15136     OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
15137   else
15138     goto invalid_kind;
15139 
15140   c_parser_consume_token (parser);
15141   if (c_parser_next_token_is (parser, CPP_COMMA))
15142     {
15143       location_t here;
15144       c_parser_consume_token (parser);
15145 
15146       here = c_parser_peek_token (parser)->location;
15147       c_expr expr = c_parser_expr_no_commas (parser, NULL);
15148       expr = convert_lvalue_to_rvalue (here, expr, false, true);
15149       t = expr.value;
15150       t = c_fully_fold (t, false, NULL);
15151 
15152       if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
15153 	error_at (here, "schedule %<runtime%> does not take "
15154 		  "a %<chunk_size%> parameter");
15155       else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO)
15156 	error_at (here,
15157 		  "schedule %<auto%> does not take "
15158 		  "a %<chunk_size%> parameter");
15159       else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE)
15160 	{
15161 	  /* Attempt to statically determine when the number isn't
15162 	     positive.  */
15163 	  tree s = fold_build2_loc (loc, LE_EXPR, boolean_type_node, t,
15164 				    build_int_cst (TREE_TYPE (t), 0));
15165 	  protected_set_expr_location (s, loc);
15166 	  if (s == boolean_true_node)
15167 	    {
15168 	      warning_at (loc, 0,
15169 			  "chunk size value must be positive");
15170 	      t = integer_one_node;
15171 	    }
15172 	  OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
15173 	}
15174       else
15175 	c_parser_error (parser, "expected integer expression");
15176 
15177       parens.skip_until_found_close (parser);
15178     }
15179   else
15180     c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
15181 			       "expected %<,%> or %<)%>");
15182 
15183   OMP_CLAUSE_SCHEDULE_KIND (c)
15184     = (enum omp_clause_schedule_kind)
15185       (OMP_CLAUSE_SCHEDULE_KIND (c) | modifiers);
15186 
15187   check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule");
15188   OMP_CLAUSE_CHAIN (c) = list;
15189   return c;
15190 
15191  invalid_kind:
15192   c_parser_error (parser, "invalid schedule kind");
15193   c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
15194   return list;
15195 }
15196 
15197 /* OpenMP 2.5:
15198    shared ( variable-list ) */
15199 
15200 static tree
c_parser_omp_clause_shared(c_parser * parser,tree list)15201 c_parser_omp_clause_shared (c_parser *parser, tree list)
15202 {
15203   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_SHARED, list);
15204 }
15205 
15206 /* OpenMP 3.0:
15207    untied */
15208 
15209 static tree
c_parser_omp_clause_untied(c_parser * parser ATTRIBUTE_UNUSED,tree list)15210 c_parser_omp_clause_untied (c_parser *parser ATTRIBUTE_UNUSED, tree list)
15211 {
15212   tree c;
15213 
15214   /* FIXME: Should we allow duplicates?  */
15215   check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied");
15216 
15217   c = build_omp_clause (c_parser_peek_token (parser)->location,
15218 			OMP_CLAUSE_UNTIED);
15219   OMP_CLAUSE_CHAIN (c) = list;
15220 
15221   return c;
15222 }
15223 
15224 /* OpenMP 4.0:
15225    inbranch
15226    notinbranch */
15227 
15228 static tree
c_parser_omp_clause_branch(c_parser * parser ATTRIBUTE_UNUSED,enum omp_clause_code code,tree list)15229 c_parser_omp_clause_branch (c_parser *parser ATTRIBUTE_UNUSED,
15230 			    enum omp_clause_code code, tree list)
15231 {
15232   check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
15233 
15234   tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15235   OMP_CLAUSE_CHAIN (c) = list;
15236 
15237   return c;
15238 }
15239 
15240 /* OpenMP 4.0:
15241    parallel
15242    for
15243    sections
15244    taskgroup */
15245 
15246 static tree
c_parser_omp_clause_cancelkind(c_parser * parser ATTRIBUTE_UNUSED,enum omp_clause_code code,tree list)15247 c_parser_omp_clause_cancelkind (c_parser *parser ATTRIBUTE_UNUSED,
15248 				enum omp_clause_code code, tree list)
15249 {
15250   tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15251   OMP_CLAUSE_CHAIN (c) = list;
15252 
15253   return c;
15254 }
15255 
15256 /* OpenMP 4.5:
15257    nogroup */
15258 
15259 static tree
c_parser_omp_clause_nogroup(c_parser * parser ATTRIBUTE_UNUSED,tree list)15260 c_parser_omp_clause_nogroup (c_parser *parser ATTRIBUTE_UNUSED, tree list)
15261 {
15262   check_no_duplicate_clause (list, OMP_CLAUSE_NOGROUP, "nogroup");
15263   tree c = build_omp_clause (c_parser_peek_token (parser)->location,
15264 			     OMP_CLAUSE_NOGROUP);
15265   OMP_CLAUSE_CHAIN (c) = list;
15266   return c;
15267 }
15268 
15269 /* OpenMP 4.5:
15270    simd
15271    threads */
15272 
15273 static tree
c_parser_omp_clause_orderedkind(c_parser * parser ATTRIBUTE_UNUSED,enum omp_clause_code code,tree list)15274 c_parser_omp_clause_orderedkind (c_parser *parser ATTRIBUTE_UNUSED,
15275 				 enum omp_clause_code code, tree list)
15276 {
15277   check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
15278   tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15279   OMP_CLAUSE_CHAIN (c) = list;
15280   return c;
15281 }
15282 
15283 /* OpenMP 4.0:
15284    num_teams ( expression )
15285 
15286    OpenMP 5.1:
15287    num_teams ( expression : expression ) */
15288 
15289 static tree
c_parser_omp_clause_num_teams(c_parser * parser,tree list)15290 c_parser_omp_clause_num_teams (c_parser *parser, tree list)
15291 {
15292   location_t num_teams_loc = c_parser_peek_token (parser)->location;
15293   matching_parens parens;
15294   if (parens.require_open (parser))
15295     {
15296       location_t upper_loc = c_parser_peek_token (parser)->location;
15297       location_t lower_loc = UNKNOWN_LOCATION;
15298       c_expr expr = c_parser_expr_no_commas (parser, NULL);
15299       expr = convert_lvalue_to_rvalue (upper_loc, expr, false, true);
15300       tree c, upper = expr.value, lower = NULL_TREE;
15301       upper = c_fully_fold (upper, false, NULL);
15302 
15303       if (c_parser_next_token_is (parser, CPP_COLON))
15304 	{
15305 	  c_parser_consume_token (parser);
15306 	  lower_loc = upper_loc;
15307 	  lower = upper;
15308 	  upper_loc = c_parser_peek_token (parser)->location;
15309 	  expr = c_parser_expr_no_commas (parser, NULL);
15310 	  expr = convert_lvalue_to_rvalue (upper_loc, expr, false, true);
15311 	  upper = expr.value;
15312 	  upper = c_fully_fold (upper, false, NULL);
15313 	}
15314 
15315       parens.skip_until_found_close (parser);
15316 
15317       if (!INTEGRAL_TYPE_P (TREE_TYPE (upper))
15318 	  || (lower && !INTEGRAL_TYPE_P (TREE_TYPE (lower))))
15319 	{
15320 	  c_parser_error (parser, "expected integer expression");
15321 	  return list;
15322 	}
15323 
15324       /* Attempt to statically determine when the number isn't positive.  */
15325       c = fold_build2_loc (upper_loc, LE_EXPR, boolean_type_node, upper,
15326 			   build_int_cst (TREE_TYPE (upper), 0));
15327       protected_set_expr_location (c, upper_loc);
15328       if (c == boolean_true_node)
15329 	{
15330 	  warning_at (upper_loc, 0, "%<num_teams%> value must be positive");
15331 	  upper = integer_one_node;
15332 	}
15333       if (lower)
15334 	{
15335 	  c = fold_build2_loc (lower_loc, LE_EXPR, boolean_type_node, lower,
15336 			       build_int_cst (TREE_TYPE (lower), 0));
15337 	  protected_set_expr_location (c, lower_loc);
15338 	  if (c == boolean_true_node)
15339 	    {
15340 	      warning_at (lower_loc, 0, "%<num_teams%> value must be positive");
15341 	      lower = NULL_TREE;
15342 	    }
15343 	  else if (TREE_CODE (lower) == INTEGER_CST
15344 		   && TREE_CODE (upper) == INTEGER_CST
15345 		   && tree_int_cst_lt (upper, lower))
15346 	    {
15347 	      warning_at (lower_loc, 0, "%<num_teams%> lower bound %qE bigger "
15348 					"than upper bound %qE", lower, upper);
15349 	      lower = NULL_TREE;
15350 	    }
15351 	}
15352 
15353       check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TEAMS, "num_teams");
15354 
15355       c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
15356       OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = upper;
15357       OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = lower;
15358       OMP_CLAUSE_CHAIN (c) = list;
15359       list = c;
15360     }
15361 
15362   return list;
15363 }
15364 
15365 /* OpenMP 4.0:
15366    thread_limit ( expression ) */
15367 
15368 static tree
c_parser_omp_clause_thread_limit(c_parser * parser,tree list)15369 c_parser_omp_clause_thread_limit (c_parser *parser, tree list)
15370 {
15371   location_t num_thread_limit_loc = c_parser_peek_token (parser)->location;
15372   matching_parens parens;
15373   if (parens.require_open (parser))
15374     {
15375       location_t expr_loc = c_parser_peek_token (parser)->location;
15376       c_expr expr = c_parser_expr_no_commas (parser, NULL);
15377       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15378       tree c, t = expr.value;
15379       t = c_fully_fold (t, false, NULL);
15380 
15381       parens.skip_until_found_close (parser);
15382 
15383       if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
15384 	{
15385 	  c_parser_error (parser, "expected integer expression");
15386 	  return list;
15387 	}
15388 
15389       /* Attempt to statically determine when the number isn't positive.  */
15390       c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
15391 			   build_int_cst (TREE_TYPE (t), 0));
15392       protected_set_expr_location (c, expr_loc);
15393       if (c == boolean_true_node)
15394 	{
15395 	  warning_at (expr_loc, 0, "%<thread_limit%> value must be positive");
15396 	  t = integer_one_node;
15397 	}
15398 
15399       check_no_duplicate_clause (list, OMP_CLAUSE_THREAD_LIMIT,
15400 				 "thread_limit");
15401 
15402       c = build_omp_clause (num_thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
15403       OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
15404       OMP_CLAUSE_CHAIN (c) = list;
15405       list = c;
15406     }
15407 
15408   return list;
15409 }
15410 
15411 /* OpenMP 4.0:
15412    aligned ( variable-list )
15413    aligned ( variable-list : constant-expression ) */
15414 
15415 static tree
c_parser_omp_clause_aligned(c_parser * parser,tree list)15416 c_parser_omp_clause_aligned (c_parser *parser, tree list)
15417 {
15418   location_t clause_loc = c_parser_peek_token (parser)->location;
15419   tree nl, c;
15420 
15421   matching_parens parens;
15422   if (!parens.require_open (parser))
15423     return list;
15424 
15425   nl = c_parser_omp_variable_list (parser, clause_loc,
15426 				   OMP_CLAUSE_ALIGNED, list);
15427 
15428   if (c_parser_next_token_is (parser, CPP_COLON))
15429     {
15430       c_parser_consume_token (parser);
15431       location_t expr_loc = c_parser_peek_token (parser)->location;
15432       c_expr expr = c_parser_expr_no_commas (parser, NULL);
15433       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15434       tree alignment = expr.value;
15435       alignment = c_fully_fold (alignment, false, NULL);
15436       if (TREE_CODE (alignment) != INTEGER_CST
15437 	  || !INTEGRAL_TYPE_P (TREE_TYPE (alignment))
15438 	  || tree_int_cst_sgn (alignment) != 1)
15439 	{
15440 	  error_at (clause_loc, "%<aligned%> clause alignment expression must "
15441 				"be positive constant integer expression");
15442 	  alignment = NULL_TREE;
15443 	}
15444 
15445       for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15446 	OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = alignment;
15447     }
15448 
15449   parens.skip_until_found_close (parser);
15450   return nl;
15451 }
15452 
15453 /* OpenMP 5.0:
15454    allocate ( variable-list )
15455    allocate ( expression : variable-list )
15456 
15457    OpenMP 5.1:
15458    allocate ( allocator-modifier : variable-list )
15459    allocate ( allocator-modifier , allocator-modifier : variable-list )
15460 
15461    allocator-modifier:
15462    allocator ( expression )
15463    align ( expression )  */
15464 
15465 static tree
c_parser_omp_clause_allocate(c_parser * parser,tree list)15466 c_parser_omp_clause_allocate (c_parser *parser, tree list)
15467 {
15468   location_t clause_loc = c_parser_peek_token (parser)->location;
15469   tree nl, c;
15470   tree allocator = NULL_TREE;
15471   tree align = NULL_TREE;
15472 
15473   matching_parens parens;
15474   if (!parens.require_open (parser))
15475     return list;
15476 
15477   if ((c_parser_next_token_is_not (parser, CPP_NAME)
15478        && c_parser_next_token_is_not (parser, CPP_KEYWORD))
15479       || (c_parser_peek_2nd_token (parser)->type != CPP_COMMA
15480 	  && c_parser_peek_2nd_token (parser)->type != CPP_CLOSE_PAREN))
15481     {
15482       bool has_modifiers = false;
15483       tree orig_type = NULL_TREE;
15484       if (c_parser_next_token_is (parser, CPP_NAME)
15485 	  && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
15486 	{
15487 	  unsigned int n = 3;
15488 	  const char *p
15489 	    = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15490 	  if ((strcmp (p, "allocator") == 0 || strcmp (p, "align") == 0)
15491 	      && c_parser_check_balanced_raw_token_sequence (parser, &n)
15492 	      && (c_parser_peek_nth_token_raw (parser, n)->type
15493 		  == CPP_CLOSE_PAREN))
15494 	    {
15495 	      if (c_parser_peek_nth_token_raw (parser, n + 1)->type
15496 		  == CPP_COLON)
15497 		has_modifiers = true;
15498 	      else if (c_parser_peek_nth_token_raw (parser, n + 1)->type
15499 		       == CPP_COMMA
15500 		       && (c_parser_peek_nth_token_raw (parser, n + 2)->type
15501 			   == CPP_NAME)
15502 		       && (c_parser_peek_nth_token_raw (parser, n + 3)->type
15503 			   == CPP_OPEN_PAREN))
15504 		{
15505 		  c_token *tok = c_parser_peek_nth_token_raw (parser, n + 2);
15506 		  const char *q = IDENTIFIER_POINTER (tok->value);
15507 		  n += 4;
15508 		  if ((strcmp (q, "allocator") == 0
15509 		       || strcmp (q, "align") == 0)
15510 		      && c_parser_check_balanced_raw_token_sequence (parser,
15511 								     &n)
15512 		      && (c_parser_peek_nth_token_raw (parser, n)->type
15513 			  == CPP_CLOSE_PAREN)
15514 		      && (c_parser_peek_nth_token_raw (parser, n + 1)->type
15515 			  == CPP_COLON))
15516 		    has_modifiers = true;
15517 		}
15518 	    }
15519 	  if (has_modifiers)
15520 	    {
15521 	      c_parser_consume_token (parser);
15522 	      matching_parens parens2;;
15523 	      parens2.require_open (parser);
15524 	      location_t expr_loc = c_parser_peek_token (parser)->location;
15525 	      c_expr expr = c_parser_expr_no_commas (parser, NULL);
15526 	      expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15527 	      if (strcmp (p, "allocator") == 0)
15528 		{
15529 		  allocator = expr.value;
15530 		  allocator = c_fully_fold (allocator, false, NULL);
15531 		  orig_type = expr.original_type
15532 			      ? expr.original_type : TREE_TYPE (allocator);
15533 		  orig_type = TYPE_MAIN_VARIANT (orig_type);
15534 		}
15535 	      else
15536 		{
15537 		  align = expr.value;
15538 		  align = c_fully_fold (align, false, NULL);
15539 		}
15540 	      parens2.skip_until_found_close (parser);
15541 	      if (c_parser_next_token_is (parser, CPP_COMMA))
15542 		{
15543 		  c_parser_consume_token (parser);
15544 		  c_token *tok = c_parser_peek_token (parser);
15545 		  const char *q = "";
15546 		  if (c_parser_next_token_is (parser, CPP_NAME))
15547 		    q = IDENTIFIER_POINTER (tok->value);
15548 		  if (strcmp (q, "allocator") != 0 && strcmp (q, "align") != 0)
15549 		    {
15550 		      c_parser_error (parser, "expected %<allocator%> or "
15551 					      "%<align%>");
15552 		      parens.skip_until_found_close (parser);
15553 		      return list;
15554 		    }
15555 		  else if (strcmp (p, q) == 0)
15556 		    {
15557 		      error_at (tok->location, "duplicate %qs modifier", p);
15558 		      parens.skip_until_found_close (parser);
15559 		      return list;
15560 		    }
15561 		  c_parser_consume_token (parser);
15562 		  if (!parens2.require_open (parser))
15563 		    {
15564 		      parens.skip_until_found_close (parser);
15565 		      return list;
15566 		    }
15567 		  expr_loc = c_parser_peek_token (parser)->location;
15568 		  expr = c_parser_expr_no_commas (parser, NULL);
15569 		  expr = convert_lvalue_to_rvalue (expr_loc, expr, false,
15570 						   true);
15571 		  if (strcmp (q, "allocator") == 0)
15572 		    {
15573 		      allocator = expr.value;
15574 		      allocator = c_fully_fold (allocator, false, NULL);
15575 		      orig_type = expr.original_type
15576 				  ? expr.original_type : TREE_TYPE (allocator);
15577 		      orig_type = TYPE_MAIN_VARIANT (orig_type);
15578 		    }
15579 		  else
15580 		    {
15581 		      align = expr.value;
15582 		      align = c_fully_fold (align, false, NULL);
15583 		    }
15584 		  parens2.skip_until_found_close (parser);
15585 		}
15586 	    }
15587 	}
15588       if (!has_modifiers)
15589 	{
15590 	  location_t expr_loc = c_parser_peek_token (parser)->location;
15591 	  c_expr expr = c_parser_expr_no_commas (parser, NULL);
15592 	  expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15593 	  allocator = expr.value;
15594 	  allocator = c_fully_fold (allocator, false, NULL);
15595 	  orig_type = expr.original_type
15596 		      ? expr.original_type : TREE_TYPE (allocator);
15597 	  orig_type = TYPE_MAIN_VARIANT (orig_type);
15598 	}
15599       if (allocator
15600 	  && (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
15601 	      || TREE_CODE (orig_type) != ENUMERAL_TYPE
15602 	      || (TYPE_NAME (orig_type)
15603 		  != get_identifier ("omp_allocator_handle_t"))))
15604         {
15605           error_at (clause_loc, "%<allocate%> clause allocator expression "
15606 				"has type %qT rather than "
15607 				"%<omp_allocator_handle_t%>",
15608 				TREE_TYPE (allocator));
15609           allocator = NULL_TREE;
15610         }
15611       if (align
15612 	  && (!INTEGRAL_TYPE_P (TREE_TYPE (align))
15613 	      || !tree_fits_uhwi_p (align)
15614 	      || !integer_pow2p (align)))
15615 	{
15616 	  error_at (clause_loc, "%<allocate%> clause %<align%> modifier "
15617 				"argument needs to be positive constant "
15618 				"power of two integer expression");
15619 	  align = NULL_TREE;
15620 	}
15621       if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15622 	{
15623 	  parens.skip_until_found_close (parser);
15624 	  return list;
15625 	}
15626     }
15627 
15628   nl = c_parser_omp_variable_list (parser, clause_loc,
15629 				   OMP_CLAUSE_ALLOCATE, list);
15630 
15631   if (allocator || align)
15632     for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15633       {
15634 	OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
15635 	OMP_CLAUSE_ALLOCATE_ALIGN (c) = align;
15636       }
15637 
15638   parens.skip_until_found_close (parser);
15639   return nl;
15640 }
15641 
15642 /* OpenMP 4.0:
15643    linear ( variable-list )
15644    linear ( variable-list : expression )
15645 
15646    OpenMP 4.5:
15647    linear ( modifier ( variable-list ) )
15648    linear ( modifier ( variable-list ) : expression ) */
15649 
15650 static tree
c_parser_omp_clause_linear(c_parser * parser,tree list)15651 c_parser_omp_clause_linear (c_parser *parser, tree list)
15652 {
15653   location_t clause_loc = c_parser_peek_token (parser)->location;
15654   tree nl, c, step;
15655   enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
15656 
15657   matching_parens parens;
15658   if (!parens.require_open (parser))
15659     return list;
15660 
15661   if (c_parser_next_token_is (parser, CPP_NAME))
15662     {
15663       c_token *tok = c_parser_peek_token (parser);
15664       const char *p = IDENTIFIER_POINTER (tok->value);
15665       if (strcmp ("val", p) == 0)
15666 	kind = OMP_CLAUSE_LINEAR_VAL;
15667       if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN)
15668 	kind = OMP_CLAUSE_LINEAR_DEFAULT;
15669       if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
15670 	{
15671 	  c_parser_consume_token (parser);
15672 	  c_parser_consume_token (parser);
15673 	}
15674     }
15675 
15676   nl = c_parser_omp_variable_list (parser, clause_loc,
15677 				   OMP_CLAUSE_LINEAR, list);
15678 
15679   if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
15680     parens.skip_until_found_close (parser);
15681 
15682   if (c_parser_next_token_is (parser, CPP_COLON))
15683     {
15684       c_parser_consume_token (parser);
15685       location_t expr_loc = c_parser_peek_token (parser)->location;
15686       c_expr expr = c_parser_expr_no_commas (parser, NULL);
15687       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15688       step = expr.value;
15689       step = c_fully_fold (step, false, NULL);
15690       if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
15691 	{
15692 	  error_at (clause_loc, "%<linear%> clause step expression must "
15693 				"be integral");
15694 	  step = integer_one_node;
15695 	}
15696 
15697     }
15698   else
15699     step = integer_one_node;
15700 
15701   for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15702     {
15703       OMP_CLAUSE_LINEAR_STEP (c) = step;
15704       OMP_CLAUSE_LINEAR_KIND (c) = kind;
15705     }
15706 
15707   parens.skip_until_found_close (parser);
15708   return nl;
15709 }
15710 
15711 /* OpenMP 5.0:
15712    nontemporal ( variable-list ) */
15713 
15714 static tree
c_parser_omp_clause_nontemporal(c_parser * parser,tree list)15715 c_parser_omp_clause_nontemporal (c_parser *parser, tree list)
15716 {
15717   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_NONTEMPORAL, list);
15718 }
15719 
15720 /* OpenMP 4.0:
15721    safelen ( constant-expression ) */
15722 
15723 static tree
c_parser_omp_clause_safelen(c_parser * parser,tree list)15724 c_parser_omp_clause_safelen (c_parser *parser, tree list)
15725 {
15726   location_t clause_loc = c_parser_peek_token (parser)->location;
15727   tree c, t;
15728 
15729   matching_parens parens;
15730   if (!parens.require_open (parser))
15731     return list;
15732 
15733   location_t expr_loc = c_parser_peek_token (parser)->location;
15734   c_expr expr = c_parser_expr_no_commas (parser, NULL);
15735   expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15736   t = expr.value;
15737   t = c_fully_fold (t, false, NULL);
15738   if (TREE_CODE (t) != INTEGER_CST
15739       || !INTEGRAL_TYPE_P (TREE_TYPE (t))
15740       || tree_int_cst_sgn (t) != 1)
15741     {
15742       error_at (clause_loc, "%<safelen%> clause expression must "
15743 			    "be positive constant integer expression");
15744       t = NULL_TREE;
15745     }
15746 
15747   parens.skip_until_found_close (parser);
15748   if (t == NULL_TREE || t == error_mark_node)
15749     return list;
15750 
15751   check_no_duplicate_clause (list, OMP_CLAUSE_SAFELEN, "safelen");
15752 
15753   c = build_omp_clause (clause_loc, OMP_CLAUSE_SAFELEN);
15754   OMP_CLAUSE_SAFELEN_EXPR (c) = t;
15755   OMP_CLAUSE_CHAIN (c) = list;
15756   return c;
15757 }
15758 
15759 /* OpenMP 4.0:
15760    simdlen ( constant-expression ) */
15761 
15762 static tree
c_parser_omp_clause_simdlen(c_parser * parser,tree list)15763 c_parser_omp_clause_simdlen (c_parser *parser, tree list)
15764 {
15765   location_t clause_loc = c_parser_peek_token (parser)->location;
15766   tree c, t;
15767 
15768   matching_parens parens;
15769   if (!parens.require_open (parser))
15770     return list;
15771 
15772   location_t expr_loc = c_parser_peek_token (parser)->location;
15773   c_expr expr = c_parser_expr_no_commas (parser, NULL);
15774   expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15775   t = expr.value;
15776   t = c_fully_fold (t, false, NULL);
15777   if (TREE_CODE (t) != INTEGER_CST
15778       || !INTEGRAL_TYPE_P (TREE_TYPE (t))
15779       || tree_int_cst_sgn (t) != 1)
15780     {
15781       error_at (clause_loc, "%<simdlen%> clause expression must "
15782 			    "be positive constant integer expression");
15783       t = NULL_TREE;
15784     }
15785 
15786   parens.skip_until_found_close (parser);
15787   if (t == NULL_TREE || t == error_mark_node)
15788     return list;
15789 
15790   check_no_duplicate_clause (list, OMP_CLAUSE_SIMDLEN, "simdlen");
15791 
15792   c = build_omp_clause (clause_loc, OMP_CLAUSE_SIMDLEN);
15793   OMP_CLAUSE_SIMDLEN_EXPR (c) = t;
15794   OMP_CLAUSE_CHAIN (c) = list;
15795   return c;
15796 }
15797 
15798 /* OpenMP 4.5:
15799    vec:
15800      identifier [+/- integer]
15801      vec , identifier [+/- integer]
15802 */
15803 
15804 static tree
c_parser_omp_clause_depend_sink(c_parser * parser,location_t clause_loc,tree list)15805 c_parser_omp_clause_depend_sink (c_parser *parser, location_t clause_loc,
15806 				 tree list)
15807 {
15808   tree vec = NULL;
15809   if (c_parser_next_token_is_not (parser, CPP_NAME)
15810       || c_parser_peek_token (parser)->id_kind != C_ID_ID)
15811     {
15812       c_parser_error (parser, "expected identifier");
15813       return list;
15814     }
15815 
15816   while (c_parser_next_token_is (parser, CPP_NAME)
15817 	 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
15818     {
15819       tree t = lookup_name (c_parser_peek_token (parser)->value);
15820       tree addend = NULL;
15821 
15822       if (t == NULL_TREE)
15823 	{
15824 	  undeclared_variable (c_parser_peek_token (parser)->location,
15825 			       c_parser_peek_token (parser)->value);
15826 	  t = error_mark_node;
15827 	}
15828 
15829       c_parser_consume_token (parser);
15830 
15831       bool neg = false;
15832       if (c_parser_next_token_is (parser, CPP_MINUS))
15833 	neg = true;
15834       else if (!c_parser_next_token_is (parser, CPP_PLUS))
15835 	{
15836 	  addend = integer_zero_node;
15837 	  neg = false;
15838 	  goto add_to_vector;
15839 	}
15840       c_parser_consume_token (parser);
15841 
15842       if (c_parser_next_token_is_not (parser, CPP_NUMBER))
15843 	{
15844 	  c_parser_error (parser, "expected integer");
15845 	  return list;
15846 	}
15847 
15848       addend = c_parser_peek_token (parser)->value;
15849       if (TREE_CODE (addend) != INTEGER_CST)
15850 	{
15851 	  c_parser_error (parser, "expected integer");
15852 	  return list;
15853 	}
15854       c_parser_consume_token (parser);
15855 
15856     add_to_vector:
15857       if (t != error_mark_node)
15858 	{
15859 	  vec = tree_cons (addend, t, vec);
15860 	  if (neg)
15861 	    OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec) = 1;
15862 	}
15863 
15864       if (c_parser_next_token_is_not (parser, CPP_COMMA)
15865 	  || c_parser_peek_2nd_token (parser)->type != CPP_NAME
15866 	  || c_parser_peek_2nd_token (parser)->id_kind != C_ID_ID)
15867 	break;
15868 
15869       c_parser_consume_token (parser);
15870     }
15871 
15872   if (vec == NULL_TREE)
15873     return list;
15874 
15875   tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
15876   OMP_CLAUSE_DEPEND_KIND (u) = OMP_CLAUSE_DEPEND_SINK;
15877   OMP_CLAUSE_DECL (u) = nreverse (vec);
15878   OMP_CLAUSE_CHAIN (u) = list;
15879   return u;
15880 }
15881 
15882 /* OpenMP 5.0:
15883    iterators ( iterators-definition )
15884 
15885    iterators-definition:
15886      iterator-specifier
15887      iterator-specifier , iterators-definition
15888 
15889    iterator-specifier:
15890      identifier = range-specification
15891      iterator-type identifier = range-specification
15892 
15893    range-specification:
15894      begin : end
15895      begin : end : step  */
15896 
15897 static tree
c_parser_omp_iterators(c_parser * parser)15898 c_parser_omp_iterators (c_parser *parser)
15899 {
15900   tree ret = NULL_TREE, *last = &ret;
15901   c_parser_consume_token (parser);
15902 
15903   push_scope ();
15904 
15905   matching_parens parens;
15906   if (!parens.require_open (parser))
15907     return error_mark_node;
15908 
15909   do
15910     {
15911       tree iter_type = NULL_TREE, type_expr = NULL_TREE;
15912       if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
15913 	{
15914 	  struct c_type_name *type = c_parser_type_name (parser);
15915 	  if (type != NULL)
15916 	    iter_type = groktypename (type, &type_expr, NULL);
15917 	}
15918       if (iter_type == NULL_TREE)
15919 	iter_type = integer_type_node;
15920 
15921       location_t loc = c_parser_peek_token (parser)->location;
15922       if (!c_parser_next_token_is (parser, CPP_NAME))
15923 	{
15924 	  c_parser_error (parser, "expected identifier");
15925 	  break;
15926 	}
15927 
15928       tree id = c_parser_peek_token (parser)->value;
15929       c_parser_consume_token (parser);
15930 
15931       if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
15932 	break;
15933 
15934       location_t eloc = c_parser_peek_token (parser)->location;
15935       c_expr expr = c_parser_expr_no_commas (parser, NULL);
15936       expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
15937       tree begin = expr.value;
15938 
15939       if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15940 	break;
15941 
15942       eloc = c_parser_peek_token (parser)->location;
15943       expr = c_parser_expr_no_commas (parser, NULL);
15944       expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
15945       tree end = expr.value;
15946 
15947       tree step = integer_one_node;
15948       if (c_parser_next_token_is (parser, CPP_COLON))
15949 	{
15950 	  c_parser_consume_token (parser);
15951 	  eloc = c_parser_peek_token (parser)->location;
15952 	  expr = c_parser_expr_no_commas (parser, NULL);
15953 	  expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
15954 	  step = expr.value;
15955 	}
15956 
15957       tree iter_var = build_decl (loc, VAR_DECL, id, iter_type);
15958       DECL_ARTIFICIAL (iter_var) = 1;
15959       DECL_CONTEXT (iter_var) = current_function_decl;
15960       pushdecl (iter_var);
15961 
15962       *last = make_tree_vec (6);
15963       TREE_VEC_ELT (*last, 0) = iter_var;
15964       TREE_VEC_ELT (*last, 1) = begin;
15965       TREE_VEC_ELT (*last, 2) = end;
15966       TREE_VEC_ELT (*last, 3) = step;
15967       last = &TREE_CHAIN (*last);
15968 
15969       if (c_parser_next_token_is (parser, CPP_COMMA))
15970 	{
15971 	  c_parser_consume_token (parser);
15972 	  continue;
15973 	}
15974       break;
15975     }
15976   while (1);
15977 
15978   parens.skip_until_found_close (parser);
15979   return ret ? ret : error_mark_node;
15980 }
15981 
15982 /* OpenMP 5.0:
15983    affinity ( [aff-modifier :] variable-list )
15984    aff-modifier:
15985      iterator ( iterators-definition )  */
15986 
15987 static tree
c_parser_omp_clause_affinity(c_parser * parser,tree list)15988 c_parser_omp_clause_affinity (c_parser *parser, tree list)
15989 {
15990   location_t clause_loc = c_parser_peek_token (parser)->location;
15991   tree nl, iterators = NULL_TREE;
15992 
15993   matching_parens parens;
15994   if (!parens.require_open (parser))
15995     return list;
15996 
15997   if (c_parser_next_token_is (parser, CPP_NAME))
15998     {
15999       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16000       bool parse_iter = ((strcmp ("iterator", p) == 0)
16001 			 && (c_parser_peek_2nd_token (parser)->type
16002 			     == CPP_OPEN_PAREN));
16003       if (parse_iter)
16004 	{
16005 	  unsigned n = 3;
16006 	  parse_iter = (c_parser_check_balanced_raw_token_sequence (parser, &n)
16007 			&& (c_parser_peek_nth_token_raw (parser, n)->type
16008 			    == CPP_CLOSE_PAREN)
16009 			&& (c_parser_peek_nth_token_raw (parser, n + 1)->type
16010 			    == CPP_COLON));
16011 	}
16012       if (parse_iter)
16013 	{
16014 	  iterators = c_parser_omp_iterators (parser);
16015 	  if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16016 	    {
16017 	      if (iterators)
16018 		pop_scope ();
16019 	      parens.skip_until_found_close (parser);
16020 	      return list;
16021 	    }
16022 	}
16023     }
16024   nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_AFFINITY,
16025 				   list);
16026   if (iterators)
16027     {
16028       tree block = pop_scope ();
16029       if (iterators != error_mark_node)
16030 	{
16031 	  TREE_VEC_ELT (iterators, 5) = block;
16032 	  for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
16033 	    OMP_CLAUSE_DECL (c) = build_tree_list (iterators,
16034 						   OMP_CLAUSE_DECL (c));
16035 	}
16036     }
16037 
16038   parens.skip_until_found_close (parser);
16039   return nl;
16040 }
16041 
16042 
16043 /* OpenMP 4.0:
16044    depend ( depend-kind: variable-list )
16045 
16046    depend-kind:
16047      in | out | inout
16048 
16049    OpenMP 4.5:
16050    depend ( source )
16051 
16052    depend ( sink  : vec )
16053 
16054    OpenMP 5.0:
16055    depend ( depend-modifier , depend-kind: variable-list )
16056 
16057    depend-kind:
16058      in | out | inout | mutexinoutset | depobj
16059 
16060    depend-modifier:
16061      iterator ( iterators-definition )  */
16062 
16063 static tree
c_parser_omp_clause_depend(c_parser * parser,tree list)16064 c_parser_omp_clause_depend (c_parser *parser, tree list)
16065 {
16066   location_t clause_loc = c_parser_peek_token (parser)->location;
16067   enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_LAST;
16068   tree nl, c, iterators = NULL_TREE;
16069 
16070   matching_parens parens;
16071   if (!parens.require_open (parser))
16072     return list;
16073 
16074   do
16075     {
16076       if (c_parser_next_token_is_not (parser, CPP_NAME))
16077 	goto invalid_kind;
16078 
16079       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16080       if (strcmp ("iterator", p) == 0 && iterators == NULL_TREE)
16081 	{
16082 	  iterators = c_parser_omp_iterators (parser);
16083 	  c_parser_require (parser, CPP_COMMA, "expected %<,%>");
16084 	  continue;
16085 	}
16086       if (strcmp ("in", p) == 0)
16087 	kind = OMP_CLAUSE_DEPEND_IN;
16088       else if (strcmp ("inout", p) == 0)
16089 	kind = OMP_CLAUSE_DEPEND_INOUT;
16090       else if (strcmp ("mutexinoutset", p) == 0)
16091 	kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
16092       else if (strcmp ("out", p) == 0)
16093 	kind = OMP_CLAUSE_DEPEND_OUT;
16094       else if (strcmp ("depobj", p) == 0)
16095 	kind = OMP_CLAUSE_DEPEND_DEPOBJ;
16096       else if (strcmp ("sink", p) == 0)
16097 	kind = OMP_CLAUSE_DEPEND_SINK;
16098       else if (strcmp ("source", p) == 0)
16099 	kind = OMP_CLAUSE_DEPEND_SOURCE;
16100       else
16101 	goto invalid_kind;
16102       break;
16103     }
16104   while (1);
16105 
16106   c_parser_consume_token (parser);
16107 
16108   if (iterators
16109       && (kind == OMP_CLAUSE_DEPEND_SOURCE || kind == OMP_CLAUSE_DEPEND_SINK))
16110     {
16111       pop_scope ();
16112       error_at (clause_loc, "%<iterator%> modifier incompatible with %qs",
16113 		kind == OMP_CLAUSE_DEPEND_SOURCE ? "source" : "sink");
16114       iterators = NULL_TREE;
16115     }
16116 
16117   if (kind == OMP_CLAUSE_DEPEND_SOURCE)
16118     {
16119       c = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
16120       OMP_CLAUSE_DEPEND_KIND (c) = kind;
16121       OMP_CLAUSE_DECL (c) = NULL_TREE;
16122       OMP_CLAUSE_CHAIN (c) = list;
16123       parens.skip_until_found_close (parser);
16124       return c;
16125     }
16126 
16127   if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16128     goto resync_fail;
16129 
16130   if (kind == OMP_CLAUSE_DEPEND_SINK)
16131     nl = c_parser_omp_clause_depend_sink (parser, clause_loc, list);
16132   else
16133     {
16134       nl = c_parser_omp_variable_list (parser, clause_loc,
16135 				       OMP_CLAUSE_DEPEND, list);
16136 
16137       if (iterators)
16138 	{
16139 	  tree block = pop_scope ();
16140 	  if (iterators == error_mark_node)
16141 	    iterators = NULL_TREE;
16142 	  else
16143 	    TREE_VEC_ELT (iterators, 5) = block;
16144 	}
16145 
16146       for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
16147 	{
16148 	  OMP_CLAUSE_DEPEND_KIND (c) = kind;
16149 	  if (iterators)
16150 	    OMP_CLAUSE_DECL (c)
16151 	      = build_tree_list (iterators, OMP_CLAUSE_DECL (c));
16152 	}
16153     }
16154 
16155   parens.skip_until_found_close (parser);
16156   return nl;
16157 
16158  invalid_kind:
16159   c_parser_error (parser, "invalid depend kind");
16160  resync_fail:
16161   parens.skip_until_found_close (parser);
16162   if (iterators)
16163     pop_scope ();
16164   return list;
16165 }
16166 
16167 /* OpenMP 4.0:
16168    map ( map-kind: variable-list )
16169    map ( variable-list )
16170 
16171    map-kind:
16172      alloc | to | from | tofrom
16173 
16174    OpenMP 4.5:
16175    map-kind:
16176      alloc | to | from | tofrom | release | delete
16177 
16178    map ( always [,] map-kind: variable-list )
16179 
16180    OpenMP 5.0:
16181    map ( [map-type-modifier[,] ...] map-kind: variable-list )
16182 
16183    map-type-modifier:
16184      always | close */
16185 
16186 static tree
c_parser_omp_clause_map(c_parser * parser,tree list)16187 c_parser_omp_clause_map (c_parser *parser, tree list)
16188 {
16189   location_t clause_loc = c_parser_peek_token (parser)->location;
16190   enum gomp_map_kind kind = GOMP_MAP_TOFROM;
16191   tree nl, c;
16192 
16193   matching_parens parens;
16194   if (!parens.require_open (parser))
16195     return list;
16196 
16197   int pos = 1;
16198   int map_kind_pos = 0;
16199   while (c_parser_peek_nth_token_raw (parser, pos)->type == CPP_NAME)
16200     {
16201       if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COLON)
16202 	{
16203 	  map_kind_pos = pos;
16204 	  break;
16205 	}
16206 
16207       if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COMMA)
16208 	pos++;
16209       pos++;
16210     }
16211 
16212   int always_modifier = 0;
16213   int close_modifier = 0;
16214   for (int pos = 1; pos < map_kind_pos; ++pos)
16215     {
16216       c_token *tok = c_parser_peek_token (parser);
16217 
16218       if (tok->type == CPP_COMMA)
16219 	{
16220 	  c_parser_consume_token (parser);
16221 	  continue;
16222 	}
16223 
16224       const char *p = IDENTIFIER_POINTER (tok->value);
16225       if (strcmp ("always", p) == 0)
16226 	{
16227 	  if (always_modifier)
16228 	    {
16229 	      c_parser_error (parser, "too many %<always%> modifiers");
16230 	      parens.skip_until_found_close (parser);
16231 	      return list;
16232 	    }
16233 	  always_modifier++;
16234 	}
16235       else if (strcmp ("close", p) == 0)
16236 	{
16237 	  if (close_modifier)
16238 	    {
16239 	      c_parser_error (parser, "too many %<close%> modifiers");
16240 	      parens.skip_until_found_close (parser);
16241 	      return list;
16242 	    }
16243 	  close_modifier++;
16244 	}
16245       else
16246 	{
16247 	  c_parser_error (parser, "%<#pragma omp target%> with "
16248 				  "modifier other than %<always%> or "
16249 				  "%<close%> on %<map%> clause");
16250 	  parens.skip_until_found_close (parser);
16251 	  return list;
16252 	}
16253 
16254 	c_parser_consume_token (parser);
16255     }
16256 
16257   if (c_parser_next_token_is (parser, CPP_NAME)
16258       && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
16259     {
16260       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16261       if (strcmp ("alloc", p) == 0)
16262 	kind = GOMP_MAP_ALLOC;
16263       else if (strcmp ("to", p) == 0)
16264 	kind = always_modifier ? GOMP_MAP_ALWAYS_TO : GOMP_MAP_TO;
16265       else if (strcmp ("from", p) == 0)
16266 	kind = always_modifier ? GOMP_MAP_ALWAYS_FROM : GOMP_MAP_FROM;
16267       else if (strcmp ("tofrom", p) == 0)
16268 	kind = always_modifier ? GOMP_MAP_ALWAYS_TOFROM : GOMP_MAP_TOFROM;
16269       else if (strcmp ("release", p) == 0)
16270 	kind = GOMP_MAP_RELEASE;
16271       else if (strcmp ("delete", p) == 0)
16272 	kind = GOMP_MAP_DELETE;
16273       else
16274 	{
16275 	  c_parser_error (parser, "invalid map kind");
16276 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
16277 				     "expected %<)%>");
16278 	  return list;
16279 	}
16280       c_parser_consume_token (parser);
16281       c_parser_consume_token (parser);
16282     }
16283 
16284   nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_MAP, list,
16285 				   true);
16286 
16287   for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
16288     OMP_CLAUSE_SET_MAP_KIND (c, kind);
16289 
16290   parens.skip_until_found_close (parser);
16291   return nl;
16292 }
16293 
16294 /* OpenMP 4.0:
16295    device ( expression )
16296 
16297    OpenMP 5.0:
16298    device ( [device-modifier :] integer-expression )
16299 
16300    device-modifier:
16301      ancestor | device_num */
16302 
16303 static tree
c_parser_omp_clause_device(c_parser * parser,tree list)16304 c_parser_omp_clause_device (c_parser *parser, tree list)
16305 {
16306   location_t clause_loc = c_parser_peek_token (parser)->location;
16307   location_t expr_loc;
16308   c_expr expr;
16309   tree c, t;
16310   bool ancestor = false;
16311 
16312   matching_parens parens;
16313   if (!parens.require_open (parser))
16314     return list;
16315 
16316   if (c_parser_next_token_is (parser, CPP_NAME)
16317       && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
16318     {
16319       c_token *tok = c_parser_peek_token (parser);
16320       const char *p = IDENTIFIER_POINTER (tok->value);
16321       if (strcmp ("ancestor", p) == 0)
16322 	{
16323 	  /* A requires directive with the reverse_offload clause must be
16324 	  specified.  */
16325 	  if ((omp_requires_mask & OMP_REQUIRES_REVERSE_OFFLOAD) == 0)
16326 	    {
16327 	      error_at (tok->location, "%<ancestor%> device modifier not "
16328 				       "preceded by %<requires%> directive "
16329 				       "with %<reverse_offload%> clause");
16330 	      parens.skip_until_found_close (parser);
16331 	      return list;
16332 	    }
16333 	  ancestor = true;
16334 	}
16335       else if (strcmp ("device_num", p) == 0)
16336 	;
16337       else
16338 	{
16339 	  error_at (tok->location, "expected %<ancestor%> or %<device_num%>");
16340 	  parens.skip_until_found_close (parser);
16341 	  return list;
16342 	}
16343       c_parser_consume_token (parser);
16344       c_parser_consume_token (parser);
16345     }
16346 
16347   expr_loc = c_parser_peek_token (parser)->location;
16348   expr = c_parser_expr_no_commas (parser, NULL);
16349   expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16350   t = expr.value;
16351   t = c_fully_fold (t, false, NULL);
16352 
16353   parens.skip_until_found_close (parser);
16354 
16355   if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16356     {
16357       c_parser_error (parser, "expected integer expression");
16358       return list;
16359     }
16360   if (ancestor && TREE_CODE (t) == INTEGER_CST && !integer_onep (t))
16361     {
16362       error_at (expr_loc, "the %<device%> clause expression must evaluate to "
16363 			  "%<1%>");
16364       return list;
16365     }
16366 
16367   check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE, "device");
16368 
16369   c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE);
16370 
16371   OMP_CLAUSE_DEVICE_ID (c) = t;
16372   OMP_CLAUSE_CHAIN (c) = list;
16373   OMP_CLAUSE_DEVICE_ANCESTOR (c) = ancestor;
16374 
16375   list = c;
16376   return list;
16377 }
16378 
16379 /* OpenMP 4.0:
16380    dist_schedule ( static )
16381    dist_schedule ( static , expression ) */
16382 
16383 static tree
c_parser_omp_clause_dist_schedule(c_parser * parser,tree list)16384 c_parser_omp_clause_dist_schedule (c_parser *parser, tree list)
16385 {
16386   tree c, t = NULL_TREE;
16387   location_t loc = c_parser_peek_token (parser)->location;
16388 
16389   matching_parens parens;
16390   if (!parens.require_open (parser))
16391     return list;
16392 
16393   if (!c_parser_next_token_is_keyword (parser, RID_STATIC))
16394     {
16395       c_parser_error (parser, "invalid dist_schedule kind");
16396       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
16397 				 "expected %<)%>");
16398       return list;
16399     }
16400 
16401   c_parser_consume_token (parser);
16402   if (c_parser_next_token_is (parser, CPP_COMMA))
16403     {
16404       c_parser_consume_token (parser);
16405 
16406       location_t expr_loc = c_parser_peek_token (parser)->location;
16407       c_expr expr = c_parser_expr_no_commas (parser, NULL);
16408       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16409       t = expr.value;
16410       t = c_fully_fold (t, false, NULL);
16411       parens.skip_until_found_close (parser);
16412     }
16413   else
16414     c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
16415 			       "expected %<,%> or %<)%>");
16416 
16417   /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
16418 				"dist_schedule"); */
16419   if (omp_find_clause (list, OMP_CLAUSE_DIST_SCHEDULE))
16420     warning_at (loc, 0, "too many %qs clauses", "dist_schedule");
16421   if (t == error_mark_node)
16422     return list;
16423 
16424   c = build_omp_clause (loc, OMP_CLAUSE_DIST_SCHEDULE);
16425   OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t;
16426   OMP_CLAUSE_CHAIN (c) = list;
16427   return c;
16428 }
16429 
16430 /* OpenMP 4.0:
16431    proc_bind ( proc-bind-kind )
16432 
16433    proc-bind-kind:
16434      primary | master | close | spread
16435    where OpenMP 5.1 added 'primary' and deprecated the alias 'master'.  */
16436 
16437 static tree
c_parser_omp_clause_proc_bind(c_parser * parser,tree list)16438 c_parser_omp_clause_proc_bind (c_parser *parser, tree list)
16439 {
16440   location_t clause_loc = c_parser_peek_token (parser)->location;
16441   enum omp_clause_proc_bind_kind kind;
16442   tree c;
16443 
16444   matching_parens parens;
16445   if (!parens.require_open (parser))
16446     return list;
16447 
16448   if (c_parser_next_token_is (parser, CPP_NAME))
16449     {
16450       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16451       if (strcmp ("primary", p) == 0)
16452 	kind = OMP_CLAUSE_PROC_BIND_PRIMARY;
16453       else if (strcmp ("master", p) == 0)
16454 	kind = OMP_CLAUSE_PROC_BIND_MASTER;
16455       else if (strcmp ("close", p) == 0)
16456 	kind = OMP_CLAUSE_PROC_BIND_CLOSE;
16457       else if (strcmp ("spread", p) == 0)
16458 	kind = OMP_CLAUSE_PROC_BIND_SPREAD;
16459       else
16460 	goto invalid_kind;
16461     }
16462   else
16463     goto invalid_kind;
16464 
16465   check_no_duplicate_clause (list, OMP_CLAUSE_PROC_BIND, "proc_bind");
16466   c_parser_consume_token (parser);
16467   parens.skip_until_found_close (parser);
16468   c = build_omp_clause (clause_loc, OMP_CLAUSE_PROC_BIND);
16469   OMP_CLAUSE_PROC_BIND_KIND (c) = kind;
16470   OMP_CLAUSE_CHAIN (c) = list;
16471   return c;
16472 
16473  invalid_kind:
16474   c_parser_error (parser, "invalid proc_bind kind");
16475   parens.skip_until_found_close (parser);
16476   return list;
16477 }
16478 
16479 /* OpenMP 5.0:
16480    device_type ( host | nohost | any )  */
16481 
16482 static tree
c_parser_omp_clause_device_type(c_parser * parser,tree list)16483 c_parser_omp_clause_device_type (c_parser *parser, tree list)
16484 {
16485   location_t clause_loc = c_parser_peek_token (parser)->location;
16486   enum omp_clause_device_type_kind kind;
16487   tree c;
16488 
16489   matching_parens parens;
16490   if (!parens.require_open (parser))
16491     return list;
16492 
16493   if (c_parser_next_token_is (parser, CPP_NAME))
16494     {
16495       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16496       if (strcmp ("host", p) == 0)
16497 	kind = OMP_CLAUSE_DEVICE_TYPE_HOST;
16498       else if (strcmp ("nohost", p) == 0)
16499 	kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
16500       else if (strcmp ("any", p) == 0)
16501 	kind = OMP_CLAUSE_DEVICE_TYPE_ANY;
16502       else
16503 	goto invalid_kind;
16504     }
16505   else
16506     goto invalid_kind;
16507 
16508   /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE,
16509 				"device_type");  */
16510   c_parser_consume_token (parser);
16511   parens.skip_until_found_close (parser);
16512   c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE_TYPE);
16513   OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind;
16514   OMP_CLAUSE_CHAIN (c) = list;
16515   return c;
16516 
16517  invalid_kind:
16518   c_parser_error (parser, "expected %<host%>, %<nohost%> or %<any%>");
16519   parens.skip_until_found_close (parser);
16520   return list;
16521 }
16522 
16523 /* OpenMP 4.0:
16524    to ( variable-list ) */
16525 
16526 static tree
c_parser_omp_clause_to(c_parser * parser,tree list)16527 c_parser_omp_clause_to (c_parser *parser, tree list)
16528 {
16529   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO, list, true);
16530 }
16531 
16532 /* OpenMP 4.0:
16533    from ( variable-list ) */
16534 
16535 static tree
c_parser_omp_clause_from(c_parser * parser,tree list)16536 c_parser_omp_clause_from (c_parser *parser, tree list)
16537 {
16538   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FROM, list, true);
16539 }
16540 
16541 /* OpenMP 4.0:
16542    uniform ( variable-list ) */
16543 
16544 static tree
c_parser_omp_clause_uniform(c_parser * parser,tree list)16545 c_parser_omp_clause_uniform (c_parser *parser, tree list)
16546 {
16547   /* The clauses location.  */
16548   location_t loc = c_parser_peek_token (parser)->location;
16549 
16550   matching_parens parens;
16551   if (parens.require_open (parser))
16552     {
16553       list = c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_UNIFORM,
16554 					 list);
16555       parens.skip_until_found_close (parser);
16556     }
16557   return list;
16558 }
16559 
16560 /* OpenMP 5.0:
16561    detach ( event-handle ) */
16562 
16563 static tree
c_parser_omp_clause_detach(c_parser * parser,tree list)16564 c_parser_omp_clause_detach (c_parser *parser, tree list)
16565 {
16566   matching_parens parens;
16567   location_t clause_loc = c_parser_peek_token (parser)->location;
16568 
16569   if (!parens.require_open (parser))
16570     return list;
16571 
16572   if (c_parser_next_token_is_not (parser, CPP_NAME)
16573       || c_parser_peek_token (parser)->id_kind != C_ID_ID)
16574     {
16575       c_parser_error (parser, "expected identifier");
16576       parens.skip_until_found_close (parser);
16577       return list;
16578     }
16579 
16580   tree t = lookup_name (c_parser_peek_token (parser)->value);
16581   if (t == NULL_TREE)
16582     {
16583       undeclared_variable (c_parser_peek_token (parser)->location,
16584 			   c_parser_peek_token (parser)->value);
16585       parens.skip_until_found_close (parser);
16586       return list;
16587     }
16588   c_parser_consume_token (parser);
16589 
16590   tree type = TYPE_MAIN_VARIANT (TREE_TYPE (t));
16591   if (!INTEGRAL_TYPE_P (type)
16592       || TREE_CODE (type) != ENUMERAL_TYPE
16593       || TYPE_NAME (type) != get_identifier ("omp_event_handle_t"))
16594     {
16595       error_at (clause_loc, "%<detach%> clause event handle "
16596 			    "has type %qT rather than "
16597 			    "%<omp_event_handle_t%>",
16598 			    type);
16599       parens.skip_until_found_close (parser);
16600       return list;
16601     }
16602 
16603   tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DETACH);
16604   OMP_CLAUSE_DECL (u) = t;
16605   OMP_CLAUSE_CHAIN (u) = list;
16606   parens.skip_until_found_close (parser);
16607   return u;
16608 }
16609 
16610 /* Parse all OpenACC clauses.  The set clauses allowed by the directive
16611    is a bitmask in MASK.  Return the list of clauses found.  */
16612 
16613 static tree
c_parser_oacc_all_clauses(c_parser * parser,omp_clause_mask mask,const char * where,bool finish_p=true)16614 c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask,
16615 			   const char *where, bool finish_p = true)
16616 {
16617   tree clauses = NULL;
16618   bool first = true;
16619 
16620   while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
16621     {
16622       location_t here;
16623       pragma_omp_clause c_kind;
16624       const char *c_name;
16625       tree prev = clauses;
16626 
16627       if (!first && c_parser_next_token_is (parser, CPP_COMMA))
16628 	c_parser_consume_token (parser);
16629 
16630       here = c_parser_peek_token (parser)->location;
16631       c_kind = c_parser_omp_clause_name (parser);
16632 
16633       switch (c_kind)
16634 	{
16635 	case PRAGMA_OACC_CLAUSE_ASYNC:
16636 	  clauses = c_parser_oacc_clause_async (parser, clauses);
16637 	  c_name = "async";
16638 	  break;
16639 	case PRAGMA_OACC_CLAUSE_AUTO:
16640 	  clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_AUTO,
16641 						 clauses);
16642 	  c_name = "auto";
16643 	  break;
16644 	case PRAGMA_OACC_CLAUSE_ATTACH:
16645 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16646 	  c_name = "attach";
16647 	  break;
16648 	case PRAGMA_OACC_CLAUSE_COLLAPSE:
16649 	  clauses = c_parser_omp_clause_collapse (parser, clauses);
16650 	  c_name = "collapse";
16651 	  break;
16652 	case PRAGMA_OACC_CLAUSE_COPY:
16653 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16654 	  c_name = "copy";
16655 	  break;
16656 	case PRAGMA_OACC_CLAUSE_COPYIN:
16657 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16658 	  c_name = "copyin";
16659 	  break;
16660 	case PRAGMA_OACC_CLAUSE_COPYOUT:
16661 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16662 	  c_name = "copyout";
16663 	  break;
16664 	case PRAGMA_OACC_CLAUSE_CREATE:
16665 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16666 	  c_name = "create";
16667 	  break;
16668 	case PRAGMA_OACC_CLAUSE_DELETE:
16669 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16670 	  c_name = "delete";
16671 	  break;
16672 	case PRAGMA_OMP_CLAUSE_DEFAULT:
16673 	  clauses = c_parser_omp_clause_default (parser, clauses, true);
16674 	  c_name = "default";
16675 	  break;
16676 	case PRAGMA_OACC_CLAUSE_DETACH:
16677 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16678 	  c_name = "detach";
16679 	  break;
16680 	case PRAGMA_OACC_CLAUSE_DEVICE:
16681 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16682 	  c_name = "device";
16683 	  break;
16684 	case PRAGMA_OACC_CLAUSE_DEVICEPTR:
16685 	  clauses = c_parser_oacc_data_clause_deviceptr (parser, clauses);
16686 	  c_name = "deviceptr";
16687 	  break;
16688 	case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
16689 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16690 	  c_name = "device_resident";
16691 	  break;
16692 	case PRAGMA_OACC_CLAUSE_FINALIZE:
16693 	  clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_FINALIZE,
16694 						 clauses);
16695 	  c_name = "finalize";
16696 	  break;
16697 	case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE:
16698 	  clauses = c_parser_omp_clause_firstprivate (parser, clauses);
16699 	  c_name = "firstprivate";
16700 	  break;
16701 	case PRAGMA_OACC_CLAUSE_GANG:
16702 	  c_name = "gang";
16703 	  clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_GANG,
16704 						c_name, clauses);
16705 	  break;
16706 	case PRAGMA_OACC_CLAUSE_HOST:
16707 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16708 	  c_name = "host";
16709 	  break;
16710 	case PRAGMA_OACC_CLAUSE_IF:
16711 	  clauses = c_parser_omp_clause_if (parser, clauses, false);
16712 	  c_name = "if";
16713 	  break;
16714 	case PRAGMA_OACC_CLAUSE_IF_PRESENT:
16715 	  clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_IF_PRESENT,
16716 						 clauses);
16717 	  c_name = "if_present";
16718 	  break;
16719 	case PRAGMA_OACC_CLAUSE_INDEPENDENT:
16720 	  clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_INDEPENDENT,
16721 						 clauses);
16722 	  c_name = "independent";
16723 	  break;
16724 	case PRAGMA_OACC_CLAUSE_LINK:
16725 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16726 	  c_name = "link";
16727 	  break;
16728 	case PRAGMA_OACC_CLAUSE_NO_CREATE:
16729 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16730 	  c_name = "no_create";
16731 	  break;
16732 	case PRAGMA_OACC_CLAUSE_NOHOST:
16733 	  clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_NOHOST,
16734 						 clauses);
16735 	  c_name = "nohost";
16736 	  break;
16737 	case PRAGMA_OACC_CLAUSE_NUM_GANGS:
16738 	  clauses = c_parser_oacc_single_int_clause (parser,
16739 						     OMP_CLAUSE_NUM_GANGS,
16740 						     clauses);
16741 	  c_name = "num_gangs";
16742 	  break;
16743 	case PRAGMA_OACC_CLAUSE_NUM_WORKERS:
16744 	  clauses = c_parser_oacc_single_int_clause (parser,
16745 						     OMP_CLAUSE_NUM_WORKERS,
16746 						     clauses);
16747 	  c_name = "num_workers";
16748 	  break;
16749 	case PRAGMA_OACC_CLAUSE_PRESENT:
16750 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16751 	  c_name = "present";
16752 	  break;
16753 	case PRAGMA_OACC_CLAUSE_PRIVATE:
16754 	  clauses = c_parser_omp_clause_private (parser, clauses);
16755 	  c_name = "private";
16756 	  break;
16757 	case PRAGMA_OACC_CLAUSE_REDUCTION:
16758 	  clauses
16759 	    = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
16760 					     false, clauses);
16761 	  c_name = "reduction";
16762 	  break;
16763 	case PRAGMA_OACC_CLAUSE_SEQ:
16764 	  clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_SEQ,
16765 						 clauses);
16766 	  c_name = "seq";
16767 	  break;
16768 	case PRAGMA_OACC_CLAUSE_TILE:
16769 	  clauses = c_parser_oacc_clause_tile (parser, clauses);
16770 	  c_name = "tile";
16771 	  break;
16772 	case PRAGMA_OACC_CLAUSE_USE_DEVICE:
16773 	  clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
16774 	  c_name = "use_device";
16775 	  break;
16776 	case PRAGMA_OACC_CLAUSE_VECTOR:
16777 	  c_name = "vector";
16778 	  clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_VECTOR,
16779 						c_name,	clauses);
16780 	  break;
16781 	case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH:
16782 	  clauses = c_parser_oacc_single_int_clause (parser,
16783 						     OMP_CLAUSE_VECTOR_LENGTH,
16784 						     clauses);
16785 	  c_name = "vector_length";
16786 	  break;
16787 	case PRAGMA_OACC_CLAUSE_WAIT:
16788 	  clauses = c_parser_oacc_clause_wait (parser, clauses);
16789 	  c_name = "wait";
16790 	  break;
16791 	case PRAGMA_OACC_CLAUSE_WORKER:
16792 	  c_name = "worker";
16793 	  clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_WORKER,
16794 						c_name, clauses);
16795 	  break;
16796 	default:
16797 	  c_parser_error (parser, "expected %<#pragma acc%> clause");
16798 	  goto saw_error;
16799 	}
16800 
16801       first = false;
16802 
16803       if (((mask >> c_kind) & 1) == 0)
16804 	{
16805 	  /* Remove the invalid clause(s) from the list to avoid
16806 	     confusing the rest of the compiler.  */
16807 	  clauses = prev;
16808 	  error_at (here, "%qs is not valid for %qs", c_name, where);
16809 	}
16810     }
16811 
16812  saw_error:
16813   c_parser_skip_to_pragma_eol (parser);
16814 
16815   if (finish_p)
16816     return c_finish_omp_clauses (clauses, C_ORT_ACC);
16817 
16818   return clauses;
16819 }
16820 
16821 /* Parse all OpenMP clauses.  The set clauses allowed by the directive
16822    is a bitmask in MASK.  Return the list of clauses found.
16823    FINISH_P set if c_finish_omp_clauses should be called.
16824    NESTED non-zero if clauses should be terminated by closing paren instead
16825    of end of pragma.  If it is 2, additionally commas are required in between
16826    the clauses.  */
16827 
16828 static tree
c_parser_omp_all_clauses(c_parser * parser,omp_clause_mask mask,const char * where,bool finish_p=true,int nested=0)16829 c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
16830 			  const char *where, bool finish_p = true,
16831 			  int nested = 0)
16832 {
16833   tree clauses = NULL;
16834   bool first = true;
16835 
16836   while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
16837     {
16838       location_t here;
16839       pragma_omp_clause c_kind;
16840       const char *c_name;
16841       tree prev = clauses;
16842 
16843       if (nested && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
16844 	break;
16845 
16846       if (!first)
16847 	{
16848 	  if (c_parser_next_token_is (parser, CPP_COMMA))
16849 	    c_parser_consume_token (parser);
16850 	  else if (nested == 2)
16851 	    error_at (c_parser_peek_token (parser)->location,
16852 		      "clauses in %<simd%> trait should be separated "
16853 		      "by %<,%>");
16854 	}
16855 
16856       here = c_parser_peek_token (parser)->location;
16857       c_kind = c_parser_omp_clause_name (parser);
16858 
16859       switch (c_kind)
16860 	{
16861 	case PRAGMA_OMP_CLAUSE_BIND:
16862 	  clauses = c_parser_omp_clause_bind (parser, clauses);
16863 	  c_name = "bind";
16864 	  break;
16865 	case PRAGMA_OMP_CLAUSE_COLLAPSE:
16866 	  clauses = c_parser_omp_clause_collapse (parser, clauses);
16867 	  c_name = "collapse";
16868 	  break;
16869 	case PRAGMA_OMP_CLAUSE_COPYIN:
16870 	  clauses = c_parser_omp_clause_copyin (parser, clauses);
16871 	  c_name = "copyin";
16872 	  break;
16873 	case PRAGMA_OMP_CLAUSE_COPYPRIVATE:
16874 	  clauses = c_parser_omp_clause_copyprivate (parser, clauses);
16875 	  c_name = "copyprivate";
16876 	  break;
16877 	case PRAGMA_OMP_CLAUSE_DEFAULT:
16878 	  clauses = c_parser_omp_clause_default (parser, clauses, false);
16879 	  c_name = "default";
16880 	  break;
16881 	case PRAGMA_OMP_CLAUSE_DETACH:
16882 	  clauses = c_parser_omp_clause_detach (parser, clauses);
16883 	  c_name = "detach";
16884 	  break;
16885 	case PRAGMA_OMP_CLAUSE_FILTER:
16886 	  clauses = c_parser_omp_clause_filter (parser, clauses);
16887 	  c_name = "filter";
16888 	  break;
16889 	case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
16890 	  clauses = c_parser_omp_clause_firstprivate (parser, clauses);
16891 	  c_name = "firstprivate";
16892 	  break;
16893 	case PRAGMA_OMP_CLAUSE_FINAL:
16894 	  clauses = c_parser_omp_clause_final (parser, clauses);
16895 	  c_name = "final";
16896 	  break;
16897 	case PRAGMA_OMP_CLAUSE_GRAINSIZE:
16898 	  clauses = c_parser_omp_clause_grainsize (parser, clauses);
16899 	  c_name = "grainsize";
16900 	  break;
16901 	case PRAGMA_OMP_CLAUSE_HINT:
16902 	  clauses = c_parser_omp_clause_hint (parser, clauses);
16903 	  c_name = "hint";
16904 	  break;
16905 	case PRAGMA_OMP_CLAUSE_DEFAULTMAP:
16906 	  clauses = c_parser_omp_clause_defaultmap (parser, clauses);
16907 	  c_name = "defaultmap";
16908 	  break;
16909 	case PRAGMA_OMP_CLAUSE_IF:
16910 	  clauses = c_parser_omp_clause_if (parser, clauses, true);
16911 	  c_name = "if";
16912 	  break;
16913 	case PRAGMA_OMP_CLAUSE_IN_REDUCTION:
16914 	  clauses
16915 	    = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION,
16916 					     true, clauses);
16917 	  c_name = "in_reduction";
16918 	  break;
16919 	case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
16920 	  clauses = c_parser_omp_clause_lastprivate (parser, clauses);
16921 	  c_name = "lastprivate";
16922 	  break;
16923 	case PRAGMA_OMP_CLAUSE_MERGEABLE:
16924 	  clauses = c_parser_omp_clause_mergeable (parser, clauses);
16925 	  c_name = "mergeable";
16926 	  break;
16927 	case PRAGMA_OMP_CLAUSE_NOWAIT:
16928 	  clauses = c_parser_omp_clause_nowait (parser, clauses);
16929 	  c_name = "nowait";
16930 	  break;
16931 	case PRAGMA_OMP_CLAUSE_NUM_TASKS:
16932 	  clauses = c_parser_omp_clause_num_tasks (parser, clauses);
16933 	  c_name = "num_tasks";
16934 	  break;
16935 	case PRAGMA_OMP_CLAUSE_NUM_THREADS:
16936 	  clauses = c_parser_omp_clause_num_threads (parser, clauses);
16937 	  c_name = "num_threads";
16938 	  break;
16939 	case PRAGMA_OMP_CLAUSE_ORDER:
16940 	  clauses = c_parser_omp_clause_order (parser, clauses);
16941 	  c_name = "order";
16942 	  break;
16943 	case PRAGMA_OMP_CLAUSE_ORDERED:
16944 	  clauses = c_parser_omp_clause_ordered (parser, clauses);
16945 	  c_name = "ordered";
16946 	  break;
16947 	case PRAGMA_OMP_CLAUSE_PRIORITY:
16948 	  clauses = c_parser_omp_clause_priority (parser, clauses);
16949 	  c_name = "priority";
16950 	  break;
16951 	case PRAGMA_OMP_CLAUSE_PRIVATE:
16952 	  clauses = c_parser_omp_clause_private (parser, clauses);
16953 	  c_name = "private";
16954 	  break;
16955 	case PRAGMA_OMP_CLAUSE_REDUCTION:
16956 	  clauses
16957 	    = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
16958 					     true, clauses);
16959 	  c_name = "reduction";
16960 	  break;
16961 	case PRAGMA_OMP_CLAUSE_SCHEDULE:
16962 	  clauses = c_parser_omp_clause_schedule (parser, clauses);
16963 	  c_name = "schedule";
16964 	  break;
16965 	case PRAGMA_OMP_CLAUSE_SHARED:
16966 	  clauses = c_parser_omp_clause_shared (parser, clauses);
16967 	  c_name = "shared";
16968 	  break;
16969 	case PRAGMA_OMP_CLAUSE_TASK_REDUCTION:
16970 	  clauses
16971 	    = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_TASK_REDUCTION,
16972 					     true, clauses);
16973 	  c_name = "task_reduction";
16974 	  break;
16975 	case PRAGMA_OMP_CLAUSE_UNTIED:
16976 	  clauses = c_parser_omp_clause_untied (parser, clauses);
16977 	  c_name = "untied";
16978 	  break;
16979 	case PRAGMA_OMP_CLAUSE_INBRANCH:
16980 	  clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_INBRANCH,
16981 						clauses);
16982 	  c_name = "inbranch";
16983 	  break;
16984 	case PRAGMA_OMP_CLAUSE_NONTEMPORAL:
16985 	  clauses = c_parser_omp_clause_nontemporal (parser, clauses);
16986 	  c_name = "nontemporal";
16987 	  break;
16988 	case PRAGMA_OMP_CLAUSE_NOTINBRANCH:
16989 	  clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_NOTINBRANCH,
16990 						clauses);
16991 	  c_name = "notinbranch";
16992 	  break;
16993 	case PRAGMA_OMP_CLAUSE_PARALLEL:
16994 	  clauses
16995 	    = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_PARALLEL,
16996 					      clauses);
16997 	  c_name = "parallel";
16998 	  if (!first)
16999 	    {
17000 	     clause_not_first:
17001 	      error_at (here, "%qs must be the first clause of %qs",
17002 			c_name, where);
17003 	      clauses = prev;
17004 	    }
17005 	  break;
17006 	case PRAGMA_OMP_CLAUSE_FOR:
17007 	  clauses
17008 	    = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_FOR,
17009 					      clauses);
17010 	  c_name = "for";
17011 	  if (!first)
17012 	    goto clause_not_first;
17013 	  break;
17014 	case PRAGMA_OMP_CLAUSE_SECTIONS:
17015 	  clauses
17016 	    = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_SECTIONS,
17017 					      clauses);
17018 	  c_name = "sections";
17019 	  if (!first)
17020 	    goto clause_not_first;
17021 	  break;
17022 	case PRAGMA_OMP_CLAUSE_TASKGROUP:
17023 	  clauses
17024 	    = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_TASKGROUP,
17025 					      clauses);
17026 	  c_name = "taskgroup";
17027 	  if (!first)
17028 	    goto clause_not_first;
17029 	  break;
17030 	case PRAGMA_OMP_CLAUSE_LINK:
17031 	  clauses
17032 	    = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LINK, clauses);
17033 	  c_name = "link";
17034 	  break;
17035 	case PRAGMA_OMP_CLAUSE_TO:
17036 	  if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0)
17037 	    clauses
17038 	      = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO_DECLARE,
17039 					      clauses);
17040 	  else
17041 	    clauses = c_parser_omp_clause_to (parser, clauses);
17042 	  c_name = "to";
17043 	  break;
17044 	case PRAGMA_OMP_CLAUSE_FROM:
17045 	  clauses = c_parser_omp_clause_from (parser, clauses);
17046 	  c_name = "from";
17047 	  break;
17048 	case PRAGMA_OMP_CLAUSE_UNIFORM:
17049 	  clauses = c_parser_omp_clause_uniform (parser, clauses);
17050 	  c_name = "uniform";
17051 	  break;
17052 	case PRAGMA_OMP_CLAUSE_NUM_TEAMS:
17053 	  clauses = c_parser_omp_clause_num_teams (parser, clauses);
17054 	  c_name = "num_teams";
17055 	  break;
17056 	case PRAGMA_OMP_CLAUSE_THREAD_LIMIT:
17057 	  clauses = c_parser_omp_clause_thread_limit (parser, clauses);
17058 	  c_name = "thread_limit";
17059 	  break;
17060 	case PRAGMA_OMP_CLAUSE_ALIGNED:
17061 	  clauses = c_parser_omp_clause_aligned (parser, clauses);
17062 	  c_name = "aligned";
17063 	  break;
17064 	case PRAGMA_OMP_CLAUSE_ALLOCATE:
17065 	  clauses = c_parser_omp_clause_allocate (parser, clauses);
17066 	  c_name = "allocate";
17067 	  break;
17068 	case PRAGMA_OMP_CLAUSE_LINEAR:
17069 	  clauses = c_parser_omp_clause_linear (parser, clauses);
17070 	  c_name = "linear";
17071 	  break;
17072 	case PRAGMA_OMP_CLAUSE_AFFINITY:
17073 	  clauses = c_parser_omp_clause_affinity (parser, clauses);
17074 	  c_name = "affinity";
17075 	  break;
17076 	case PRAGMA_OMP_CLAUSE_DEPEND:
17077 	  clauses = c_parser_omp_clause_depend (parser, clauses);
17078 	  c_name = "depend";
17079 	  break;
17080 	case PRAGMA_OMP_CLAUSE_MAP:
17081 	  clauses = c_parser_omp_clause_map (parser, clauses);
17082 	  c_name = "map";
17083 	  break;
17084 	case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR:
17085 	  clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
17086 	  c_name = "use_device_ptr";
17087 	  break;
17088 	case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR:
17089 	  clauses = c_parser_omp_clause_use_device_addr (parser, clauses);
17090 	  c_name = "use_device_addr";
17091 	  break;
17092 	case PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR:
17093 	  clauses = c_parser_omp_clause_has_device_addr (parser, clauses);
17094 	  c_name = "has_device_addr";
17095 	  break;
17096 	case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR:
17097 	  clauses = c_parser_omp_clause_is_device_ptr (parser, clauses);
17098 	  c_name = "is_device_ptr";
17099 	  break;
17100 	case PRAGMA_OMP_CLAUSE_DEVICE:
17101 	  clauses = c_parser_omp_clause_device (parser, clauses);
17102 	  c_name = "device";
17103 	  break;
17104 	case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE:
17105 	  clauses = c_parser_omp_clause_dist_schedule (parser, clauses);
17106 	  c_name = "dist_schedule";
17107 	  break;
17108 	case PRAGMA_OMP_CLAUSE_PROC_BIND:
17109 	  clauses = c_parser_omp_clause_proc_bind (parser, clauses);
17110 	  c_name = "proc_bind";
17111 	  break;
17112 	case PRAGMA_OMP_CLAUSE_DEVICE_TYPE:
17113 	  clauses = c_parser_omp_clause_device_type (parser, clauses);
17114 	  c_name = "device_type";
17115 	  break;
17116 	case PRAGMA_OMP_CLAUSE_SAFELEN:
17117 	  clauses = c_parser_omp_clause_safelen (parser, clauses);
17118 	  c_name = "safelen";
17119 	  break;
17120 	case PRAGMA_OMP_CLAUSE_SIMDLEN:
17121 	  clauses = c_parser_omp_clause_simdlen (parser, clauses);
17122 	  c_name = "simdlen";
17123 	  break;
17124 	case PRAGMA_OMP_CLAUSE_NOGROUP:
17125 	  clauses = c_parser_omp_clause_nogroup (parser, clauses);
17126 	  c_name = "nogroup";
17127 	  break;
17128 	case PRAGMA_OMP_CLAUSE_THREADS:
17129 	  clauses
17130 	    = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_THREADS,
17131 					       clauses);
17132 	  c_name = "threads";
17133 	  break;
17134 	case PRAGMA_OMP_CLAUSE_SIMD:
17135 	  clauses
17136 	    = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_SIMD,
17137 					       clauses);
17138 	  c_name = "simd";
17139 	  break;
17140 	default:
17141 	  c_parser_error (parser, "expected %<#pragma omp%> clause");
17142 	  goto saw_error;
17143 	}
17144 
17145       first = false;
17146 
17147       if (((mask >> c_kind) & 1) == 0)
17148 	{
17149 	  /* Remove the invalid clause(s) from the list to avoid
17150 	     confusing the rest of the compiler.  */
17151 	  clauses = prev;
17152 	  error_at (here, "%qs is not valid for %qs", c_name, where);
17153 	}
17154     }
17155 
17156  saw_error:
17157   if (!nested)
17158     c_parser_skip_to_pragma_eol (parser);
17159 
17160   if (finish_p)
17161     {
17162       if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)) != 0)
17163 	return c_finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD);
17164       return c_finish_omp_clauses (clauses, C_ORT_OMP);
17165     }
17166 
17167   return clauses;
17168 }
17169 
17170 /* OpenACC 2.0, OpenMP 2.5:
17171    structured-block:
17172      statement
17173 
17174    In practice, we're also interested in adding the statement to an
17175    outer node.  So it is convenient if we work around the fact that
17176    c_parser_statement calls add_stmt.  */
17177 
17178 static tree
c_parser_omp_structured_block(c_parser * parser,bool * if_p)17179 c_parser_omp_structured_block (c_parser *parser, bool *if_p)
17180 {
17181   tree stmt = push_stmt_list ();
17182   c_parser_statement (parser, if_p);
17183   return pop_stmt_list (stmt);
17184 }
17185 
17186 /* OpenACC 2.0:
17187    # pragma acc cache (variable-list) new-line
17188 
17189    LOC is the location of the #pragma token.
17190 */
17191 
17192 static tree
c_parser_oacc_cache(location_t loc,c_parser * parser)17193 c_parser_oacc_cache (location_t loc, c_parser *parser)
17194 {
17195   tree stmt, clauses;
17196 
17197   clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE__CACHE_, NULL);
17198   clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
17199 
17200   c_parser_skip_to_pragma_eol (parser);
17201 
17202   stmt = make_node (OACC_CACHE);
17203   TREE_TYPE (stmt) = void_type_node;
17204   OACC_CACHE_CLAUSES (stmt) = clauses;
17205   SET_EXPR_LOCATION (stmt, loc);
17206   add_stmt (stmt);
17207 
17208   return stmt;
17209 }
17210 
17211 /* OpenACC 2.0:
17212    # pragma acc data oacc-data-clause[optseq] new-line
17213      structured-block
17214 
17215    LOC is the location of the #pragma token.
17216 */
17217 
17218 #define OACC_DATA_CLAUSE_MASK						\
17219 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH)		\
17220 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY)		\
17221 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)		\
17222 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)		\
17223 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)		\
17224 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)		\
17225 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)			\
17226 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE)		\
17227 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
17228 
17229 static tree
c_parser_oacc_data(location_t loc,c_parser * parser,bool * if_p)17230 c_parser_oacc_data (location_t loc, c_parser *parser, bool *if_p)
17231 {
17232   tree stmt, clauses, block;
17233 
17234   clauses = c_parser_oacc_all_clauses (parser, OACC_DATA_CLAUSE_MASK,
17235 				       "#pragma acc data");
17236 
17237   block = c_begin_omp_parallel ();
17238   add_stmt (c_parser_omp_structured_block (parser, if_p));
17239 
17240   stmt = c_finish_oacc_data (loc, clauses, block);
17241 
17242   return stmt;
17243 }
17244 
17245 /* OpenACC 2.0:
17246    # pragma acc declare oacc-data-clause[optseq] new-line
17247 */
17248 
17249 #define OACC_DECLARE_CLAUSE_MASK					\
17250 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY)		\
17251 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)		\
17252 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)		\
17253 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)		\
17254 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)		\
17255 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT)	\
17256 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK)		\
17257 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
17258 
17259 static void
c_parser_oacc_declare(c_parser * parser)17260 c_parser_oacc_declare (c_parser *parser)
17261 {
17262   location_t pragma_loc = c_parser_peek_token (parser)->location;
17263   tree clauses, stmt, t, decl;
17264 
17265   bool error = false;
17266 
17267   c_parser_consume_pragma (parser);
17268 
17269   clauses = c_parser_oacc_all_clauses (parser, OACC_DECLARE_CLAUSE_MASK,
17270 				       "#pragma acc declare");
17271   if (!clauses)
17272     {
17273       error_at (pragma_loc,
17274 		"no valid clauses specified in %<#pragma acc declare%>");
17275       return;
17276     }
17277 
17278   for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
17279     {
17280       location_t loc = OMP_CLAUSE_LOCATION (t);
17281       decl = OMP_CLAUSE_DECL (t);
17282       if (!DECL_P (decl))
17283 	{
17284 	  error_at (loc, "array section in %<#pragma acc declare%>");
17285 	  error = true;
17286 	  continue;
17287 	}
17288 
17289       switch (OMP_CLAUSE_MAP_KIND (t))
17290 	{
17291 	case GOMP_MAP_FIRSTPRIVATE_POINTER:
17292 	case GOMP_MAP_ALLOC:
17293 	case GOMP_MAP_TO:
17294 	case GOMP_MAP_FORCE_DEVICEPTR:
17295 	case GOMP_MAP_DEVICE_RESIDENT:
17296 	  break;
17297 
17298 	case GOMP_MAP_LINK:
17299 	  if (!global_bindings_p ()
17300 	      && (TREE_STATIC (decl)
17301 	       || !DECL_EXTERNAL (decl)))
17302 	    {
17303 	      error_at (loc,
17304 			"%qD must be a global variable in "
17305 			"%<#pragma acc declare link%>",
17306 			decl);
17307 	      error = true;
17308 	      continue;
17309 	    }
17310 	  break;
17311 
17312 	default:
17313 	  if (global_bindings_p ())
17314 	    {
17315 	      error_at (loc, "invalid OpenACC clause at file scope");
17316 	      error = true;
17317 	      continue;
17318 	    }
17319 	  if (DECL_EXTERNAL (decl))
17320 	    {
17321 	      error_at (loc,
17322 			"invalid use of %<extern%> variable %qD "
17323 			"in %<#pragma acc declare%>", decl);
17324 	      error = true;
17325 	      continue;
17326 	    }
17327 	  else if (TREE_PUBLIC (decl))
17328 	    {
17329 	      error_at (loc,
17330 			"invalid use of %<global%> variable %qD "
17331 			"in %<#pragma acc declare%>", decl);
17332 	      error = true;
17333 	      continue;
17334 	    }
17335 	  break;
17336 	}
17337 
17338       if (!c_check_in_current_scope (decl))
17339 	{
17340 	  error_at (loc,
17341 		    "%qD must be a variable declared in the same scope as "
17342 		    "%<#pragma acc declare%>", decl);
17343 	  error = true;
17344 	  continue;
17345 	}
17346 
17347       if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl))
17348 	  || lookup_attribute ("omp declare target link",
17349 			       DECL_ATTRIBUTES (decl)))
17350 	{
17351 	  error_at (loc, "variable %qD used more than once with "
17352 		    "%<#pragma acc declare%>", decl);
17353 	  error = true;
17354 	  continue;
17355 	}
17356 
17357       if (!error)
17358 	{
17359 	  tree id;
17360 
17361 	  if (OMP_CLAUSE_MAP_KIND (t) == GOMP_MAP_LINK)
17362 	    id = get_identifier ("omp declare target link");
17363 	  else
17364 	    id = get_identifier ("omp declare target");
17365 
17366 	  DECL_ATTRIBUTES (decl)
17367 			   = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
17368 
17369 	  if (global_bindings_p ())
17370 	    {
17371 	      symtab_node *node = symtab_node::get (decl);
17372 	      if (node != NULL)
17373 		{
17374 		  node->offloadable = 1;
17375 		  if (ENABLE_OFFLOADING)
17376 		    {
17377 		      g->have_offload = true;
17378 		      if (is_a <varpool_node *> (node))
17379 			vec_safe_push (offload_vars, decl);
17380 		    }
17381 		}
17382 	    }
17383 	}
17384     }
17385 
17386   if (error || global_bindings_p ())
17387     return;
17388 
17389   stmt = make_node (OACC_DECLARE);
17390   TREE_TYPE (stmt) = void_type_node;
17391   OACC_DECLARE_CLAUSES (stmt) = clauses;
17392   SET_EXPR_LOCATION (stmt, pragma_loc);
17393 
17394   add_stmt (stmt);
17395 
17396   return;
17397 }
17398 
17399 /* OpenACC 2.0:
17400    # pragma acc enter data oacc-enter-data-clause[optseq] new-line
17401 
17402    or
17403 
17404    # pragma acc exit data oacc-exit-data-clause[optseq] new-line
17405 
17406 
17407    LOC is the location of the #pragma token.
17408 */
17409 
17410 #define OACC_ENTER_DATA_CLAUSE_MASK					\
17411 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)			\
17412 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)		\
17413 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH)		\
17414 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)		\
17415 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)		\
17416 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17417 
17418 #define OACC_EXIT_DATA_CLAUSE_MASK					\
17419 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)			\
17420 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)		\
17421 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)		\
17422 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) 		\
17423 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) 		\
17424 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) 		\
17425 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17426 
17427 static void
c_parser_oacc_enter_exit_data(c_parser * parser,bool enter)17428 c_parser_oacc_enter_exit_data (c_parser *parser, bool enter)
17429 {
17430   location_t loc = c_parser_peek_token (parser)->location;
17431   tree clauses, stmt;
17432   const char *p = "";
17433 
17434   c_parser_consume_pragma (parser);
17435 
17436   if (c_parser_next_token_is (parser, CPP_NAME))
17437     {
17438       p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17439       c_parser_consume_token (parser);
17440     }
17441 
17442   if (strcmp (p, "data") != 0)
17443     {
17444       error_at (loc, "expected %<data%> after %<#pragma acc %s%>",
17445 		enter ? "enter" : "exit");
17446       parser->error = true;
17447       c_parser_skip_to_pragma_eol (parser);
17448       return;
17449     }
17450 
17451   if (enter)
17452     clauses = c_parser_oacc_all_clauses (parser, OACC_ENTER_DATA_CLAUSE_MASK,
17453 					 "#pragma acc enter data");
17454   else
17455     clauses = c_parser_oacc_all_clauses (parser, OACC_EXIT_DATA_CLAUSE_MASK,
17456 					 "#pragma acc exit data");
17457 
17458   if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
17459     {
17460       error_at (loc, "%<#pragma acc %s data%> has no data movement clause",
17461 		enter ? "enter" : "exit");
17462       return;
17463     }
17464 
17465   stmt = enter ? make_node (OACC_ENTER_DATA) : make_node (OACC_EXIT_DATA);
17466   TREE_TYPE (stmt) = void_type_node;
17467   OMP_STANDALONE_CLAUSES (stmt) = clauses;
17468   SET_EXPR_LOCATION (stmt, loc);
17469   add_stmt (stmt);
17470 }
17471 
17472 
17473 /* OpenACC 2.0:
17474    # pragma acc host_data oacc-data-clause[optseq] new-line
17475      structured-block
17476 */
17477 
17478 #define OACC_HOST_DATA_CLAUSE_MASK					\
17479 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE)          \
17480 	 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)                  \
17481 	 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
17482 
17483 static tree
c_parser_oacc_host_data(location_t loc,c_parser * parser,bool * if_p)17484 c_parser_oacc_host_data (location_t loc, c_parser *parser, bool *if_p)
17485 {
17486   tree stmt, clauses, block;
17487 
17488   clauses = c_parser_oacc_all_clauses (parser, OACC_HOST_DATA_CLAUSE_MASK,
17489 				       "#pragma acc host_data");
17490 
17491   block = c_begin_omp_parallel ();
17492   add_stmt (c_parser_omp_structured_block (parser, if_p));
17493   stmt = c_finish_oacc_host_data (loc, clauses, block);
17494   return stmt;
17495 }
17496 
17497 
17498 /* OpenACC 2.0:
17499 
17500    # pragma acc loop oacc-loop-clause[optseq] new-line
17501      structured-block
17502 
17503    LOC is the location of the #pragma token.
17504 */
17505 
17506 #define OACC_LOOP_CLAUSE_MASK						\
17507 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE)		\
17508 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE)		\
17509 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION)		\
17510 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG)		\
17511 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER)		\
17512 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR)		\
17513 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO)		\
17514 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) 	\
17515 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ)			\
17516 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
17517 static tree
c_parser_oacc_loop(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)17518 c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name,
17519 		    omp_clause_mask mask, tree *cclauses, bool *if_p)
17520 {
17521   bool is_parallel = ((mask >> PRAGMA_OACC_CLAUSE_REDUCTION) & 1) == 1;
17522 
17523   strcat (p_name, " loop");
17524   mask |= OACC_LOOP_CLAUSE_MASK;
17525 
17526   tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name,
17527 					    cclauses == NULL);
17528   if (cclauses)
17529     {
17530       clauses = c_oacc_split_loop_clauses (clauses, cclauses, is_parallel);
17531       if (*cclauses)
17532 	*cclauses = c_finish_omp_clauses (*cclauses, C_ORT_ACC);
17533       if (clauses)
17534 	clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
17535     }
17536 
17537   tree block = c_begin_compound_stmt (true);
17538   tree stmt = c_parser_omp_for_loop (loc, parser, OACC_LOOP, clauses, NULL,
17539 				     if_p);
17540   block = c_end_compound_stmt (loc, block, true);
17541   add_stmt (block);
17542 
17543   return stmt;
17544 }
17545 
17546 /* OpenACC 2.0:
17547    # pragma acc kernels oacc-kernels-clause[optseq] new-line
17548      structured-block
17549 
17550    or
17551 
17552    # pragma acc parallel oacc-parallel-clause[optseq] new-line
17553      structured-block
17554 
17555    OpenACC 2.6:
17556 
17557    # pragma acc serial oacc-serial-clause[optseq] new-line
17558      structured-block
17559 
17560    LOC is the location of the #pragma token.
17561 */
17562 
17563 #define OACC_KERNELS_CLAUSE_MASK					\
17564 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)		\
17565 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH)		\
17566 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY)		\
17567 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)		\
17568 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)		\
17569 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)		\
17570 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT)		\
17571 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)		\
17572 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)			\
17573 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE)		\
17574 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS)		\
17575 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS)		\
17576 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT)		\
17577 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH)	\
17578 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17579 
17580 #define OACC_PARALLEL_CLAUSE_MASK					\
17581 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)		\
17582 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH)		\
17583 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY)		\
17584 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)		\
17585 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)		\
17586 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)		\
17587 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT)		\
17588 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)		\
17589 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)			\
17590 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE)		\
17591 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE)		\
17592 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE)	\
17593 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS)		\
17594 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS)		\
17595 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT)		\
17596 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION)		\
17597 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH)	\
17598 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17599 
17600 #define OACC_SERIAL_CLAUSE_MASK					\
17601 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)		\
17602 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH)		\
17603 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY)		\
17604 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)		\
17605 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)		\
17606 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)		\
17607 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT)		\
17608 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)		\
17609 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)			\
17610 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE)		\
17611 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE)		\
17612 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE)	\
17613 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT)		\
17614 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION)		\
17615 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17616 
17617 static tree
c_parser_oacc_compute(location_t loc,c_parser * parser,enum pragma_kind p_kind,char * p_name,bool * if_p)17618 c_parser_oacc_compute (location_t loc, c_parser *parser,
17619 		       enum pragma_kind p_kind, char *p_name, bool *if_p)
17620 {
17621   omp_clause_mask mask;
17622   enum tree_code code;
17623   switch (p_kind)
17624     {
17625     case PRAGMA_OACC_KERNELS:
17626       strcat (p_name, " kernels");
17627       mask = OACC_KERNELS_CLAUSE_MASK;
17628       code = OACC_KERNELS;
17629       break;
17630     case PRAGMA_OACC_PARALLEL:
17631       strcat (p_name, " parallel");
17632       mask = OACC_PARALLEL_CLAUSE_MASK;
17633       code = OACC_PARALLEL;
17634       break;
17635     case PRAGMA_OACC_SERIAL:
17636       strcat (p_name, " serial");
17637       mask = OACC_SERIAL_CLAUSE_MASK;
17638       code = OACC_SERIAL;
17639       break;
17640     default:
17641       gcc_unreachable ();
17642     }
17643 
17644   if (c_parser_next_token_is (parser, CPP_NAME))
17645     {
17646       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17647       if (strcmp (p, "loop") == 0)
17648 	{
17649 	  c_parser_consume_token (parser);
17650 	  tree block = c_begin_omp_parallel ();
17651 	  tree clauses;
17652 	  c_parser_oacc_loop (loc, parser, p_name, mask, &clauses, if_p);
17653 	  return c_finish_omp_construct (loc, code, block, clauses);
17654 	}
17655     }
17656 
17657   tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name);
17658 
17659   tree block = c_begin_omp_parallel ();
17660   add_stmt (c_parser_omp_structured_block (parser, if_p));
17661 
17662   return c_finish_omp_construct (loc, code, block, clauses);
17663 }
17664 
17665 /* OpenACC 2.0:
17666    # pragma acc routine oacc-routine-clause[optseq] new-line
17667      function-definition
17668 
17669    # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
17670 */
17671 
17672 #define OACC_ROUTINE_CLAUSE_MASK					\
17673 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG)		\
17674 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER)		\
17675 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR)		\
17676 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ)			\
17677 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NOHOST) )
17678 
17679 /* Parse an OpenACC routine directive.  For named directives, we apply
17680    immediately to the named function.  For unnamed ones we then parse
17681    a declaration or definition, which must be for a function.  */
17682 
17683 static void
c_parser_oacc_routine(c_parser * parser,enum pragma_context context)17684 c_parser_oacc_routine (c_parser *parser, enum pragma_context context)
17685 {
17686   gcc_checking_assert (context == pragma_external);
17687 
17688   oacc_routine_data data;
17689   data.error_seen = false;
17690   data.fndecl_seen = false;
17691   data.loc = c_parser_peek_token (parser)->location;
17692 
17693   c_parser_consume_pragma (parser);
17694 
17695   /* Look for optional '( name )'.  */
17696   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
17697     {
17698       c_parser_consume_token (parser); /* '(' */
17699 
17700       tree decl = NULL_TREE;
17701       c_token *name_token = c_parser_peek_token (parser);
17702       location_t name_loc = name_token->location;
17703       if (name_token->type == CPP_NAME
17704 	  && (name_token->id_kind == C_ID_ID
17705 	      || name_token->id_kind == C_ID_TYPENAME))
17706 	{
17707 	  decl = lookup_name (name_token->value);
17708 	  if (!decl)
17709 	    error_at (name_loc,
17710 		      "%qE has not been declared", name_token->value);
17711 	  c_parser_consume_token (parser);
17712 	}
17713       else
17714 	c_parser_error (parser, "expected function name");
17715 
17716       if (!decl
17717 	  || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
17718 	{
17719 	  c_parser_skip_to_pragma_eol (parser, false);
17720 	  return;
17721 	}
17722 
17723       data.clauses
17724 	= c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
17725 				     "#pragma acc routine");
17726       /* The clauses are in reverse order; fix that to make later diagnostic
17727 	 emission easier.  */
17728       data.clauses = nreverse (data.clauses);
17729 
17730       if (TREE_CODE (decl) != FUNCTION_DECL)
17731 	{
17732 	  error_at (name_loc, "%qD does not refer to a function", decl);
17733 	  return;
17734 	}
17735 
17736       c_finish_oacc_routine (&data, decl, false);
17737     }
17738   else /* No optional '( name )'.  */
17739     {
17740       data.clauses
17741 	= c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
17742 				     "#pragma acc routine");
17743       /* The clauses are in reverse order; fix that to make later diagnostic
17744 	 emission easier.  */
17745       data.clauses = nreverse (data.clauses);
17746 
17747       /* Emit a helpful diagnostic if there's another pragma following this
17748 	 one.  Also don't allow a static assertion declaration, as in the
17749 	 following we'll just parse a *single* "declaration or function
17750 	 definition", and the static assertion counts an one.  */
17751       if (c_parser_next_token_is (parser, CPP_PRAGMA)
17752 	  || c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
17753 	{
17754 	  error_at (data.loc,
17755 		    "%<#pragma acc routine%> not immediately followed by"
17756 		    " function declaration or definition");
17757 	  /* ..., and then just keep going.  */
17758 	  return;
17759 	}
17760 
17761       /* We only have to consider the pragma_external case here.  */
17762       if (c_parser_next_token_is (parser, CPP_KEYWORD)
17763 	  && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
17764 	{
17765 	  int ext = disable_extension_diagnostics ();
17766 	  do
17767 	    c_parser_consume_token (parser);
17768 	  while (c_parser_next_token_is (parser, CPP_KEYWORD)
17769 		 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
17770 	  c_parser_declaration_or_fndef (parser, true, true, true, false, true,
17771 					 NULL, NULL, false, NULL, &data);
17772 	  restore_extension_diagnostics (ext);
17773 	}
17774       else
17775 	c_parser_declaration_or_fndef (parser, true, true, true, false, true,
17776 				       NULL, NULL, false, NULL, &data);
17777     }
17778 }
17779 
17780 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
17781    IS_DEFN is true if we're applying it to the definition.  */
17782 
17783 static void
c_finish_oacc_routine(struct oacc_routine_data * data,tree fndecl,bool is_defn)17784 c_finish_oacc_routine (struct oacc_routine_data *data, tree fndecl,
17785 		       bool is_defn)
17786 {
17787   /* Keep going if we're in error reporting mode.  */
17788   if (data->error_seen
17789       || fndecl == error_mark_node)
17790     return;
17791 
17792   if (data->fndecl_seen)
17793     {
17794       error_at (data->loc,
17795 		"%<#pragma acc routine%> not immediately followed by"
17796 		" a single function declaration or definition");
17797       data->error_seen = true;
17798       return;
17799     }
17800   if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
17801     {
17802       error_at (data->loc,
17803 		"%<#pragma acc routine%> not immediately followed by"
17804 		" function declaration or definition");
17805       data->error_seen = true;
17806       return;
17807     }
17808 
17809   int compatible
17810     = oacc_verify_routine_clauses (fndecl, &data->clauses, data->loc,
17811 				   "#pragma acc routine");
17812   if (compatible < 0)
17813     {
17814       data->error_seen = true;
17815       return;
17816     }
17817   if (compatible > 0)
17818     {
17819     }
17820   else
17821     {
17822       if (TREE_USED (fndecl) || (!is_defn && DECL_SAVED_TREE (fndecl)))
17823 	{
17824 	  error_at (data->loc,
17825 		    TREE_USED (fndecl)
17826 		    ? G_("%<#pragma acc routine%> must be applied before use")
17827 		    : G_("%<#pragma acc routine%> must be applied before"
17828 			 " definition"));
17829 	  data->error_seen = true;
17830 	  return;
17831 	}
17832 
17833       /* Set the routine's level of parallelism.  */
17834       tree dims = oacc_build_routine_dims (data->clauses);
17835       oacc_replace_fn_attrib (fndecl, dims);
17836 
17837       /* Add an "omp declare target" attribute.  */
17838       DECL_ATTRIBUTES (fndecl)
17839 	= tree_cons (get_identifier ("omp declare target"),
17840 		     data->clauses, DECL_ATTRIBUTES (fndecl));
17841     }
17842 
17843   /* Remember that we've used this "#pragma acc routine".  */
17844   data->fndecl_seen = true;
17845 }
17846 
17847 /* OpenACC 2.0:
17848    # pragma acc update oacc-update-clause[optseq] new-line
17849 */
17850 
17851 #define OACC_UPDATE_CLAUSE_MASK						\
17852 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)		\
17853 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE)		\
17854 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST)		\
17855 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)			\
17856 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT)		\
17857 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17858 
17859 static void
c_parser_oacc_update(c_parser * parser)17860 c_parser_oacc_update (c_parser *parser)
17861 {
17862   location_t loc = c_parser_peek_token (parser)->location;
17863 
17864   c_parser_consume_pragma (parser);
17865 
17866   tree clauses = c_parser_oacc_all_clauses (parser, OACC_UPDATE_CLAUSE_MASK,
17867 					    "#pragma acc update");
17868   if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
17869     {
17870       error_at (loc,
17871 		"%<#pragma acc update%> must contain at least one "
17872 		"%<device%> or %<host%> or %<self%> clause");
17873       return;
17874     }
17875 
17876   if (parser->error)
17877     return;
17878 
17879   tree stmt = make_node (OACC_UPDATE);
17880   TREE_TYPE (stmt) = void_type_node;
17881   OACC_UPDATE_CLAUSES (stmt) = clauses;
17882   SET_EXPR_LOCATION (stmt, loc);
17883   add_stmt (stmt);
17884 }
17885 
17886 /* OpenACC 2.0:
17887    # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
17888 
17889    LOC is the location of the #pragma token.
17890 */
17891 
17892 #define OACC_WAIT_CLAUSE_MASK						\
17893 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
17894 
17895 static tree
c_parser_oacc_wait(location_t loc,c_parser * parser,char * p_name)17896 c_parser_oacc_wait (location_t loc, c_parser *parser, char *p_name)
17897 {
17898   tree clauses, list = NULL_TREE, stmt = NULL_TREE;
17899 
17900   if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
17901     list = c_parser_oacc_wait_list (parser, loc, list);
17902 
17903   strcpy (p_name, " wait");
17904   clauses = c_parser_oacc_all_clauses (parser, OACC_WAIT_CLAUSE_MASK, p_name);
17905   stmt = c_finish_oacc_wait (loc, list, clauses);
17906   add_stmt (stmt);
17907 
17908   return stmt;
17909 }
17910 
17911 /* OpenMP 5.0:
17912    # pragma omp allocate (list)  [allocator(allocator)]  */
17913 
17914 static void
c_parser_omp_allocate(location_t loc,c_parser * parser)17915 c_parser_omp_allocate (location_t loc, c_parser *parser)
17916 {
17917   tree allocator = NULL_TREE;
17918   tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ALLOCATE, NULL_TREE);
17919   if (c_parser_next_token_is (parser, CPP_NAME))
17920     {
17921       matching_parens parens;
17922       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17923       c_parser_consume_token (parser);
17924       if (strcmp ("allocator", p) != 0)
17925 	error_at (c_parser_peek_token (parser)->location,
17926 		  "expected %<allocator%>");
17927       else if (parens.require_open (parser))
17928 	{
17929 	  location_t expr_loc = c_parser_peek_token (parser)->location;
17930 	  c_expr expr = c_parser_expr_no_commas (parser, NULL);
17931 	  expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
17932 	  allocator = expr.value;
17933 	  allocator = c_fully_fold (allocator, false, NULL);
17934 	  tree orig_type
17935 	    = expr.original_type ? expr.original_type : TREE_TYPE (allocator);
17936 	  orig_type = TYPE_MAIN_VARIANT (orig_type);
17937 	  if (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
17938 	      || TREE_CODE (orig_type) != ENUMERAL_TYPE
17939 	      || TYPE_NAME (orig_type)
17940 		 != get_identifier ("omp_allocator_handle_t"))
17941 	    {
17942 	      error_at (expr_loc, "%<allocator%> clause allocator expression "
17943 				"has type %qT rather than "
17944 				"%<omp_allocator_handle_t%>",
17945 				TREE_TYPE (allocator));
17946 	      allocator = NULL_TREE;
17947 	    }
17948 	  parens.skip_until_found_close (parser);
17949 	}
17950     }
17951   c_parser_skip_to_pragma_eol (parser);
17952 
17953   if (allocator)
17954     for (tree c = nl; c != NULL_TREE; c = OMP_CLAUSE_CHAIN (c))
17955       OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
17956 
17957   sorry_at (loc, "%<#pragma omp allocate%> not yet supported");
17958 }
17959 
17960 /* OpenMP 2.5:
17961    # pragma omp atomic new-line
17962      expression-stmt
17963 
17964    expression-stmt:
17965      x binop= expr | x++ | ++x | x-- | --x
17966    binop:
17967      +, *, -, /, &, ^, |, <<, >>
17968 
17969   where x is an lvalue expression with scalar type.
17970 
17971    OpenMP 3.1:
17972    # pragma omp atomic new-line
17973      update-stmt
17974 
17975    # pragma omp atomic read new-line
17976      read-stmt
17977 
17978    # pragma omp atomic write new-line
17979      write-stmt
17980 
17981    # pragma omp atomic update new-line
17982      update-stmt
17983 
17984    # pragma omp atomic capture new-line
17985      capture-stmt
17986 
17987    # pragma omp atomic capture new-line
17988      capture-block
17989 
17990    read-stmt:
17991      v = x
17992    write-stmt:
17993      x = expr
17994    update-stmt:
17995      expression-stmt | x = x binop expr
17996    capture-stmt:
17997      v = expression-stmt
17998    capture-block:
17999      { v = x; update-stmt; } | { update-stmt; v = x; }
18000 
18001    OpenMP 4.0:
18002    update-stmt:
18003      expression-stmt | x = x binop expr | x = expr binop x
18004    capture-stmt:
18005      v = update-stmt
18006    capture-block:
18007      { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
18008 
18009    OpenMP 5.1:
18010    # pragma omp atomic compare new-line
18011      conditional-update-atomic
18012 
18013    # pragma omp atomic compare capture new-line
18014      conditional-update-capture-atomic
18015 
18016    conditional-update-atomic:
18017      cond-expr-stmt | cond-update-stmt
18018    cond-expr-stmt:
18019      x = expr ordop x ? expr : x;
18020      x = x ordop expr ? expr : x;
18021      x = x == e ? d : x;
18022    cond-update-stmt:
18023      if (expr ordop x) { x = expr; }
18024      if (x ordop expr) { x = expr; }
18025      if (x == e) { x = d; }
18026    ordop:
18027      <, >
18028    conditional-update-capture-atomic:
18029      v = cond-expr-stmt
18030      { v = x; cond-expr-stmt }
18031      { cond-expr-stmt v = x; }
18032      { v = x; cond-update-stmt }
18033      { cond-update-stmt v = x; }
18034      if (x == e) { x = d; } else { v = x; }
18035      { r = x == e; if (r) { x = d; } }
18036      { r = x == e; if (r) { x = d; } else { v = x; } }
18037 
18038   where x, r and v are lvalue expressions with scalar type,
18039   expr, e and d are expressions with scalar type and e might be
18040   the same as v.
18041 
18042   LOC is the location of the #pragma token.  */
18043 
18044 static void
c_parser_omp_atomic(location_t loc,c_parser * parser,bool openacc)18045 c_parser_omp_atomic (location_t loc, c_parser *parser, bool openacc)
18046 {
18047   tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE, r = NULL_TREE;
18048   tree lhs1 = NULL_TREE, rhs1 = NULL_TREE;
18049   tree stmt, orig_lhs, unfolded_lhs = NULL_TREE, unfolded_lhs1 = NULL_TREE;
18050   enum tree_code code = ERROR_MARK, opcode = NOP_EXPR;
18051   enum omp_memory_order memory_order = OMP_MEMORY_ORDER_UNSPECIFIED;
18052   struct c_expr expr;
18053   location_t eloc;
18054   bool structured_block = false;
18055   bool swapped = false;
18056   bool non_lvalue_p;
18057   bool first = true;
18058   tree clauses = NULL_TREE;
18059   bool capture = false;
18060   bool compare = false;
18061   bool weak = false;
18062   enum omp_memory_order fail = OMP_MEMORY_ORDER_UNSPECIFIED;
18063   bool no_semicolon = false;
18064   bool extra_scope = false;
18065 
18066   while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
18067     {
18068       if (!first
18069 	  && c_parser_next_token_is (parser, CPP_COMMA)
18070 	  && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
18071 	c_parser_consume_token (parser);
18072 
18073       first = false;
18074 
18075       if (c_parser_next_token_is (parser, CPP_NAME))
18076 	{
18077 	  const char *p
18078 	    = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18079 	  location_t cloc = c_parser_peek_token (parser)->location;
18080 	  enum tree_code new_code = ERROR_MARK;
18081 	  enum omp_memory_order new_memory_order
18082 	    = OMP_MEMORY_ORDER_UNSPECIFIED;
18083 	  bool new_capture = false;
18084 	  bool new_compare = false;
18085 	  bool new_weak = false;
18086 	  enum omp_memory_order new_fail = OMP_MEMORY_ORDER_UNSPECIFIED;
18087 
18088 	  if (!strcmp (p, "read"))
18089 	    new_code = OMP_ATOMIC_READ;
18090 	  else if (!strcmp (p, "write"))
18091 	    new_code = NOP_EXPR;
18092 	  else if (!strcmp (p, "update"))
18093 	    new_code = OMP_ATOMIC;
18094 	  else if (openacc && !strcmp (p, "capture"))
18095 	    new_code = OMP_ATOMIC_CAPTURE_NEW;
18096 	  else if (openacc)
18097 	    {
18098 	      p = NULL;
18099 	      error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
18100 			      "or %<capture%> clause");
18101 	    }
18102 	  else if (!strcmp (p, "capture"))
18103 	    new_capture = true;
18104 	  else if (!strcmp (p, "compare"))
18105 	    new_compare = true;
18106 	  else if (!strcmp (p, "weak"))
18107 	    new_weak = true;
18108 	  else if (!strcmp (p, "fail"))
18109 	    {
18110 	      matching_parens parens;
18111 
18112 	      c_parser_consume_token (parser);
18113 	      if (!parens.require_open (parser))
18114 		continue;
18115 
18116 	      if (c_parser_next_token_is (parser, CPP_NAME))
18117 		{
18118 		  const char *q
18119 		    = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18120 
18121 		  if (!strcmp (q, "seq_cst"))
18122 		    new_fail = OMP_MEMORY_ORDER_SEQ_CST;
18123 		  else if (!strcmp (q, "acquire"))
18124 		    new_fail = OMP_MEMORY_ORDER_ACQUIRE;
18125 		  else if (!strcmp (q, "relaxed"))
18126 		    new_fail = OMP_MEMORY_ORDER_RELAXED;
18127 		}
18128 
18129 	      if (new_fail != OMP_MEMORY_ORDER_UNSPECIFIED)
18130 		{
18131 		  c_parser_consume_token (parser);
18132 		  if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
18133 		    error_at (cloc, "too many %qs clauses", "fail");
18134 		  else
18135 		    fail = new_fail;
18136 		}
18137 	      else
18138 		c_parser_error (parser, "expected %<seq_cst%>, %<acquire%> "
18139 					"or %<relaxed%>");
18140 	      parens.skip_until_found_close (parser);
18141 	      continue;
18142 	    }
18143 	  else if (!strcmp (p, "seq_cst"))
18144 	    new_memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18145 	  else if (!strcmp (p, "acq_rel"))
18146 	    new_memory_order = OMP_MEMORY_ORDER_ACQ_REL;
18147 	  else if (!strcmp (p, "release"))
18148 	    new_memory_order = OMP_MEMORY_ORDER_RELEASE;
18149 	  else if (!strcmp (p, "acquire"))
18150 	    new_memory_order = OMP_MEMORY_ORDER_ACQUIRE;
18151 	  else if (!strcmp (p, "relaxed"))
18152 	    new_memory_order = OMP_MEMORY_ORDER_RELAXED;
18153 	  else if (!strcmp (p, "hint"))
18154 	    {
18155 	      c_parser_consume_token (parser);
18156 	      clauses = c_parser_omp_clause_hint (parser, clauses);
18157 	      continue;
18158 	    }
18159 	  else
18160 	    {
18161 	      p = NULL;
18162 	      error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
18163 			      "%<capture%>, %<compare%>, %<weak%>, %<fail%>, "
18164 			      "%<seq_cst%>, %<acq_rel%>, %<release%>, "
18165 			      "%<relaxed%> or %<hint%> clause");
18166 	    }
18167 	  if (p)
18168 	    {
18169 	      if (new_code != ERROR_MARK)
18170 		{
18171 		  /* OpenACC permits 'update capture'.  */
18172 		  if (openacc
18173 		      && code == OMP_ATOMIC
18174 		      && new_code == OMP_ATOMIC_CAPTURE_NEW)
18175 		    code = new_code;
18176 		  else if (code != ERROR_MARK)
18177 		    error_at (cloc, "too many atomic clauses");
18178 		  else
18179 		    code = new_code;
18180 		}
18181 	      else if (new_memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
18182 		{
18183 		  if (memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
18184 		    error_at (cloc, "too many memory order clauses");
18185 		  else
18186 		    memory_order = new_memory_order;
18187 		}
18188 	      else if (new_capture)
18189 		{
18190 		  if (capture)
18191 		    error_at (cloc, "too many %qs clauses", "capture");
18192 		  else
18193 		    capture = true;
18194 		}
18195 	      else if (new_compare)
18196 		{
18197 		  if (compare)
18198 		    error_at (cloc, "too many %qs clauses", "compare");
18199 		  else
18200 		    compare = true;
18201 		}
18202 	      else if (new_weak)
18203 		{
18204 		  if (weak)
18205 		    error_at (cloc, "too many %qs clauses", "weak");
18206 		  else
18207 		    weak = true;
18208 		}
18209 	      c_parser_consume_token (parser);
18210 	      continue;
18211 	    }
18212 	}
18213       break;
18214     }
18215   c_parser_skip_to_pragma_eol (parser);
18216 
18217   if (code == ERROR_MARK)
18218     code = OMP_ATOMIC;
18219   if (capture)
18220     {
18221       if (code != OMP_ATOMIC)
18222 	error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
18223 		       "clauses", "capture");
18224       else
18225 	code = OMP_ATOMIC_CAPTURE_NEW;
18226     }
18227   if (compare && code != OMP_ATOMIC && code != OMP_ATOMIC_CAPTURE_NEW)
18228     {
18229       error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
18230 		      "clauses", "compare");
18231       compare = false;
18232     }
18233   if (fail != OMP_MEMORY_ORDER_UNSPECIFIED && !compare)
18234     {
18235       error_at (loc, "%qs clause requires %qs clause", "fail", "compare");
18236       fail = OMP_MEMORY_ORDER_UNSPECIFIED;
18237     }
18238   if (weak && !compare)
18239     {
18240       error_at (loc, "%qs clause requires %qs clause", "weak", "compare");
18241       weak = false;
18242     }
18243   if (openacc)
18244     memory_order = OMP_MEMORY_ORDER_RELAXED;
18245   else if (memory_order == OMP_MEMORY_ORDER_UNSPECIFIED)
18246     {
18247       omp_requires_mask
18248 	= (enum omp_requires) (omp_requires_mask
18249 			       | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED);
18250       switch ((enum omp_memory_order)
18251 	      (omp_requires_mask & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER))
18252 	{
18253 	case OMP_MEMORY_ORDER_UNSPECIFIED:
18254 	case OMP_MEMORY_ORDER_RELAXED:
18255 	  memory_order = OMP_MEMORY_ORDER_RELAXED;
18256 	  break;
18257 	case OMP_MEMORY_ORDER_SEQ_CST:
18258 	  memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18259 	  break;
18260 	case OMP_MEMORY_ORDER_ACQ_REL:
18261 	  switch (code)
18262 	    {
18263 	    case OMP_ATOMIC_READ:
18264 	      memory_order = OMP_MEMORY_ORDER_ACQUIRE;
18265 	      break;
18266 	    case NOP_EXPR: /* atomic write */
18267 	      memory_order = OMP_MEMORY_ORDER_RELEASE;
18268 	      break;
18269 	    default:
18270 	      memory_order = OMP_MEMORY_ORDER_ACQ_REL;
18271 	      break;
18272 	    }
18273 	  break;
18274 	default:
18275 	  gcc_unreachable ();
18276 	}
18277     }
18278   else
18279     switch (code)
18280       {
18281       case OMP_ATOMIC_READ:
18282 	if (memory_order == OMP_MEMORY_ORDER_RELEASE)
18283 	  {
18284 	    error_at (loc, "%<#pragma omp atomic read%> incompatible with "
18285 			   "%<release%> clause");
18286 	    memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18287 	  }
18288 	else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
18289 	  memory_order = OMP_MEMORY_ORDER_ACQUIRE;
18290 	break;
18291       case NOP_EXPR: /* atomic write */
18292 	if (memory_order == OMP_MEMORY_ORDER_ACQUIRE)
18293 	  {
18294 	    error_at (loc, "%<#pragma omp atomic write%> incompatible with "
18295 			   "%<acquire%> clause");
18296 	    memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18297 	  }
18298 	else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
18299 	  memory_order = OMP_MEMORY_ORDER_RELEASE;
18300 	break;
18301       default:
18302 	break;
18303       }
18304   if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
18305     memory_order
18306       = (enum omp_memory_order) (memory_order
18307 				 | (fail << OMP_FAIL_MEMORY_ORDER_SHIFT));
18308 
18309   switch (code)
18310     {
18311     case OMP_ATOMIC_READ:
18312     case NOP_EXPR: /* atomic write */
18313       v = c_parser_cast_expression (parser, NULL).value;
18314       non_lvalue_p = !lvalue_p (v);
18315       v = c_fully_fold (v, false, NULL, true);
18316       if (v == error_mark_node)
18317 	goto saw_error;
18318       if (non_lvalue_p)
18319 	v = non_lvalue (v);
18320       loc = c_parser_peek_token (parser)->location;
18321       if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18322 	goto saw_error;
18323       if (code == NOP_EXPR)
18324 	{
18325 	  lhs = c_parser_expression (parser).value;
18326 	  lhs = c_fully_fold (lhs, false, NULL);
18327 	  if (lhs == error_mark_node)
18328 	    goto saw_error;
18329 	}
18330       else
18331 	{
18332 	  lhs = c_parser_cast_expression (parser, NULL).value;
18333 	  non_lvalue_p = !lvalue_p (lhs);
18334 	  lhs = c_fully_fold (lhs, false, NULL, true);
18335 	  if (lhs == error_mark_node)
18336 	    goto saw_error;
18337 	  if (non_lvalue_p)
18338 	    lhs = non_lvalue (lhs);
18339 	}
18340       if (code == NOP_EXPR)
18341 	{
18342 	  /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
18343 	     opcode.  */
18344 	  code = OMP_ATOMIC;
18345 	  rhs = lhs;
18346 	  lhs = v;
18347 	  v = NULL_TREE;
18348 	}
18349       goto done;
18350     case OMP_ATOMIC_CAPTURE_NEW:
18351       if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
18352 	{
18353 	  c_parser_consume_token (parser);
18354 	  structured_block = true;
18355 	}
18356       else if (compare
18357 	       && c_parser_next_token_is_keyword (parser, RID_IF))
18358 	break;
18359       else
18360 	{
18361 	  v = c_parser_cast_expression (parser, NULL).value;
18362 	  non_lvalue_p = !lvalue_p (v);
18363 	  v = c_fully_fold (v, false, NULL, true);
18364 	  if (v == error_mark_node)
18365 	    goto saw_error;
18366 	  if (non_lvalue_p)
18367 	    v = non_lvalue (v);
18368 	  if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18369 	    goto saw_error;
18370 	  if (compare && c_parser_next_token_is_keyword (parser, RID_IF))
18371 	    {
18372 	      eloc = c_parser_peek_token (parser)->location;
18373 	      error_at (eloc, "expected expression");
18374 	      goto saw_error;
18375 	    }
18376 	}
18377       break;
18378     default:
18379       break;
18380     }
18381 
18382   /* For structured_block case we don't know yet whether
18383      old or new x should be captured.  */
18384 restart:
18385   if (compare && c_parser_next_token_is_keyword (parser, RID_IF))
18386     {
18387       c_parser_consume_token (parser);
18388 
18389       matching_parens parens;
18390       if (!parens.require_open (parser))
18391 	goto saw_error;
18392       eloc = c_parser_peek_token (parser)->location;
18393       c_expr cmp_expr;
18394       if (r)
18395 	{
18396 	  cmp_expr = c_parser_cast_expression (parser, NULL);
18397 	  cmp_expr = default_function_array_conversion (eloc, cmp_expr);
18398 	}
18399       else
18400 	cmp_expr = c_parser_binary_expression (parser, NULL, void_list_node);
18401       parens.skip_until_found_close (parser);
18402       if (cmp_expr.value == error_mark_node)
18403 	goto saw_error;
18404       if (r)
18405 	{
18406 	  if (!c_tree_equal (cmp_expr.value, unfolded_lhs))
18407 	    goto bad_if;
18408 	  cmp_expr.value = rhs1;
18409 	  rhs1 = NULL_TREE;
18410 	  gcc_assert (TREE_CODE (cmp_expr.value) == EQ_EXPR);
18411 	}
18412       if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
18413 	;
18414       else if (!structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
18415 	{
18416 	  error_at (EXPR_LOC_OR_LOC (cmp_expr.value, eloc),
18417 		    "expected %<==%> comparison in %<if%> condition");
18418 	  goto saw_error;
18419 	}
18420       else if (TREE_CODE (cmp_expr.value) != GT_EXPR
18421 	       && TREE_CODE (cmp_expr.value) != LT_EXPR)
18422 	{
18423 	  error_at (EXPR_LOC_OR_LOC (cmp_expr.value, eloc),
18424 		    "expected %<==%>, %<<%> or %<>%> comparison in %<if%> "
18425 		    "condition");
18426 	  goto saw_error;
18427 	}
18428       if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
18429 	goto saw_error;
18430 
18431       extra_scope = true;
18432       eloc = c_parser_peek_token (parser)->location;
18433       expr = c_parser_cast_expression (parser, NULL);
18434       lhs = expr.value;
18435       expr = default_function_array_conversion (eloc, expr);
18436       unfolded_lhs = expr.value;
18437       lhs = c_fully_fold (lhs, false, NULL, true);
18438       orig_lhs = lhs;
18439       if (lhs == error_mark_node)
18440 	goto saw_error;
18441       if (!lvalue_p (unfolded_lhs))
18442 	lhs = non_lvalue (lhs);
18443       if (!c_parser_next_token_is (parser, CPP_EQ))
18444 	{
18445 	  c_parser_error (parser, "expected %<=%>");
18446 	  goto saw_error;
18447 	}
18448       c_parser_consume_token (parser);
18449       eloc = c_parser_peek_token (parser)->location;
18450       expr = c_parser_expr_no_commas (parser, NULL);
18451       rhs1 = expr.value;
18452 
18453       if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
18454 	goto saw_error;
18455 
18456       if (!c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
18457 	goto saw_error;
18458 
18459       extra_scope = false;
18460       no_semicolon = true;
18461 
18462       if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 0), unfolded_lhs))
18463 	{
18464 	  if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
18465 	    {
18466 	      opcode = COND_EXPR;
18467 	      rhs = c_fully_fold (TREE_OPERAND (cmp_expr.value, 1),
18468 				  false, NULL, true);
18469 	      rhs1 = c_fully_fold (rhs1, false, NULL, true);
18470 	    }
18471 	  else if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 1), rhs1))
18472 	    {
18473 	      opcode = (TREE_CODE (cmp_expr.value) == GT_EXPR
18474 			? MIN_EXPR : MAX_EXPR);
18475 	      rhs = c_fully_fold (rhs1, false, NULL, true);
18476 	      rhs1 = c_fully_fold (TREE_OPERAND (cmp_expr.value, 0),
18477 				   false, NULL, true);
18478 	    }
18479 	  else
18480 	    goto bad_if;
18481 	}
18482       else if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
18483 	goto bad_if;
18484       else if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 1), unfolded_lhs)
18485 	       && c_tree_equal (TREE_OPERAND (cmp_expr.value, 0), rhs1))
18486 	{
18487 	  opcode = (TREE_CODE (cmp_expr.value) == GT_EXPR
18488 		    ? MAX_EXPR : MIN_EXPR);
18489 	  rhs = c_fully_fold (rhs1, false, NULL, true);
18490 	  rhs1 = c_fully_fold (TREE_OPERAND (cmp_expr.value, 1),
18491 			       false, NULL, true);
18492 	}
18493       else
18494 	{
18495 	bad_if:
18496 	  c_parser_error (parser,
18497 			  "invalid form of %<#pragma omp atomic compare%>");
18498 	  goto saw_error;
18499 	}
18500 
18501       if (c_parser_next_token_is_keyword (parser, RID_ELSE))
18502 	{
18503 	  if (code != OMP_ATOMIC_CAPTURE_NEW
18504 	      || (structured_block && r == NULL_TREE)
18505 	      || TREE_CODE (cmp_expr.value) != EQ_EXPR)
18506 	    {
18507 	      eloc = c_parser_peek_token (parser)->location;
18508 	      error_at (eloc, "unexpected %<else%>");
18509 	      goto saw_error;
18510 	    }
18511 
18512 	  c_parser_consume_token (parser);
18513 
18514 	  if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
18515 	    goto saw_error;
18516 
18517 	  extra_scope = true;
18518 	  v = c_parser_cast_expression (parser, NULL).value;
18519 	  non_lvalue_p = !lvalue_p (v);
18520 	  v = c_fully_fold (v, false, NULL, true);
18521 	  if (v == error_mark_node)
18522 	    goto saw_error;
18523 	  if (non_lvalue_p)
18524 	    v = non_lvalue (v);
18525 	  if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18526 	    goto saw_error;
18527 
18528 	  expr = c_parser_expr_no_commas (parser, NULL);
18529 
18530 	  if (!c_tree_equal (expr.value, unfolded_lhs))
18531 	    goto bad_if;
18532 
18533 	  if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
18534 	    goto saw_error;
18535 
18536 	  if (!c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
18537 	    goto saw_error;
18538 
18539 	  extra_scope = false;
18540 	  code = OMP_ATOMIC_CAPTURE_OLD;
18541 	  if (r == NULL_TREE)
18542 	    /* Signal to c_finish_omp_atomic that in
18543 	       if (x == e) { x = d; } else { v = x; }
18544 	       case the store to v should be conditional.  */
18545 	    r = void_list_node;
18546 	}
18547       else if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
18548 	{
18549 	  c_parser_require_keyword (parser, RID_ELSE, "expected %<else%>");
18550 	  goto saw_error;
18551 	}
18552       else if (code == OMP_ATOMIC_CAPTURE_NEW
18553 	       && r != NULL_TREE
18554 	       && v == NULL_TREE)
18555 	code = OMP_ATOMIC;
18556       goto stmt_done;
18557     }
18558   eloc = c_parser_peek_token (parser)->location;
18559   expr = c_parser_cast_expression (parser, NULL);
18560   lhs = expr.value;
18561   expr = default_function_array_conversion (eloc, expr);
18562   unfolded_lhs = expr.value;
18563   lhs = c_fully_fold (lhs, false, NULL, true);
18564   orig_lhs = lhs;
18565   switch (TREE_CODE (lhs))
18566     {
18567     invalid_compare:
18568       error_at (eloc, "invalid form of %<pragma omp atomic compare%>");
18569       /* FALLTHRU */
18570     case ERROR_MARK:
18571     saw_error:
18572       c_parser_skip_to_end_of_block_or_statement (parser);
18573       if (extra_scope && c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18574 	c_parser_consume_token (parser);
18575       if (structured_block)
18576 	{
18577 	  if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18578 	    c_parser_consume_token (parser);
18579 	  else if (code == OMP_ATOMIC_CAPTURE_NEW)
18580 	    {
18581 	      c_parser_skip_to_end_of_block_or_statement (parser);
18582 	      if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18583 		c_parser_consume_token (parser);
18584 	    }
18585 	}
18586       return;
18587 
18588     case POSTINCREMENT_EXPR:
18589       if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
18590 	code = OMP_ATOMIC_CAPTURE_OLD;
18591       /* FALLTHROUGH */
18592     case PREINCREMENT_EXPR:
18593       lhs = TREE_OPERAND (lhs, 0);
18594       unfolded_lhs = NULL_TREE;
18595       opcode = PLUS_EXPR;
18596       rhs = integer_one_node;
18597       if (compare)
18598 	goto invalid_compare;
18599       break;
18600 
18601     case POSTDECREMENT_EXPR:
18602       if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
18603 	code = OMP_ATOMIC_CAPTURE_OLD;
18604       /* FALLTHROUGH */
18605     case PREDECREMENT_EXPR:
18606       lhs = TREE_OPERAND (lhs, 0);
18607       unfolded_lhs = NULL_TREE;
18608       opcode = MINUS_EXPR;
18609       rhs = integer_one_node;
18610       if (compare)
18611 	goto invalid_compare;
18612       break;
18613 
18614     case COMPOUND_EXPR:
18615       if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR
18616 	  && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR
18617 	  && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR
18618 	  && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0)
18619 	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
18620 					      (TREE_OPERAND (lhs, 1), 0), 0)))
18621 	     == BOOLEAN_TYPE)
18622 	/* Undo effects of boolean_increment for post {in,de}crement.  */
18623 	lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
18624       /* FALLTHRU */
18625     case MODIFY_EXPR:
18626       if (TREE_CODE (lhs) == MODIFY_EXPR
18627 	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) == BOOLEAN_TYPE)
18628 	{
18629 	  /* Undo effects of boolean_increment.  */
18630 	  if (integer_onep (TREE_OPERAND (lhs, 1)))
18631 	    {
18632 	      /* This is pre or post increment.  */
18633 	      rhs = TREE_OPERAND (lhs, 1);
18634 	      lhs = TREE_OPERAND (lhs, 0);
18635 	      unfolded_lhs = NULL_TREE;
18636 	      opcode = NOP_EXPR;
18637 	      if (code == OMP_ATOMIC_CAPTURE_NEW
18638 		  && !structured_block
18639 		  && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
18640 		code = OMP_ATOMIC_CAPTURE_OLD;
18641 	      if (compare)
18642 		goto invalid_compare;
18643 	      break;
18644 	    }
18645 	  if (TREE_CODE (TREE_OPERAND (lhs, 1)) == TRUTH_NOT_EXPR
18646 	      && TREE_OPERAND (lhs, 0)
18647 		 == TREE_OPERAND (TREE_OPERAND (lhs, 1), 0))
18648 	    {
18649 	      /* This is pre or post decrement.  */
18650 	      rhs = TREE_OPERAND (lhs, 1);
18651 	      lhs = TREE_OPERAND (lhs, 0);
18652 	      unfolded_lhs = NULL_TREE;
18653 	      opcode = NOP_EXPR;
18654 	      if (code == OMP_ATOMIC_CAPTURE_NEW
18655 		  && !structured_block
18656 		  && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
18657 		code = OMP_ATOMIC_CAPTURE_OLD;
18658 	      if (compare)
18659 		goto invalid_compare;
18660 	      break;
18661 	    }
18662 	}
18663       /* FALLTHRU */
18664     default:
18665       if (!lvalue_p (unfolded_lhs))
18666 	lhs = non_lvalue (lhs);
18667       if (compare && !c_parser_next_token_is (parser, CPP_EQ))
18668 	{
18669 	  c_parser_error (parser, "expected %<=%>");
18670 	  goto saw_error;
18671 	}
18672       switch (c_parser_peek_token (parser)->type)
18673 	{
18674 	case CPP_MULT_EQ:
18675 	  opcode = MULT_EXPR;
18676 	  break;
18677 	case CPP_DIV_EQ:
18678 	  opcode = TRUNC_DIV_EXPR;
18679 	  break;
18680 	case CPP_PLUS_EQ:
18681 	  opcode = PLUS_EXPR;
18682 	  break;
18683 	case CPP_MINUS_EQ:
18684 	  opcode = MINUS_EXPR;
18685 	  break;
18686 	case CPP_LSHIFT_EQ:
18687 	  opcode = LSHIFT_EXPR;
18688 	  break;
18689 	case CPP_RSHIFT_EQ:
18690 	  opcode = RSHIFT_EXPR;
18691 	  break;
18692 	case CPP_AND_EQ:
18693 	  opcode = BIT_AND_EXPR;
18694 	  break;
18695 	case CPP_OR_EQ:
18696 	  opcode = BIT_IOR_EXPR;
18697 	  break;
18698 	case CPP_XOR_EQ:
18699 	  opcode = BIT_XOR_EXPR;
18700 	  break;
18701 	case CPP_EQ:
18702 	  c_parser_consume_token (parser);
18703 	  eloc = c_parser_peek_token (parser)->location;
18704 	  expr = c_parser_expr_no_commas (parser, NULL, unfolded_lhs);
18705 	  rhs1 = expr.value;
18706 	  switch (TREE_CODE (rhs1))
18707 	    {
18708 	    case MULT_EXPR:
18709 	    case TRUNC_DIV_EXPR:
18710 	    case RDIV_EXPR:
18711 	    case PLUS_EXPR:
18712 	    case MINUS_EXPR:
18713 	    case LSHIFT_EXPR:
18714 	    case RSHIFT_EXPR:
18715 	    case BIT_AND_EXPR:
18716 	    case BIT_IOR_EXPR:
18717 	    case BIT_XOR_EXPR:
18718 	      if (compare)
18719 		break;
18720 	      if (c_tree_equal (TREE_OPERAND (rhs1, 0), unfolded_lhs))
18721 		{
18722 		  opcode = TREE_CODE (rhs1);
18723 		  rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
18724 				      true);
18725 		  rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
18726 				       true);
18727 		  goto stmt_done;
18728 		}
18729 	      if (c_tree_equal (TREE_OPERAND (rhs1, 1), unfolded_lhs))
18730 		{
18731 		  opcode = TREE_CODE (rhs1);
18732 		  rhs = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
18733 				      true);
18734 		  rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
18735 				       true);
18736 		  swapped = !commutative_tree_code (opcode);
18737 		  goto stmt_done;
18738 		}
18739 	      break;
18740 	    case COND_EXPR:
18741 	      if (!compare)
18742 		break;
18743 	      if (TREE_CODE (TREE_OPERAND (rhs1, 0)) != GT_EXPR
18744 		  && TREE_CODE (TREE_OPERAND (rhs1, 0)) != LT_EXPR
18745 		  && TREE_CODE (TREE_OPERAND (rhs1, 0)) != EQ_EXPR)
18746 		break;
18747 	      if (!TREE_OPERAND (rhs1, 1))
18748 		break;
18749 	      if (!c_tree_equal (TREE_OPERAND (rhs1, 2), unfolded_lhs))
18750 		break;
18751 	      if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0),
18752 				unfolded_lhs))
18753 		{
18754 		  if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == EQ_EXPR)
18755 		    {
18756 		      opcode = COND_EXPR;
18757 		      rhs = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
18758 								      0), 1),
18759 					  false, NULL, true);
18760 		      rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false,
18761 					   NULL, true);
18762 		      goto stmt_done;
18763 		    }
18764 		  if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1),
18765 				    TREE_OPERAND (rhs1, 1)))
18766 		    {
18767 		      opcode = (TREE_CODE (TREE_OPERAND (rhs1, 0)) == GT_EXPR
18768 				? MIN_EXPR : MAX_EXPR);
18769 		      rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
18770 					  true);
18771 		      rhs1 = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
18772 								       0), 0),
18773 					   false, NULL, true);
18774 		      goto stmt_done;
18775 		    }
18776 		}
18777 	      else if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == EQ_EXPR)
18778 		break;
18779 	      else if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1),
18780 				     unfolded_lhs))
18781 		{
18782 		  if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0),
18783 				    TREE_OPERAND (rhs1, 1)))
18784 		    {
18785 		      opcode = (TREE_CODE (TREE_OPERAND (rhs1, 0)) == GT_EXPR
18786 				? MAX_EXPR : MIN_EXPR);
18787 		      rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
18788 					  true);
18789 		      rhs1 = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
18790 								       0), 1),
18791 					   false, NULL, true);
18792 		      goto stmt_done;
18793 		    }
18794 		}
18795 	      break;
18796 	    case EQ_EXPR:
18797 	      if (!compare
18798 		  || code != OMP_ATOMIC_CAPTURE_NEW
18799 		  || !structured_block
18800 		  || v
18801 		  || r)
18802 		break;
18803 	      if (c_parser_next_token_is (parser, CPP_SEMICOLON)
18804 		  && c_parser_peek_2nd_token (parser)->keyword == RID_IF)
18805 		{
18806 		  r = lhs;
18807 		  lhs = NULL_TREE;
18808 		  c_parser_consume_token (parser);
18809 		  goto restart;
18810 		}
18811 	      break;
18812 	    case ERROR_MARK:
18813 	      goto saw_error;
18814 	    default:
18815 	      break;
18816 	    }
18817 	  if (c_parser_peek_token (parser)->type == CPP_SEMICOLON)
18818 	    {
18819 	      if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
18820 		{
18821 		  code = OMP_ATOMIC_CAPTURE_OLD;
18822 		  v = lhs;
18823 		  lhs = NULL_TREE;
18824 		  expr = default_function_array_read_conversion (eloc, expr);
18825 		  unfolded_lhs1 = expr.value;
18826 		  lhs1 = c_fully_fold (unfolded_lhs1, false, NULL, true);
18827 		  rhs1 = NULL_TREE;
18828 		  c_parser_consume_token (parser);
18829 		  goto restart;
18830 		}
18831 	      if (structured_block && !compare)
18832 		{
18833 		  opcode = NOP_EXPR;
18834 		  expr = default_function_array_read_conversion (eloc, expr);
18835 		  rhs = c_fully_fold (expr.value, false, NULL, true);
18836 		  rhs1 = NULL_TREE;
18837 		  goto stmt_done;
18838 		}
18839 	    }
18840 	  c_parser_error (parser, "invalid form of %<#pragma omp atomic%>");
18841 	  goto saw_error;
18842 	default:
18843 	  c_parser_error (parser,
18844 			  "invalid operator for %<#pragma omp atomic%>");
18845 	  goto saw_error;
18846 	}
18847 
18848       /* Arrange to pass the location of the assignment operator to
18849 	 c_finish_omp_atomic.  */
18850       loc = c_parser_peek_token (parser)->location;
18851       c_parser_consume_token (parser);
18852       eloc = c_parser_peek_token (parser)->location;
18853       expr = c_parser_expression (parser);
18854       expr = default_function_array_read_conversion (eloc, expr);
18855       rhs = expr.value;
18856       rhs = c_fully_fold (rhs, false, NULL, true);
18857       break;
18858     }
18859 stmt_done:
18860   if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW && r == NULL_TREE)
18861     {
18862       if (!no_semicolon
18863 	  && !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
18864 	goto saw_error;
18865       no_semicolon = false;
18866       v = c_parser_cast_expression (parser, NULL).value;
18867       non_lvalue_p = !lvalue_p (v);
18868       v = c_fully_fold (v, false, NULL, true);
18869       if (v == error_mark_node)
18870 	goto saw_error;
18871       if (non_lvalue_p)
18872 	v = non_lvalue (v);
18873       if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18874 	goto saw_error;
18875       eloc = c_parser_peek_token (parser)->location;
18876       expr = c_parser_cast_expression (parser, NULL);
18877       lhs1 = expr.value;
18878       expr = default_function_array_read_conversion (eloc, expr);
18879       unfolded_lhs1 = expr.value;
18880       lhs1 = c_fully_fold (lhs1, false, NULL, true);
18881       if (lhs1 == error_mark_node)
18882 	goto saw_error;
18883       if (!lvalue_p (unfolded_lhs1))
18884 	lhs1 = non_lvalue (lhs1);
18885     }
18886   if (structured_block)
18887     {
18888       if (!no_semicolon)
18889 	c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
18890       c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>");
18891     }
18892 done:
18893   if (weak && opcode != COND_EXPR)
18894     {
18895       error_at (loc, "%<weak%> clause requires atomic equality comparison");
18896       weak = false;
18897     }
18898   if (unfolded_lhs && unfolded_lhs1
18899       && !c_tree_equal (unfolded_lhs, unfolded_lhs1))
18900     {
18901       error ("%<#pragma omp atomic capture%> uses two different "
18902 	     "expressions for memory");
18903       stmt = error_mark_node;
18904     }
18905   else
18906     stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs, v, lhs1, rhs1, r,
18907 				swapped, memory_order, weak);
18908   if (stmt != error_mark_node)
18909     add_stmt (stmt);
18910 
18911   if (!structured_block && !no_semicolon)
18912     c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
18913 }
18914 
18915 
18916 /* OpenMP 2.5:
18917    # pragma omp barrier new-line
18918 */
18919 
18920 static void
c_parser_omp_barrier(c_parser * parser)18921 c_parser_omp_barrier (c_parser *parser)
18922 {
18923   location_t loc = c_parser_peek_token (parser)->location;
18924   c_parser_consume_pragma (parser);
18925   c_parser_skip_to_pragma_eol (parser);
18926 
18927   c_finish_omp_barrier (loc);
18928 }
18929 
18930 /* OpenMP 2.5:
18931    # pragma omp critical [(name)] new-line
18932      structured-block
18933 
18934    OpenMP 4.5:
18935    # pragma omp critical [(name) [hint(expression)]] new-line
18936 
18937   LOC is the location of the #pragma itself.  */
18938 
18939 #define OMP_CRITICAL_CLAUSE_MASK		\
18940 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
18941 
18942 static tree
c_parser_omp_critical(location_t loc,c_parser * parser,bool * if_p)18943 c_parser_omp_critical (location_t loc, c_parser *parser, bool *if_p)
18944 {
18945   tree stmt, name = NULL_TREE, clauses = NULL_TREE;
18946 
18947   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
18948     {
18949       c_parser_consume_token (parser);
18950       if (c_parser_next_token_is (parser, CPP_NAME))
18951 	{
18952 	  name = c_parser_peek_token (parser)->value;
18953 	  c_parser_consume_token (parser);
18954 	  c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
18955 	}
18956       else
18957 	c_parser_error (parser, "expected identifier");
18958 
18959       if (c_parser_next_token_is (parser, CPP_COMMA)
18960 	  && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
18961 	c_parser_consume_token (parser);
18962     }
18963   clauses = c_parser_omp_all_clauses (parser, OMP_CRITICAL_CLAUSE_MASK,
18964 				      "#pragma omp critical");
18965   stmt = c_parser_omp_structured_block (parser, if_p);
18966   return c_finish_omp_critical (loc, stmt, name, clauses);
18967 }
18968 
18969 /* OpenMP 5.0:
18970    # pragma omp depobj ( depobj ) depobj-clause new-line
18971 
18972    depobj-clause:
18973      depend (dependence-type : locator)
18974      destroy
18975      update (dependence-type)
18976 
18977    dependence-type:
18978      in
18979      out
18980      inout
18981      mutexinout  */
18982 
18983 static void
c_parser_omp_depobj(c_parser * parser)18984 c_parser_omp_depobj (c_parser *parser)
18985 {
18986   location_t loc = c_parser_peek_token (parser)->location;
18987   c_parser_consume_pragma (parser);
18988   matching_parens parens;
18989   if (!parens.require_open (parser))
18990     {
18991       c_parser_skip_to_pragma_eol (parser);
18992       return;
18993     }
18994 
18995   tree depobj = c_parser_expr_no_commas (parser, NULL).value;
18996   if (depobj != error_mark_node)
18997     {
18998       if (!lvalue_p (depobj))
18999 	{
19000 	  error_at (EXPR_LOC_OR_LOC (depobj, loc),
19001 		    "%<depobj%> expression is not lvalue expression");
19002 	  depobj = error_mark_node;
19003 	}
19004       else
19005 	{
19006 	  tree addr = build_unary_op (EXPR_LOC_OR_LOC (depobj, loc), ADDR_EXPR,
19007 				      depobj, false);
19008 	  if (addr == error_mark_node)
19009 	    depobj = error_mark_node;
19010 	  else
19011 	    depobj = build_indirect_ref (EXPR_LOC_OR_LOC (depobj, loc),
19012 					 addr, RO_UNARY_STAR);
19013 	}
19014     }
19015 
19016   parens.skip_until_found_close (parser);
19017   tree clause = NULL_TREE;
19018   enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_SOURCE;
19019   location_t c_loc = c_parser_peek_token (parser)->location;
19020   if (c_parser_next_token_is (parser, CPP_NAME))
19021     {
19022       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19023 
19024       c_parser_consume_token (parser);
19025       if (!strcmp ("depend", p))
19026 	{
19027 	  clause = c_parser_omp_clause_depend (parser, NULL_TREE);
19028 	  clause = c_finish_omp_clauses (clause, C_ORT_OMP);
19029 	  if (!clause)
19030 	    clause = error_mark_node;
19031 	}
19032       else if (!strcmp ("destroy", p))
19033 	kind = OMP_CLAUSE_DEPEND_LAST;
19034       else if (!strcmp ("update", p))
19035 	{
19036 	  matching_parens c_parens;
19037 	  if (c_parens.require_open (parser))
19038 	    {
19039 	      location_t c2_loc = c_parser_peek_token (parser)->location;
19040 	      if (c_parser_next_token_is (parser, CPP_NAME))
19041 		{
19042 		  const char *p2
19043 		    = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19044 
19045 		  c_parser_consume_token (parser);
19046 		  if (!strcmp ("in", p2))
19047 		    kind = OMP_CLAUSE_DEPEND_IN;
19048 		  else if (!strcmp ("out", p2))
19049 		    kind = OMP_CLAUSE_DEPEND_OUT;
19050 		  else if (!strcmp ("inout", p2))
19051 		    kind = OMP_CLAUSE_DEPEND_INOUT;
19052 		  else if (!strcmp ("mutexinoutset", p2))
19053 		    kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
19054 		}
19055 	      if (kind == OMP_CLAUSE_DEPEND_SOURCE)
19056 		{
19057 		  clause = error_mark_node;
19058 		  error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%> or "
19059 				    "%<mutexinoutset%>");
19060 		}
19061 	      c_parens.skip_until_found_close (parser);
19062 	    }
19063 	  else
19064 	    clause = error_mark_node;
19065 	}
19066     }
19067   if (!clause && kind == OMP_CLAUSE_DEPEND_SOURCE)
19068     {
19069       clause = error_mark_node;
19070       error_at (c_loc, "expected %<depend%>, %<destroy%> or %<update%> clause");
19071     }
19072   c_parser_skip_to_pragma_eol (parser);
19073 
19074   c_finish_omp_depobj (loc, depobj, kind, clause);
19075 }
19076 
19077 
19078 /* OpenMP 2.5:
19079    # pragma omp flush flush-vars[opt] new-line
19080 
19081    flush-vars:
19082      ( variable-list )
19083 
19084    OpenMP 5.0:
19085    # pragma omp flush memory-order-clause new-line  */
19086 
19087 static void
c_parser_omp_flush(c_parser * parser)19088 c_parser_omp_flush (c_parser *parser)
19089 {
19090   location_t loc = c_parser_peek_token (parser)->location;
19091   c_parser_consume_pragma (parser);
19092   enum memmodel mo = MEMMODEL_LAST;
19093   if (c_parser_next_token_is (parser, CPP_NAME))
19094     {
19095       const char *p
19096 	= IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19097 
19098       if (!strcmp (p, "seq_cst"))
19099 	mo = MEMMODEL_SEQ_CST;
19100       else if (!strcmp (p, "acq_rel"))
19101 	mo = MEMMODEL_ACQ_REL;
19102       else if (!strcmp (p, "release"))
19103 	mo = MEMMODEL_RELEASE;
19104       else if (!strcmp (p, "acquire"))
19105 	mo = MEMMODEL_ACQUIRE;
19106       else
19107 	error_at (c_parser_peek_token (parser)->location,
19108 		  "expected %<seq_cst%>, %<acq_rel%>, %<release%> or "
19109 		  "%<acquire%>");
19110       c_parser_consume_token (parser);
19111     }
19112   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
19113     {
19114       if (mo != MEMMODEL_LAST)
19115 	error_at (c_parser_peek_token (parser)->location,
19116 		  "%<flush%> list specified together with memory order "
19117 		  "clause");
19118       c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
19119     }
19120   else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
19121     c_parser_error (parser, "expected %<(%> or end of line");
19122   c_parser_skip_to_pragma_eol (parser);
19123 
19124   c_finish_omp_flush (loc, mo);
19125 }
19126 
19127 /* Parse an OpenMP structured block sequence.  KIND is the corresponding
19128    separating directive.  */
19129 
19130 static tree
c_parser_omp_structured_block_sequence(c_parser * parser,enum pragma_kind kind)19131 c_parser_omp_structured_block_sequence (c_parser *parser,
19132 					enum pragma_kind kind)
19133 {
19134   tree stmt = push_stmt_list ();
19135   c_parser_statement (parser, NULL);
19136   do
19137     {
19138       if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
19139 	break;
19140       if (c_parser_next_token_is (parser, CPP_EOF))
19141 	break;
19142 
19143       if (kind != PRAGMA_NONE
19144 	  && c_parser_peek_token (parser)->pragma_kind == kind)
19145 	break;
19146       c_parser_statement (parser, NULL);
19147     }
19148   while (1);
19149   return pop_stmt_list (stmt);
19150 }
19151 
19152 /* OpenMP 5.0:
19153 
19154    scan-loop-body:
19155      { structured-block scan-directive structured-block }  */
19156 
19157 static void
c_parser_omp_scan_loop_body(c_parser * parser,bool open_brace_parsed)19158 c_parser_omp_scan_loop_body (c_parser *parser, bool open_brace_parsed)
19159 {
19160   tree substmt;
19161   location_t loc;
19162   tree clauses = NULL_TREE;
19163 
19164   loc = c_parser_peek_token (parser)->location;
19165   if (!open_brace_parsed
19166       && !c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
19167     {
19168       /* Avoid skipping until the end of the block.  */
19169       parser->error = false;
19170       return;
19171     }
19172 
19173   substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_OMP_SCAN);
19174   substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE);
19175   SET_EXPR_LOCATION (substmt, loc);
19176   add_stmt (substmt);
19177 
19178   loc = c_parser_peek_token (parser)->location;
19179   if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SCAN)
19180     {
19181       enum omp_clause_code clause = OMP_CLAUSE_ERROR;
19182 
19183       c_parser_consume_pragma (parser);
19184 
19185       if (c_parser_next_token_is (parser, CPP_NAME))
19186 	{
19187 	  const char *p
19188 	    = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19189 	  if (strcmp (p, "inclusive") == 0)
19190 	    clause = OMP_CLAUSE_INCLUSIVE;
19191 	  else if (strcmp (p, "exclusive") == 0)
19192 	    clause = OMP_CLAUSE_EXCLUSIVE;
19193 	}
19194       if (clause != OMP_CLAUSE_ERROR)
19195 	{
19196 	  c_parser_consume_token (parser);
19197 	  clauses = c_parser_omp_var_list_parens (parser, clause, NULL_TREE);
19198 	}
19199       else
19200 	c_parser_error (parser, "expected %<inclusive%> or "
19201 				"%<exclusive%> clause");
19202       c_parser_skip_to_pragma_eol (parser);
19203     }
19204   else
19205     error ("expected %<#pragma omp scan%>");
19206 
19207   clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
19208   substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_NONE);
19209   substmt = build2 (OMP_SCAN, void_type_node, substmt, clauses);
19210   SET_EXPR_LOCATION (substmt, loc);
19211   add_stmt (substmt);
19212 
19213   c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
19214 			     "expected %<}%>");
19215 }
19216 
19217 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
19218    The real trick here is to determine the loop control variable early
19219    so that we can push a new decl if necessary to make it private.
19220    LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
19221    respectively.  */
19222 
19223 static tree
c_parser_omp_for_loop(location_t loc,c_parser * parser,enum tree_code code,tree clauses,tree * cclauses,bool * if_p)19224 c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
19225 		       tree clauses, tree *cclauses, bool *if_p)
19226 {
19227   tree decl, cond, incr, body, init, stmt, cl;
19228   unsigned char save_in_statement;
19229   tree declv, condv, incrv, initv, ret = NULL_TREE;
19230   tree pre_body = NULL_TREE, this_pre_body;
19231   tree ordered_cl = NULL_TREE;
19232   bool fail = false, open_brace_parsed = false;
19233   int i, collapse = 1, ordered = 0, count, nbraces = 0;
19234   location_t for_loc;
19235   bool tiling = false;
19236   bool inscan = false;
19237   vec<tree, va_gc> *for_block = make_tree_vector ();
19238 
19239   for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
19240     if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
19241       collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl));
19242     else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_TILE)
19243       {
19244 	tiling = true;
19245 	collapse = list_length (OMP_CLAUSE_TILE_LIST (cl));
19246       }
19247     else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED
19248 	     && OMP_CLAUSE_ORDERED_EXPR (cl))
19249       {
19250 	ordered_cl = cl;
19251 	ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
19252       }
19253     else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_REDUCTION
19254 	     && OMP_CLAUSE_REDUCTION_INSCAN (cl)
19255 	     && (code == OMP_SIMD || code == OMP_FOR))
19256       inscan = true;
19257 
19258   if (ordered && ordered < collapse)
19259     {
19260       error_at (OMP_CLAUSE_LOCATION (ordered_cl),
19261 		"%<ordered%> clause parameter is less than %<collapse%>");
19262       OMP_CLAUSE_ORDERED_EXPR (ordered_cl)
19263 	= build_int_cst (NULL_TREE, collapse);
19264       ordered = collapse;
19265     }
19266   if (ordered)
19267     {
19268       for (tree *pc = &clauses; *pc; )
19269 	if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LINEAR)
19270 	  {
19271 	    error_at (OMP_CLAUSE_LOCATION (*pc),
19272 		      "%<linear%> clause may not be specified together "
19273 		      "with %<ordered%> clause with a parameter");
19274 	    *pc = OMP_CLAUSE_CHAIN (*pc);
19275 	  }
19276 	else
19277 	  pc = &OMP_CLAUSE_CHAIN (*pc);
19278     }
19279 
19280   gcc_assert (tiling || (collapse >= 1 && ordered >= 0));
19281   count = ordered ? ordered : collapse;
19282 
19283   declv = make_tree_vec (count);
19284   initv = make_tree_vec (count);
19285   condv = make_tree_vec (count);
19286   incrv = make_tree_vec (count);
19287 
19288   if (!c_parser_next_token_is_keyword (parser, RID_FOR))
19289     {
19290       c_parser_error (parser, "for statement expected");
19291       return NULL;
19292     }
19293   for_loc = c_parser_peek_token (parser)->location;
19294   c_parser_consume_token (parser);
19295 
19296   /* Forbid break/continue in the loop initializer, condition, and
19297      increment expressions.  */
19298   save_in_statement = in_statement;
19299   in_statement = IN_OMP_BLOCK;
19300 
19301   for (i = 0; i < count; i++)
19302     {
19303       int bracecount = 0;
19304 
19305       matching_parens parens;
19306       if (!parens.require_open (parser))
19307 	goto pop_scopes;
19308 
19309       /* Parse the initialization declaration or expression.  */
19310       if (c_parser_next_tokens_start_declaration (parser))
19311 	{
19312 	  if (i > 0)
19313 	    vec_safe_push (for_block, c_begin_compound_stmt (true));
19314 	  this_pre_body = push_stmt_list ();
19315 	  c_in_omp_for = true;
19316 	  c_parser_declaration_or_fndef (parser, true, true, true, true, true);
19317 	  c_in_omp_for = false;
19318 	  if (this_pre_body)
19319 	    {
19320 	      this_pre_body = pop_stmt_list (this_pre_body);
19321 	      if (pre_body)
19322 		{
19323 		  tree t = pre_body;
19324 		  pre_body = push_stmt_list ();
19325 		  add_stmt (t);
19326 		  add_stmt (this_pre_body);
19327 		  pre_body = pop_stmt_list (pre_body);
19328 		}
19329 	      else
19330 		pre_body = this_pre_body;
19331 	    }
19332 	  decl = check_for_loop_decls (for_loc, flag_isoc99);
19333 	  if (decl == NULL)
19334 	    goto error_init;
19335 	  if (DECL_INITIAL (decl) == error_mark_node)
19336 	    decl = error_mark_node;
19337 	  init = decl;
19338 	}
19339       else if (c_parser_next_token_is (parser, CPP_NAME)
19340 	       && c_parser_peek_2nd_token (parser)->type == CPP_EQ)
19341 	{
19342 	  struct c_expr decl_exp;
19343 	  struct c_expr init_exp;
19344 	  location_t init_loc;
19345 
19346 	  decl_exp = c_parser_postfix_expression (parser);
19347 	  decl = decl_exp.value;
19348 
19349 	  c_parser_require (parser, CPP_EQ, "expected %<=%>");
19350 
19351 	  init_loc = c_parser_peek_token (parser)->location;
19352 	  init_exp = c_parser_expr_no_commas (parser, NULL);
19353 	  init_exp = default_function_array_read_conversion (init_loc,
19354 							     init_exp);
19355 	  c_in_omp_for = true;
19356 	  init = build_modify_expr (init_loc, decl, decl_exp.original_type,
19357 				    NOP_EXPR, init_loc, init_exp.value,
19358 				    init_exp.original_type);
19359 	  c_in_omp_for = false;
19360 	  init = c_process_expr_stmt (init_loc, init);
19361 
19362 	  c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
19363 	}
19364       else
19365 	{
19366 	error_init:
19367 	  c_parser_error (parser,
19368 			  "expected iteration declaration or initialization");
19369 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
19370 				     "expected %<)%>");
19371 	  fail = true;
19372 	  goto parse_next;
19373 	}
19374 
19375       /* Parse the loop condition.  */
19376       cond = NULL_TREE;
19377       if (c_parser_next_token_is_not (parser, CPP_SEMICOLON))
19378 	{
19379 	  location_t cond_loc = c_parser_peek_token (parser)->location;
19380 	  c_in_omp_for = true;
19381 	  struct c_expr cond_expr
19382 	    = c_parser_binary_expression (parser, NULL, NULL_TREE);
19383           c_in_omp_for = false;
19384 
19385 	  cond = cond_expr.value;
19386 	  cond = c_objc_common_truthvalue_conversion (cond_loc, cond);
19387 	  switch (cond_expr.original_code)
19388 	    {
19389 	    case GT_EXPR:
19390 	    case GE_EXPR:
19391 	    case LT_EXPR:
19392 	    case LE_EXPR:
19393 	      break;
19394 	    case NE_EXPR:
19395 	      if (code != OACC_LOOP)
19396 		break;
19397 	      /* FALLTHRU.  */
19398 	    default:
19399 	      /* Can't be cond = error_mark_node, because we want to preserve
19400 		 the location until c_finish_omp_for.  */
19401 	      cond = build1 (NOP_EXPR, boolean_type_node, error_mark_node);
19402 	      break;
19403 	    }
19404 	  protected_set_expr_location (cond, cond_loc);
19405 	}
19406       c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
19407 
19408       /* Parse the increment expression.  */
19409       incr = NULL_TREE;
19410       if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
19411 	{
19412 	  location_t incr_loc = c_parser_peek_token (parser)->location;
19413 
19414 	  incr = c_process_expr_stmt (incr_loc,
19415 				      c_parser_expression (parser).value);
19416 	}
19417       parens.skip_until_found_close (parser);
19418 
19419       if (decl == NULL || decl == error_mark_node || init == error_mark_node)
19420 	fail = true;
19421       else
19422 	{
19423 	  TREE_VEC_ELT (declv, i) = decl;
19424 	  TREE_VEC_ELT (initv, i) = init;
19425 	  TREE_VEC_ELT (condv, i) = cond;
19426 	  TREE_VEC_ELT (incrv, i) = incr;
19427 	}
19428 
19429     parse_next:
19430       if (i == count - 1)
19431 	break;
19432 
19433       /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
19434 	 in between the collapsed for loops to be still considered perfectly
19435 	 nested.  Hopefully the final version clarifies this.
19436 	 For now handle (multiple) {'s and empty statements.  */
19437       do
19438 	{
19439 	  if (c_parser_next_token_is_keyword (parser, RID_FOR))
19440 	    {
19441 	      c_parser_consume_token (parser);
19442 	      break;
19443 	    }
19444 	  else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
19445 	    {
19446 	      c_parser_consume_token (parser);
19447 	      bracecount++;
19448 	    }
19449 	  else if (bracecount
19450 		   && c_parser_next_token_is (parser, CPP_SEMICOLON))
19451 	    c_parser_consume_token (parser);
19452 	  else
19453 	    {
19454 	      c_parser_error (parser, "not enough perfectly nested loops");
19455 	      if (bracecount)
19456 		{
19457 		  open_brace_parsed = true;
19458 		  bracecount--;
19459 		}
19460 	      fail = true;
19461 	      count = 0;
19462 	      break;
19463 	    }
19464 	}
19465       while (1);
19466 
19467       nbraces += bracecount;
19468     }
19469 
19470   if (nbraces)
19471     if_p = NULL;
19472 
19473   in_statement = IN_OMP_FOR;
19474   body = push_stmt_list ();
19475 
19476   if (inscan)
19477     c_parser_omp_scan_loop_body (parser, open_brace_parsed);
19478   else if (open_brace_parsed)
19479     {
19480       location_t here = c_parser_peek_token (parser)->location;
19481       stmt = c_begin_compound_stmt (true);
19482       c_parser_compound_statement_nostart (parser);
19483       add_stmt (c_end_compound_stmt (here, stmt, true));
19484     }
19485   else
19486     add_stmt (c_parser_c99_block_statement (parser, if_p));
19487 
19488   body = pop_stmt_list (body);
19489   in_statement = save_in_statement;
19490 
19491   while (nbraces)
19492     {
19493       if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
19494 	{
19495 	  c_parser_consume_token (parser);
19496 	  nbraces--;
19497 	}
19498       else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
19499 	c_parser_consume_token (parser);
19500       else
19501 	{
19502 	  c_parser_error (parser, "collapsed loops not perfectly nested");
19503 	  while (nbraces)
19504 	    {
19505 	      location_t here = c_parser_peek_token (parser)->location;
19506 	      stmt = c_begin_compound_stmt (true);
19507 	      add_stmt (body);
19508 	      c_parser_compound_statement_nostart (parser);
19509 	      body = c_end_compound_stmt (here, stmt, true);
19510 	      nbraces--;
19511 	    }
19512 	  goto pop_scopes;
19513 	}
19514     }
19515 
19516   /* Only bother calling c_finish_omp_for if we haven't already generated
19517      an error from the initialization parsing.  */
19518   if (!fail)
19519     {
19520       c_in_omp_for = true;
19521       stmt = c_finish_omp_for (loc, code, declv, NULL, initv, condv,
19522 			       incrv, body, pre_body, true);
19523       c_in_omp_for = false;
19524 
19525       /* Check for iterators appearing in lb, b or incr expressions.  */
19526       if (stmt && !c_omp_check_loop_iv (stmt, declv, NULL))
19527 	stmt = NULL_TREE;
19528 
19529       if (stmt)
19530 	{
19531 	  add_stmt (stmt);
19532 
19533 	  for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (stmt)); i++)
19534 	    {
19535 	      tree init = TREE_VEC_ELT (OMP_FOR_INIT (stmt), i);
19536 	      gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
19537 	      tree decl = TREE_OPERAND (init, 0);
19538 	      tree cond = TREE_VEC_ELT (OMP_FOR_COND (stmt), i);
19539 	      gcc_assert (COMPARISON_CLASS_P (cond));
19540 	      gcc_assert (TREE_OPERAND (cond, 0) == decl);
19541 
19542 	      tree op0 = TREE_OPERAND (init, 1);
19543 	      if (!OMP_FOR_NON_RECTANGULAR (stmt)
19544 		  || TREE_CODE (op0) != TREE_VEC)
19545 		TREE_OPERAND (init, 1) = c_fully_fold (op0, false, NULL);
19546 	      else
19547 		{
19548 		  TREE_VEC_ELT (op0, 1)
19549 		    = c_fully_fold (TREE_VEC_ELT (op0, 1), false, NULL);
19550 		  TREE_VEC_ELT (op0, 2)
19551 		    = c_fully_fold (TREE_VEC_ELT (op0, 2), false, NULL);
19552 		}
19553 
19554 	      tree op1 = TREE_OPERAND (cond, 1);
19555 	      if (!OMP_FOR_NON_RECTANGULAR (stmt)
19556 		  || TREE_CODE (op1) != TREE_VEC)
19557 		TREE_OPERAND (cond, 1) = c_fully_fold (op1, false, NULL);
19558 	      else
19559 		{
19560 		  TREE_VEC_ELT (op1, 1)
19561 		    = c_fully_fold (TREE_VEC_ELT (op1, 1), false, NULL);
19562 		  TREE_VEC_ELT (op1, 2)
19563 		    = c_fully_fold (TREE_VEC_ELT (op1, 2), false, NULL);
19564 		}
19565 	    }
19566 
19567 	  if (cclauses != NULL
19568 	      && cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL)
19569 	    {
19570 	      tree *c;
19571 	      for (c = &cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; *c ; )
19572 		if (OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_FIRSTPRIVATE
19573 		    && OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_LASTPRIVATE)
19574 		  c = &OMP_CLAUSE_CHAIN (*c);
19575 		else
19576 		  {
19577 		    for (i = 0; i < count; i++)
19578 		      if (TREE_VEC_ELT (declv, i) == OMP_CLAUSE_DECL (*c))
19579 			break;
19580 		    if (i == count)
19581 		      c = &OMP_CLAUSE_CHAIN (*c);
19582 		    else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE)
19583 		      {
19584 			error_at (loc,
19585 				  "iteration variable %qD should not be firstprivate",
19586 				  OMP_CLAUSE_DECL (*c));
19587 			*c = OMP_CLAUSE_CHAIN (*c);
19588 		      }
19589 		    else
19590 		      {
19591 			/* Move lastprivate (decl) clause to OMP_FOR_CLAUSES.  */
19592 			tree l = *c;
19593 			*c = OMP_CLAUSE_CHAIN (*c);
19594 			if (code == OMP_SIMD)
19595 			  {
19596 			    OMP_CLAUSE_CHAIN (l)
19597 			      = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
19598 			    cclauses[C_OMP_CLAUSE_SPLIT_FOR] = l;
19599 			  }
19600 			else
19601 			  {
19602 			    OMP_CLAUSE_CHAIN (l) = clauses;
19603 			    clauses = l;
19604 			  }
19605 		      }
19606 		  }
19607 	    }
19608 	  OMP_FOR_CLAUSES (stmt) = clauses;
19609 	}
19610       ret = stmt;
19611     }
19612 pop_scopes:
19613   while (!for_block->is_empty ())
19614     {
19615       /* FIXME diagnostics: LOC below should be the actual location of
19616 	 this particular for block.  We need to build a list of
19617 	 locations to go along with FOR_BLOCK.  */
19618       stmt = c_end_compound_stmt (loc, for_block->pop (), true);
19619       add_stmt (stmt);
19620     }
19621   release_tree_vector (for_block);
19622   return ret;
19623 }
19624 
19625 /* Helper function for OpenMP parsing, split clauses and call
19626    finish_omp_clauses on each of the set of clauses afterwards.  */
19627 
19628 static void
omp_split_clauses(location_t loc,enum tree_code code,omp_clause_mask mask,tree clauses,tree * cclauses)19629 omp_split_clauses (location_t loc, enum tree_code code,
19630 		   omp_clause_mask mask, tree clauses, tree *cclauses)
19631 {
19632   int i;
19633   c_omp_split_clauses (loc, code, mask, clauses, cclauses);
19634   for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
19635     if (cclauses[i])
19636       cclauses[i] = c_finish_omp_clauses (cclauses[i],
19637 					  i == C_OMP_CLAUSE_SPLIT_TARGET
19638 					  ? C_ORT_OMP_TARGET : C_ORT_OMP);
19639 }
19640 
19641 /* OpenMP 5.0:
19642    #pragma omp loop loop-clause[optseq] new-line
19643      for-loop
19644 
19645    LOC is the location of the #pragma token.
19646 */
19647 
19648 #define OMP_LOOP_CLAUSE_MASK					\
19649 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
19650 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)	\
19651 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)	\
19652 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)	\
19653 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND)		\
19654 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
19655 
19656 static tree
c_parser_omp_loop(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)19657 c_parser_omp_loop (location_t loc, c_parser *parser,
19658 		   char *p_name, omp_clause_mask mask, tree *cclauses,
19659 		   bool *if_p)
19660 {
19661   tree block, clauses, ret;
19662 
19663   strcat (p_name, " loop");
19664   mask |= OMP_LOOP_CLAUSE_MASK;
19665 
19666   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19667   if (cclauses)
19668     {
19669       omp_split_clauses (loc, OMP_LOOP, mask, clauses, cclauses);
19670       clauses = cclauses[C_OMP_CLAUSE_SPLIT_LOOP];
19671     }
19672 
19673   block = c_begin_compound_stmt (true);
19674   ret = c_parser_omp_for_loop (loc, parser, OMP_LOOP, clauses, cclauses, if_p);
19675   block = c_end_compound_stmt (loc, block, true);
19676   add_stmt (block);
19677 
19678   return ret;
19679 }
19680 
19681 /* OpenMP 4.0:
19682    #pragma omp simd simd-clause[optseq] new-line
19683      for-loop
19684 
19685    LOC is the location of the #pragma token.
19686 */
19687 
19688 #define OMP_SIMD_CLAUSE_MASK					\
19689 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN)	\
19690 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN)	\
19691 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR)	\
19692 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED)	\
19693 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
19694 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)	\
19695 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)	\
19696 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)	\
19697 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
19698 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL)	\
19699 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
19700 
19701 static tree
c_parser_omp_simd(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)19702 c_parser_omp_simd (location_t loc, c_parser *parser,
19703 		   char *p_name, omp_clause_mask mask, tree *cclauses,
19704 		   bool *if_p)
19705 {
19706   tree block, clauses, ret;
19707 
19708   strcat (p_name, " simd");
19709   mask |= OMP_SIMD_CLAUSE_MASK;
19710 
19711   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19712   if (cclauses)
19713     {
19714       omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses);
19715       clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
19716       tree c = omp_find_clause (cclauses[C_OMP_CLAUSE_SPLIT_FOR],
19717 				OMP_CLAUSE_ORDERED);
19718       if (c && OMP_CLAUSE_ORDERED_EXPR (c))
19719 	{
19720 	  error_at (OMP_CLAUSE_LOCATION (c),
19721 		    "%<ordered%> clause with parameter may not be specified "
19722 		    "on %qs construct", p_name);
19723 	  OMP_CLAUSE_ORDERED_EXPR (c) = NULL_TREE;
19724 	}
19725     }
19726 
19727   block = c_begin_compound_stmt (true);
19728   ret = c_parser_omp_for_loop (loc, parser, OMP_SIMD, clauses, cclauses, if_p);
19729   block = c_end_compound_stmt (loc, block, true);
19730   add_stmt (block);
19731 
19732   return ret;
19733 }
19734 
19735 /* OpenMP 2.5:
19736    #pragma omp for for-clause[optseq] new-line
19737      for-loop
19738 
19739    OpenMP 4.0:
19740    #pragma omp for simd for-simd-clause[optseq] new-line
19741      for-loop
19742 
19743    LOC is the location of the #pragma token.
19744 */
19745 
19746 #define OMP_FOR_CLAUSE_MASK					\
19747 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
19748 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
19749 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)	\
19750 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR)	\
19751 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)	\
19752 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED)	\
19753 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)	\
19754 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)	\
19755 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT)	\
19756 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)	\
19757 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
19758 
19759 static tree
c_parser_omp_for(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)19760 c_parser_omp_for (location_t loc, c_parser *parser,
19761 		  char *p_name, omp_clause_mask mask, tree *cclauses,
19762 		  bool *if_p)
19763 {
19764   tree block, clauses, ret;
19765 
19766   strcat (p_name, " for");
19767   mask |= OMP_FOR_CLAUSE_MASK;
19768   /* parallel for{, simd} disallows nowait clause, but for
19769      target {teams distribute ,}parallel for{, simd} it should be accepted.  */
19770   if (cclauses && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0)
19771     mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
19772   /* Composite distribute parallel for{, simd} disallows ordered clause.  */
19773   if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
19774     mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED);
19775 
19776   if (c_parser_next_token_is (parser, CPP_NAME))
19777     {
19778       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19779 
19780       if (strcmp (p, "simd") == 0)
19781 	{
19782 	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19783 	  if (cclauses == NULL)
19784 	    cclauses = cclauses_buf;
19785 
19786 	  c_parser_consume_token (parser);
19787 	  if (!flag_openmp)  /* flag_openmp_simd  */
19788 	    return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
19789 				      if_p);
19790 	  block = c_begin_compound_stmt (true);
19791 	  ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
19792 	  block = c_end_compound_stmt (loc, block, true);
19793 	  if (ret == NULL_TREE)
19794 	    return ret;
19795 	  ret = make_node (OMP_FOR);
19796 	  TREE_TYPE (ret) = void_type_node;
19797 	  OMP_FOR_BODY (ret) = block;
19798 	  OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
19799 	  SET_EXPR_LOCATION (ret, loc);
19800 	  add_stmt (ret);
19801 	  return ret;
19802 	}
19803     }
19804   if (!flag_openmp)  /* flag_openmp_simd  */
19805     {
19806       c_parser_skip_to_pragma_eol (parser, false);
19807       return NULL_TREE;
19808     }
19809 
19810   /* Composite distribute parallel for disallows linear clause.  */
19811   if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
19812     mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR);
19813 
19814   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19815   if (cclauses)
19816     {
19817       omp_split_clauses (loc, OMP_FOR, mask, clauses, cclauses);
19818       clauses = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
19819     }
19820 
19821   block = c_begin_compound_stmt (true);
19822   ret = c_parser_omp_for_loop (loc, parser, OMP_FOR, clauses, cclauses, if_p);
19823   block = c_end_compound_stmt (loc, block, true);
19824   add_stmt (block);
19825 
19826   return ret;
19827 }
19828 
19829 static tree c_parser_omp_taskloop (location_t, c_parser *, char *,
19830 				   omp_clause_mask, tree *, bool *);
19831 
19832 /* OpenMP 2.5:
19833    # pragma omp master new-line
19834      structured-block
19835 
19836    LOC is the location of the #pragma token.
19837 */
19838 
19839 static tree
c_parser_omp_master(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)19840 c_parser_omp_master (location_t loc, c_parser *parser,
19841 		     char *p_name, omp_clause_mask mask, tree *cclauses,
19842 		     bool *if_p)
19843 {
19844   tree block, clauses, ret;
19845 
19846   strcat (p_name, " master");
19847 
19848   if (c_parser_next_token_is (parser, CPP_NAME))
19849     {
19850       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19851 
19852       if (strcmp (p, "taskloop") == 0)
19853 	{
19854 	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19855 	  if (cclauses == NULL)
19856 	    cclauses = cclauses_buf;
19857 
19858 	  c_parser_consume_token (parser);
19859 	  if (!flag_openmp)  /* flag_openmp_simd  */
19860 	    return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
19861 					  if_p);
19862 	  block = c_begin_compound_stmt (true);
19863 	  ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
19864 				       if_p);
19865 	  block = c_end_compound_stmt (loc, block, true);
19866 	  if (ret == NULL_TREE)
19867 	    return ret;
19868 	  ret = c_finish_omp_master (loc, block);
19869 	  OMP_MASTER_COMBINED (ret) = 1;
19870 	  return ret;
19871 	}
19872     }
19873   if (!flag_openmp)  /* flag_openmp_simd  */
19874     {
19875       c_parser_skip_to_pragma_eol (parser, false);
19876       return NULL_TREE;
19877     }
19878 
19879   if (cclauses)
19880     {
19881       clauses = c_parser_omp_all_clauses (parser, mask, p_name, false);
19882       omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses);
19883     }
19884   else
19885     c_parser_skip_to_pragma_eol (parser);
19886 
19887   return c_finish_omp_master (loc, c_parser_omp_structured_block (parser,
19888 								  if_p));
19889 }
19890 
19891 /* OpenMP 5.1:
19892    # pragma omp masked masked-clauses new-line
19893      structured-block
19894 
19895    LOC is the location of the #pragma token.
19896 */
19897 
19898 #define OMP_MASKED_CLAUSE_MASK					\
19899 	(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER)
19900 
19901 static tree
c_parser_omp_masked(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)19902 c_parser_omp_masked (location_t loc, c_parser *parser,
19903 		     char *p_name, omp_clause_mask mask, tree *cclauses,
19904 		     bool *if_p)
19905 {
19906   tree block, clauses, ret;
19907 
19908   strcat (p_name, " masked");
19909   mask |= OMP_MASKED_CLAUSE_MASK;
19910 
19911   if (c_parser_next_token_is (parser, CPP_NAME))
19912     {
19913       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19914 
19915       if (strcmp (p, "taskloop") == 0)
19916 	{
19917 	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19918 	  if (cclauses == NULL)
19919 	    cclauses = cclauses_buf;
19920 
19921 	  c_parser_consume_token (parser);
19922 	  if (!flag_openmp)  /* flag_openmp_simd  */
19923 	    return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
19924 					  if_p);
19925 	  block = c_begin_compound_stmt (true);
19926 	  ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
19927 				       if_p);
19928 	  block = c_end_compound_stmt (loc, block, true);
19929 	  if (ret == NULL_TREE)
19930 	    return ret;
19931 	  ret = c_finish_omp_masked (loc, block,
19932 				     cclauses[C_OMP_CLAUSE_SPLIT_MASKED]);
19933 	  OMP_MASKED_COMBINED (ret) = 1;
19934 	  return ret;
19935 	}
19936     }
19937   if (!flag_openmp)  /* flag_openmp_simd  */
19938     {
19939       c_parser_skip_to_pragma_eol (parser, false);
19940       return NULL_TREE;
19941     }
19942 
19943   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19944   if (cclauses)
19945     {
19946       omp_split_clauses (loc, OMP_MASKED, mask, clauses, cclauses);
19947       clauses = cclauses[C_OMP_CLAUSE_SPLIT_MASKED];
19948     }
19949 
19950   return c_finish_omp_masked (loc, c_parser_omp_structured_block (parser,
19951 								  if_p),
19952 			      clauses);
19953 }
19954 
19955 /* OpenMP 2.5:
19956    # pragma omp ordered new-line
19957      structured-block
19958 
19959    OpenMP 4.5:
19960    # pragma omp ordered ordered-clauses new-line
19961      structured-block
19962 
19963    # pragma omp ordered depend-clauses new-line  */
19964 
19965 #define OMP_ORDERED_CLAUSE_MASK					\
19966 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS)	\
19967 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
19968 
19969 #define OMP_ORDERED_DEPEND_CLAUSE_MASK				\
19970 	(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
19971 
19972 static bool
c_parser_omp_ordered(c_parser * parser,enum pragma_context context,bool * if_p)19973 c_parser_omp_ordered (c_parser *parser, enum pragma_context context,
19974 		      bool *if_p)
19975 {
19976   location_t loc = c_parser_peek_token (parser)->location;
19977   c_parser_consume_pragma (parser);
19978 
19979   if (context != pragma_stmt && context != pragma_compound)
19980     {
19981       c_parser_error (parser, "expected declaration specifiers");
19982       c_parser_skip_to_pragma_eol (parser, false);
19983       return false;
19984     }
19985 
19986   if (c_parser_next_token_is (parser, CPP_NAME))
19987     {
19988       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19989 
19990       if (!strcmp ("depend", p))
19991 	{
19992 	  if (!flag_openmp)	/* flag_openmp_simd  */
19993 	    {
19994 	      c_parser_skip_to_pragma_eol (parser, false);
19995 	      return false;
19996 	    }
19997 	  if (context == pragma_stmt)
19998 	    {
19999 	      error_at (loc,
20000 			"%<#pragma omp ordered%> with %<depend%> clause may "
20001 			"only be used in compound statements");
20002 	      c_parser_skip_to_pragma_eol (parser, false);
20003 	      return true;
20004 	    }
20005 
20006 	  tree clauses
20007 	    = c_parser_omp_all_clauses (parser,
20008 					OMP_ORDERED_DEPEND_CLAUSE_MASK,
20009 					"#pragma omp ordered");
20010 	  c_finish_omp_ordered (loc, clauses, NULL_TREE);
20011 	  return false;
20012 	}
20013     }
20014 
20015   tree clauses = c_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK,
20016 					   "#pragma omp ordered");
20017 
20018   if (!flag_openmp	/* flag_openmp_simd  */
20019       && omp_find_clause (clauses, OMP_CLAUSE_SIMD) == NULL_TREE)
20020     return false;
20021 
20022   c_finish_omp_ordered (loc, clauses,
20023 			c_parser_omp_structured_block (parser, if_p));
20024   return true;
20025 }
20026 
20027 /* OpenMP 2.5:
20028 
20029    section-scope:
20030      { section-sequence }
20031 
20032    section-sequence:
20033      section-directive[opt] structured-block
20034      section-sequence section-directive structured-block
20035 
20036    OpenMP 5.1 allows structured-block-sequence instead of structured-block.
20037 
20038     SECTIONS_LOC is the location of the #pragma omp sections.  */
20039 
20040 static tree
c_parser_omp_sections_scope(location_t sections_loc,c_parser * parser)20041 c_parser_omp_sections_scope (location_t sections_loc, c_parser *parser)
20042 {
20043   tree stmt, substmt;
20044   bool error_suppress = false;
20045   location_t loc;
20046 
20047   loc = c_parser_peek_token (parser)->location;
20048   if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
20049     {
20050       /* Avoid skipping until the end of the block.  */
20051       parser->error = false;
20052       return NULL_TREE;
20053     }
20054 
20055   stmt = push_stmt_list ();
20056 
20057   if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION)
20058     {
20059       substmt = c_parser_omp_structured_block_sequence (parser,
20060 							PRAGMA_OMP_SECTION);
20061       substmt = build1 (OMP_SECTION, void_type_node, substmt);
20062       SET_EXPR_LOCATION (substmt, loc);
20063       add_stmt (substmt);
20064     }
20065 
20066   while (1)
20067     {
20068       if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
20069 	break;
20070       if (c_parser_next_token_is (parser, CPP_EOF))
20071 	break;
20072 
20073       loc = c_parser_peek_token (parser)->location;
20074       if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION)
20075 	{
20076 	  c_parser_consume_pragma (parser);
20077 	  c_parser_skip_to_pragma_eol (parser);
20078 	  error_suppress = false;
20079 	}
20080       else if (!error_suppress)
20081 	{
20082 	  error_at (loc, "expected %<#pragma omp section%> or %<}%>");
20083 	  error_suppress = true;
20084 	}
20085 
20086       substmt = c_parser_omp_structured_block_sequence (parser,
20087 							PRAGMA_OMP_SECTION);
20088       substmt = build1 (OMP_SECTION, void_type_node, substmt);
20089       SET_EXPR_LOCATION (substmt, loc);
20090       add_stmt (substmt);
20091     }
20092   c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
20093 			     "expected %<#pragma omp section%> or %<}%>");
20094 
20095   substmt = pop_stmt_list (stmt);
20096 
20097   stmt = make_node (OMP_SECTIONS);
20098   SET_EXPR_LOCATION (stmt, sections_loc);
20099   TREE_TYPE (stmt) = void_type_node;
20100   OMP_SECTIONS_BODY (stmt) = substmt;
20101 
20102   return add_stmt (stmt);
20103 }
20104 
20105 /* OpenMP 2.5:
20106    # pragma omp sections sections-clause[optseq] newline
20107      sections-scope
20108 
20109    LOC is the location of the #pragma token.
20110 */
20111 
20112 #define OMP_SECTIONS_CLAUSE_MASK				\
20113 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
20114 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
20115 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)	\
20116 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)	\
20117 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)	\
20118 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20119 
20120 static tree
c_parser_omp_sections(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses)20121 c_parser_omp_sections (location_t loc, c_parser *parser,
20122 		       char *p_name, omp_clause_mask mask, tree *cclauses)
20123 {
20124   tree block, clauses, ret;
20125 
20126   strcat (p_name, " sections");
20127   mask |= OMP_SECTIONS_CLAUSE_MASK;
20128   if (cclauses)
20129     mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
20130 
20131   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20132   if (cclauses)
20133     {
20134       omp_split_clauses (loc, OMP_SECTIONS, mask, clauses, cclauses);
20135       clauses = cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS];
20136     }
20137 
20138   block = c_begin_compound_stmt (true);
20139   ret = c_parser_omp_sections_scope (loc, parser);
20140   if (ret)
20141     OMP_SECTIONS_CLAUSES (ret) = clauses;
20142   block = c_end_compound_stmt (loc, block, true);
20143   add_stmt (block);
20144 
20145   return ret;
20146 }
20147 
20148 /* OpenMP 2.5:
20149    # pragma omp parallel parallel-clause[optseq] new-line
20150      structured-block
20151    # pragma omp parallel for parallel-for-clause[optseq] new-line
20152      structured-block
20153    # pragma omp parallel sections parallel-sections-clause[optseq] new-line
20154      structured-block
20155 
20156    OpenMP 4.0:
20157    # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
20158      structured-block
20159 
20160    LOC is the location of the #pragma token.
20161 */
20162 
20163 #define OMP_PARALLEL_CLAUSE_MASK				\
20164 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
20165 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
20166 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
20167 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT)	\
20168 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED)	\
20169 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN)	\
20170 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)	\
20171 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)	\
20172 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)	\
20173 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
20174 
20175 static tree
c_parser_omp_parallel(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)20176 c_parser_omp_parallel (location_t loc, c_parser *parser,
20177 		       char *p_name, omp_clause_mask mask, tree *cclauses,
20178 		       bool *if_p)
20179 {
20180   tree stmt, clauses, block;
20181 
20182   strcat (p_name, " parallel");
20183   mask |= OMP_PARALLEL_CLAUSE_MASK;
20184   /* #pragma omp target parallel{, for, for simd} disallow copyin clause.  */
20185   if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0
20186       && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
20187     mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN);
20188 
20189   if (c_parser_next_token_is_keyword (parser, RID_FOR))
20190     {
20191       tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20192       if (cclauses == NULL)
20193 	cclauses = cclauses_buf;
20194 
20195       c_parser_consume_token (parser);
20196       if (!flag_openmp)  /* flag_openmp_simd  */
20197 	return c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
20198       block = c_begin_omp_parallel ();
20199       tree ret = c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
20200       stmt
20201 	= c_finish_omp_parallel (loc, cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20202 				 block);
20203       if (ret == NULL_TREE)
20204 	return ret;
20205       OMP_PARALLEL_COMBINED (stmt) = 1;
20206       return stmt;
20207     }
20208   /* When combined with distribute, parallel has to be followed by for.
20209      #pragma omp target parallel is allowed though.  */
20210   else if (cclauses
20211 	   && (mask & (OMP_CLAUSE_MASK_1
20212 		       << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
20213     {
20214       error_at (loc, "expected %<for%> after %qs", p_name);
20215       c_parser_skip_to_pragma_eol (parser);
20216       return NULL_TREE;
20217     }
20218   else if (c_parser_next_token_is (parser, CPP_NAME))
20219     {
20220       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20221       if (cclauses == NULL && strcmp (p, "masked") == 0)
20222 	{
20223 	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20224 	  cclauses = cclauses_buf;
20225 
20226 	  c_parser_consume_token (parser);
20227 	  if (!flag_openmp)  /* flag_openmp_simd  */
20228 	    return c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
20229 					if_p);
20230 	  block = c_begin_omp_parallel ();
20231 	  tree ret = c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
20232 					  if_p);
20233 	  stmt = c_finish_omp_parallel (loc,
20234 					cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20235 					block);
20236 	  if (ret == NULL)
20237 	    return ret;
20238 	  /* masked does have just filter clause, but during gimplification
20239 	     isn't represented by a gimplification omp context, so for
20240 	     #pragma omp parallel masked don't set OMP_PARALLEL_COMBINED,
20241 	     so that
20242 	     #pragma omp parallel masked
20243 	     #pragma omp taskloop simd lastprivate (x)
20244 	     isn't confused with
20245 	     #pragma omp parallel masked taskloop simd lastprivate (x)  */
20246 	  if (OMP_MASKED_COMBINED (ret))
20247 	    OMP_PARALLEL_COMBINED (stmt) = 1;
20248 	  return stmt;
20249 	}
20250       else if (cclauses == NULL && strcmp (p, "master") == 0)
20251 	{
20252 	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20253 	  cclauses = cclauses_buf;
20254 
20255 	  c_parser_consume_token (parser);
20256 	  if (!flag_openmp)  /* flag_openmp_simd  */
20257 	    return c_parser_omp_master (loc, parser, p_name, mask, cclauses,
20258 					if_p);
20259 	  block = c_begin_omp_parallel ();
20260 	  tree ret = c_parser_omp_master (loc, parser, p_name, mask, cclauses,
20261 					  if_p);
20262 	  stmt = c_finish_omp_parallel (loc,
20263 					cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20264 					block);
20265 	  if (ret == NULL)
20266 	    return ret;
20267 	  /* master doesn't have any clauses and during gimplification
20268 	     isn't represented by a gimplification omp context, so for
20269 	     #pragma omp parallel master don't set OMP_PARALLEL_COMBINED,
20270 	     so that
20271 	     #pragma omp parallel master
20272 	     #pragma omp taskloop simd lastprivate (x)
20273 	     isn't confused with
20274 	     #pragma omp parallel master taskloop simd lastprivate (x)  */
20275 	  if (OMP_MASTER_COMBINED (ret))
20276 	    OMP_PARALLEL_COMBINED (stmt) = 1;
20277 	  return stmt;
20278 	}
20279       else if (strcmp (p, "loop") == 0)
20280 	{
20281 	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20282 	  if (cclauses == NULL)
20283 	    cclauses = cclauses_buf;
20284 
20285 	  c_parser_consume_token (parser);
20286 	  if (!flag_openmp)  /* flag_openmp_simd  */
20287 	    return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
20288 				      if_p);
20289 	  block = c_begin_omp_parallel ();
20290 	  tree ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
20291 					if_p);
20292 	  stmt
20293 	    = c_finish_omp_parallel (loc,
20294 				     cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20295 				     block);
20296 	  if (ret == NULL_TREE)
20297 	    return ret;
20298 	  OMP_PARALLEL_COMBINED (stmt) = 1;
20299 	  return stmt;
20300 	}
20301       else if (!flag_openmp)  /* flag_openmp_simd  */
20302 	{
20303 	  c_parser_skip_to_pragma_eol (parser, false);
20304 	  return NULL_TREE;
20305 	}
20306       else if (cclauses == NULL && strcmp (p, "sections") == 0)
20307 	{
20308 	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20309 	  cclauses = cclauses_buf;
20310 
20311 	  c_parser_consume_token (parser);
20312 	  block = c_begin_omp_parallel ();
20313 	  c_parser_omp_sections (loc, parser, p_name, mask, cclauses);
20314 	  stmt = c_finish_omp_parallel (loc,
20315 					cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20316 					block);
20317 	  OMP_PARALLEL_COMBINED (stmt) = 1;
20318 	  return stmt;
20319 	}
20320     }
20321   else if (!flag_openmp)  /* flag_openmp_simd  */
20322     {
20323       c_parser_skip_to_pragma_eol (parser, false);
20324       return NULL_TREE;
20325     }
20326 
20327   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20328   if (cclauses)
20329     {
20330       omp_split_clauses (loc, OMP_PARALLEL, mask, clauses, cclauses);
20331       clauses = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
20332     }
20333 
20334   block = c_begin_omp_parallel ();
20335   c_parser_statement (parser, if_p);
20336   stmt = c_finish_omp_parallel (loc, clauses, block);
20337 
20338   return stmt;
20339 }
20340 
20341 /* OpenMP 2.5:
20342    # pragma omp single single-clause[optseq] new-line
20343      structured-block
20344 
20345    LOC is the location of the #pragma.
20346 */
20347 
20348 #define OMP_SINGLE_CLAUSE_MASK					\
20349 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
20350 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
20351 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE)	\
20352 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)	\
20353 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20354 
20355 static tree
c_parser_omp_single(location_t loc,c_parser * parser,bool * if_p)20356 c_parser_omp_single (location_t loc, c_parser *parser, bool *if_p)
20357 {
20358   tree stmt = make_node (OMP_SINGLE);
20359   SET_EXPR_LOCATION (stmt, loc);
20360   TREE_TYPE (stmt) = void_type_node;
20361 
20362   OMP_SINGLE_CLAUSES (stmt)
20363     = c_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK,
20364 				"#pragma omp single");
20365   OMP_SINGLE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
20366 
20367   return add_stmt (stmt);
20368 }
20369 
20370 /* OpenMP 5.1:
20371    # pragma omp scope scope-clause[optseq] new-line
20372      structured-block
20373 
20374    LOC is the location of the #pragma.
20375 */
20376 
20377 #define OMP_SCOPE_CLAUSE_MASK					\
20378 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
20379 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)	\
20380 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20381 
20382 static tree
c_parser_omp_scope(location_t loc,c_parser * parser,bool * if_p)20383 c_parser_omp_scope (location_t loc, c_parser *parser, bool *if_p)
20384 {
20385   tree stmt = make_node (OMP_SCOPE);
20386   SET_EXPR_LOCATION (stmt, loc);
20387   TREE_TYPE (stmt) = void_type_node;
20388 
20389   OMP_SCOPE_CLAUSES (stmt)
20390     = c_parser_omp_all_clauses (parser, OMP_SCOPE_CLAUSE_MASK,
20391 				"#pragma omp scope");
20392   OMP_SCOPE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
20393 
20394   return add_stmt (stmt);
20395 }
20396 
20397 /* OpenMP 3.0:
20398    # pragma omp task task-clause[optseq] new-line
20399 
20400    LOC is the location of the #pragma.
20401 */
20402 
20403 #define OMP_TASK_CLAUSE_MASK					\
20404 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
20405 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED)	\
20406 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT)	\
20407 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
20408 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
20409 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED)	\
20410 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL)	\
20411 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE)	\
20412 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)	\
20413 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY)	\
20414 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)	\
20415 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION)	\
20416 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH)	\
20417 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_AFFINITY))
20418 
20419 static tree
c_parser_omp_task(location_t loc,c_parser * parser,bool * if_p)20420 c_parser_omp_task (location_t loc, c_parser *parser, bool *if_p)
20421 {
20422   tree clauses, block;
20423 
20424   clauses = c_parser_omp_all_clauses (parser, OMP_TASK_CLAUSE_MASK,
20425 				      "#pragma omp task");
20426 
20427   block = c_begin_omp_task ();
20428   c_parser_statement (parser, if_p);
20429   return c_finish_omp_task (loc, clauses, block);
20430 }
20431 
20432 /* OpenMP 3.0:
20433    # pragma omp taskwait new-line
20434 
20435    OpenMP 5.0:
20436    # pragma omp taskwait taskwait-clause[optseq] new-line
20437 */
20438 
20439 #define OMP_TASKWAIT_CLAUSE_MASK					\
20440 	(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
20441 
20442 static void
c_parser_omp_taskwait(c_parser * parser)20443 c_parser_omp_taskwait (c_parser *parser)
20444 {
20445   location_t loc = c_parser_peek_token (parser)->location;
20446   c_parser_consume_pragma (parser);
20447 
20448   tree clauses
20449     = c_parser_omp_all_clauses (parser, OMP_TASKWAIT_CLAUSE_MASK,
20450 				"#pragma omp taskwait");
20451 
20452   if (clauses)
20453     {
20454       tree stmt = make_node (OMP_TASK);
20455       TREE_TYPE (stmt) = void_node;
20456       OMP_TASK_CLAUSES (stmt) = clauses;
20457       OMP_TASK_BODY (stmt) = NULL_TREE;
20458       SET_EXPR_LOCATION (stmt, loc);
20459       add_stmt (stmt);
20460     }
20461   else
20462     c_finish_omp_taskwait (loc);
20463 }
20464 
20465 /* OpenMP 3.1:
20466    # pragma omp taskyield new-line
20467 */
20468 
20469 static void
c_parser_omp_taskyield(c_parser * parser)20470 c_parser_omp_taskyield (c_parser *parser)
20471 {
20472   location_t loc = c_parser_peek_token (parser)->location;
20473   c_parser_consume_pragma (parser);
20474   c_parser_skip_to_pragma_eol (parser);
20475 
20476   c_finish_omp_taskyield (loc);
20477 }
20478 
20479 /* OpenMP 4.0:
20480    # pragma omp taskgroup new-line
20481 
20482    OpenMP 5.0:
20483    # pragma omp taskgroup taskgroup-clause[optseq] new-line
20484 */
20485 
20486 #define OMP_TASKGROUP_CLAUSE_MASK				\
20487 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)	\
20488 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
20489 
20490 static tree
c_parser_omp_taskgroup(location_t loc,c_parser * parser,bool * if_p)20491 c_parser_omp_taskgroup (location_t loc, c_parser *parser, bool *if_p)
20492 {
20493   tree clauses = c_parser_omp_all_clauses (parser, OMP_TASKGROUP_CLAUSE_MASK,
20494 					   "#pragma omp taskgroup");
20495 
20496   tree body = c_parser_omp_structured_block (parser, if_p);
20497   return c_finish_omp_taskgroup (loc, body, clauses);
20498 }
20499 
20500 /* OpenMP 4.0:
20501    # pragma omp cancel cancel-clause[optseq] new-line
20502 
20503    LOC is the location of the #pragma.
20504 */
20505 
20506 #define OMP_CANCEL_CLAUSE_MASK					\
20507 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL)	\
20508 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR)		\
20509 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS)	\
20510 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP)	\
20511 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
20512 
20513 static void
c_parser_omp_cancel(c_parser * parser)20514 c_parser_omp_cancel (c_parser *parser)
20515 {
20516   location_t loc = c_parser_peek_token (parser)->location;
20517 
20518   c_parser_consume_pragma (parser);
20519   tree clauses = c_parser_omp_all_clauses (parser, OMP_CANCEL_CLAUSE_MASK,
20520 					   "#pragma omp cancel");
20521 
20522   c_finish_omp_cancel (loc, clauses);
20523 }
20524 
20525 /* OpenMP 4.0:
20526    # pragma omp cancellation point cancelpt-clause[optseq] new-line
20527 
20528    LOC is the location of the #pragma.
20529 */
20530 
20531 #define OMP_CANCELLATION_POINT_CLAUSE_MASK			\
20532 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL)	\
20533 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR)		\
20534 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS)	\
20535 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
20536 
20537 static bool
c_parser_omp_cancellation_point(c_parser * parser,enum pragma_context context)20538 c_parser_omp_cancellation_point (c_parser *parser, enum pragma_context context)
20539 {
20540   location_t loc = c_parser_peek_token (parser)->location;
20541   tree clauses;
20542   bool point_seen = false;
20543 
20544   c_parser_consume_pragma (parser);
20545   if (c_parser_next_token_is (parser, CPP_NAME))
20546     {
20547       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20548       if (strcmp (p, "point") == 0)
20549 	{
20550 	  c_parser_consume_token (parser);
20551 	  point_seen = true;
20552 	}
20553     }
20554   if (!point_seen)
20555     {
20556       c_parser_error (parser, "expected %<point%>");
20557       c_parser_skip_to_pragma_eol (parser);
20558       return false;
20559     }
20560 
20561   if (context != pragma_compound)
20562     {
20563       if (context == pragma_stmt)
20564 	error_at (loc,
20565 		  "%<#pragma %s%> may only be used in compound statements",
20566 		  "omp cancellation point");
20567       else
20568 	c_parser_error (parser, "expected declaration specifiers");
20569       c_parser_skip_to_pragma_eol (parser, false);
20570       return true;
20571     }
20572 
20573   clauses
20574     = c_parser_omp_all_clauses (parser, OMP_CANCELLATION_POINT_CLAUSE_MASK,
20575 				"#pragma omp cancellation point");
20576 
20577   c_finish_omp_cancellation_point (loc, clauses);
20578   return true;
20579 }
20580 
20581 /* OpenMP 4.0:
20582    #pragma omp distribute distribute-clause[optseq] new-line
20583      for-loop  */
20584 
20585 #define OMP_DISTRIBUTE_CLAUSE_MASK				\
20586 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
20587 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
20588 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)	\
20589 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
20590 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)	\
20591 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)	\
20592 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
20593 
20594 static tree
c_parser_omp_distribute(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)20595 c_parser_omp_distribute (location_t loc, c_parser *parser,
20596 			 char *p_name, omp_clause_mask mask, tree *cclauses,
20597 			 bool *if_p)
20598 {
20599   tree clauses, block, ret;
20600 
20601   strcat (p_name, " distribute");
20602   mask |= OMP_DISTRIBUTE_CLAUSE_MASK;
20603 
20604   if (c_parser_next_token_is (parser, CPP_NAME))
20605     {
20606       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20607       bool simd = false;
20608       bool parallel = false;
20609 
20610       if (strcmp (p, "simd") == 0)
20611 	simd = true;
20612       else
20613 	parallel = strcmp (p, "parallel") == 0;
20614       if (parallel || simd)
20615 	{
20616 	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20617 	  if (cclauses == NULL)
20618 	    cclauses = cclauses_buf;
20619 	  c_parser_consume_token (parser);
20620 	  if (!flag_openmp)  /* flag_openmp_simd  */
20621 	    {
20622 	      if (simd)
20623 		return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
20624 					  if_p);
20625 	      else
20626 		return c_parser_omp_parallel (loc, parser, p_name, mask,
20627 					      cclauses, if_p);
20628 	    }
20629 	  block = c_begin_compound_stmt (true);
20630 	  if (simd)
20631 	    ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
20632 				     if_p);
20633 	  else
20634 	    ret = c_parser_omp_parallel (loc, parser, p_name, mask, cclauses,
20635 					 if_p);
20636 	  block = c_end_compound_stmt (loc, block, true);
20637 	  if (ret == NULL)
20638 	    return ret;
20639 	  ret = make_node (OMP_DISTRIBUTE);
20640 	  TREE_TYPE (ret) = void_type_node;
20641 	  OMP_FOR_BODY (ret) = block;
20642 	  OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
20643 	  SET_EXPR_LOCATION (ret, loc);
20644 	  add_stmt (ret);
20645 	  return ret;
20646 	}
20647     }
20648   if (!flag_openmp)  /* flag_openmp_simd  */
20649     {
20650       c_parser_skip_to_pragma_eol (parser, false);
20651       return NULL_TREE;
20652     }
20653 
20654   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20655   if (cclauses)
20656     {
20657       omp_split_clauses (loc, OMP_DISTRIBUTE, mask, clauses, cclauses);
20658       clauses = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
20659     }
20660 
20661   block = c_begin_compound_stmt (true);
20662   ret = c_parser_omp_for_loop (loc, parser, OMP_DISTRIBUTE, clauses, NULL,
20663 			       if_p);
20664   block = c_end_compound_stmt (loc, block, true);
20665   add_stmt (block);
20666 
20667   return ret;
20668 }
20669 
20670 /* OpenMP 4.0:
20671    # pragma omp teams teams-clause[optseq] new-line
20672      structured-block  */
20673 
20674 #define OMP_TEAMS_CLAUSE_MASK					\
20675 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
20676 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
20677 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED)	\
20678 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)	\
20679 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS)	\
20680 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT)	\
20681 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)	\
20682 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
20683 
20684 static tree
c_parser_omp_teams(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)20685 c_parser_omp_teams (location_t loc, c_parser *parser,
20686 		    char *p_name, omp_clause_mask mask, tree *cclauses,
20687 		    bool *if_p)
20688 {
20689   tree clauses, block, ret;
20690 
20691   strcat (p_name, " teams");
20692   mask |= OMP_TEAMS_CLAUSE_MASK;
20693 
20694   if (c_parser_next_token_is (parser, CPP_NAME))
20695     {
20696       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20697       if (strcmp (p, "distribute") == 0)
20698 	{
20699 	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20700 	  if (cclauses == NULL)
20701 	    cclauses = cclauses_buf;
20702 
20703 	  c_parser_consume_token (parser);
20704 	  if (!flag_openmp)  /* flag_openmp_simd  */
20705 	    return c_parser_omp_distribute (loc, parser, p_name, mask,
20706 					    cclauses, if_p);
20707 	  block = c_begin_omp_parallel ();
20708 	  ret = c_parser_omp_distribute (loc, parser, p_name, mask, cclauses,
20709 					 if_p);
20710 	  block = c_end_compound_stmt (loc, block, true);
20711 	  if (ret == NULL)
20712 	    return ret;
20713 	  clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
20714 	  ret = make_node (OMP_TEAMS);
20715 	  TREE_TYPE (ret) = void_type_node;
20716 	  OMP_TEAMS_CLAUSES (ret) = clauses;
20717 	  OMP_TEAMS_BODY (ret) = block;
20718 	  OMP_TEAMS_COMBINED (ret) = 1;
20719 	  SET_EXPR_LOCATION (ret, loc);
20720 	  return add_stmt (ret);
20721 	}
20722       else if (strcmp (p, "loop") == 0)
20723 	{
20724 	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20725 	  if (cclauses == NULL)
20726 	    cclauses = cclauses_buf;
20727 
20728 	  c_parser_consume_token (parser);
20729 	  if (!flag_openmp)  /* flag_openmp_simd  */
20730 	    return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
20731 				      if_p);
20732 	  block = c_begin_omp_parallel ();
20733 	  ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses, if_p);
20734 	  block = c_end_compound_stmt (loc, block, true);
20735 	  if (ret == NULL)
20736 	    return ret;
20737 	  clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
20738 	  ret = make_node (OMP_TEAMS);
20739 	  TREE_TYPE (ret) = void_type_node;
20740 	  OMP_TEAMS_CLAUSES (ret) = clauses;
20741 	  OMP_TEAMS_BODY (ret) = block;
20742 	  OMP_TEAMS_COMBINED (ret) = 1;
20743 	  SET_EXPR_LOCATION (ret, loc);
20744 	  return add_stmt (ret);
20745 	}
20746     }
20747   if (!flag_openmp)  /* flag_openmp_simd  */
20748     {
20749       c_parser_skip_to_pragma_eol (parser, false);
20750       return NULL_TREE;
20751     }
20752 
20753   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20754   if (cclauses)
20755     {
20756       omp_split_clauses (loc, OMP_TEAMS, mask, clauses, cclauses);
20757       clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
20758     }
20759 
20760   tree stmt = make_node (OMP_TEAMS);
20761   TREE_TYPE (stmt) = void_type_node;
20762   OMP_TEAMS_CLAUSES (stmt) = clauses;
20763   block = c_begin_omp_parallel ();
20764   add_stmt (c_parser_omp_structured_block (parser, if_p));
20765   OMP_TEAMS_BODY (stmt) = c_end_compound_stmt (loc, block, true);
20766   SET_EXPR_LOCATION (stmt, loc);
20767 
20768   return add_stmt (stmt);
20769 }
20770 
20771 /* OpenMP 4.0:
20772    # pragma omp target data target-data-clause[optseq] new-line
20773      structured-block  */
20774 
20775 #define OMP_TARGET_DATA_CLAUSE_MASK				\
20776 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE)	\
20777 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)		\
20778 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
20779 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
20780 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
20781 
20782 static tree
c_parser_omp_target_data(location_t loc,c_parser * parser,bool * if_p)20783 c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p)
20784 {
20785   tree clauses
20786     = c_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
20787 				"#pragma omp target data");
20788   c_omp_adjust_map_clauses (clauses, false);
20789   int map_seen = 0;
20790   for (tree *pc = &clauses; *pc;)
20791     {
20792       if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
20793 	switch (OMP_CLAUSE_MAP_KIND (*pc))
20794 	  {
20795 	  case GOMP_MAP_TO:
20796 	  case GOMP_MAP_ALWAYS_TO:
20797 	  case GOMP_MAP_FROM:
20798 	  case GOMP_MAP_ALWAYS_FROM:
20799 	  case GOMP_MAP_TOFROM:
20800 	  case GOMP_MAP_ALWAYS_TOFROM:
20801 	  case GOMP_MAP_ALLOC:
20802 	    map_seen = 3;
20803 	    break;
20804 	  case GOMP_MAP_FIRSTPRIVATE_POINTER:
20805 	  case GOMP_MAP_ALWAYS_POINTER:
20806 	  case GOMP_MAP_ATTACH_DETACH:
20807 	    break;
20808 	  default:
20809 	    map_seen |= 1;
20810 	    error_at (OMP_CLAUSE_LOCATION (*pc),
20811 		      "%<#pragma omp target data%> with map-type other "
20812 		      "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
20813 		      "on %<map%> clause");
20814 	    *pc = OMP_CLAUSE_CHAIN (*pc);
20815 	    continue;
20816 	  }
20817       else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
20818 	       || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
20819 	map_seen = 3;
20820       pc = &OMP_CLAUSE_CHAIN (*pc);
20821     }
20822 
20823   if (map_seen != 3)
20824     {
20825       if (map_seen == 0)
20826 	error_at (loc,
20827 		  "%<#pragma omp target data%> must contain at least "
20828 		  "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
20829 		  "clause");
20830       return NULL_TREE;
20831     }
20832 
20833   tree stmt = make_node (OMP_TARGET_DATA);
20834   TREE_TYPE (stmt) = void_type_node;
20835   OMP_TARGET_DATA_CLAUSES (stmt) = clauses;
20836   keep_next_level ();
20837   tree block = c_begin_compound_stmt (true);
20838   add_stmt (c_parser_omp_structured_block (parser, if_p));
20839   OMP_TARGET_DATA_BODY (stmt) = c_end_compound_stmt (loc, block, true);
20840 
20841   SET_EXPR_LOCATION (stmt, loc);
20842   return add_stmt (stmt);
20843 }
20844 
20845 /* OpenMP 4.0:
20846    # pragma omp target update target-update-clause[optseq] new-line */
20847 
20848 #define OMP_TARGET_UPDATE_CLAUSE_MASK				\
20849 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM)		\
20850 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO)		\
20851 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE)	\
20852 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
20853 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)	\
20854 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20855 
20856 static bool
c_parser_omp_target_update(location_t loc,c_parser * parser,enum pragma_context context)20857 c_parser_omp_target_update (location_t loc, c_parser *parser,
20858 			    enum pragma_context context)
20859 {
20860   if (context == pragma_stmt)
20861     {
20862       error_at (loc, "%<#pragma %s%> may only be used in compound statements",
20863 		"omp target update");
20864       c_parser_skip_to_pragma_eol (parser, false);
20865       return true;
20866     }
20867 
20868   tree clauses
20869     = c_parser_omp_all_clauses (parser, OMP_TARGET_UPDATE_CLAUSE_MASK,
20870 				"#pragma omp target update");
20871   if (omp_find_clause (clauses, OMP_CLAUSE_TO) == NULL_TREE
20872       && omp_find_clause (clauses, OMP_CLAUSE_FROM) == NULL_TREE)
20873     {
20874       error_at (loc,
20875 		"%<#pragma omp target update%> must contain at least one "
20876 		"%<from%> or %<to%> clauses");
20877       return false;
20878     }
20879 
20880   tree stmt = make_node (OMP_TARGET_UPDATE);
20881   TREE_TYPE (stmt) = void_type_node;
20882   OMP_TARGET_UPDATE_CLAUSES (stmt) = clauses;
20883   SET_EXPR_LOCATION (stmt, loc);
20884   add_stmt (stmt);
20885   return false;
20886 }
20887 
20888 /* OpenMP 4.5:
20889    # pragma omp target enter data target-data-clause[optseq] new-line  */
20890 
20891 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK			\
20892 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE)	\
20893 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)		\
20894 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
20895 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)	\
20896 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20897 
20898 static bool
c_parser_omp_target_enter_data(location_t loc,c_parser * parser,enum pragma_context context)20899 c_parser_omp_target_enter_data (location_t loc, c_parser *parser,
20900 				enum pragma_context context)
20901 {
20902   bool data_seen = false;
20903   if (c_parser_next_token_is (parser, CPP_NAME))
20904     {
20905       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20906       if (strcmp (p, "data") == 0)
20907 	{
20908 	  c_parser_consume_token (parser);
20909 	  data_seen = true;
20910 	}
20911     }
20912   if (!data_seen)
20913     {
20914       c_parser_error (parser, "expected %<data%>");
20915       c_parser_skip_to_pragma_eol (parser);
20916       return false;
20917     }
20918 
20919   if (context == pragma_stmt)
20920     {
20921       error_at (loc, "%<#pragma %s%> may only be used in compound statements",
20922 		"omp target enter data");
20923       c_parser_skip_to_pragma_eol (parser, false);
20924       return true;
20925     }
20926 
20927   tree clauses
20928     = c_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK,
20929 				"#pragma omp target enter data");
20930   c_omp_adjust_map_clauses (clauses, false);
20931   int map_seen = 0;
20932   for (tree *pc = &clauses; *pc;)
20933     {
20934       if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
20935 	switch (OMP_CLAUSE_MAP_KIND (*pc))
20936 	  {
20937 	  case GOMP_MAP_TO:
20938 	  case GOMP_MAP_ALWAYS_TO:
20939 	  case GOMP_MAP_ALLOC:
20940 	    map_seen = 3;
20941 	    break;
20942 	  case GOMP_MAP_FIRSTPRIVATE_POINTER:
20943 	  case GOMP_MAP_ALWAYS_POINTER:
20944 	  case GOMP_MAP_ATTACH_DETACH:
20945 	    break;
20946 	  default:
20947 	    map_seen |= 1;
20948 	    error_at (OMP_CLAUSE_LOCATION (*pc),
20949 		      "%<#pragma omp target enter data%> with map-type other "
20950 		      "than %<to%> or %<alloc%> on %<map%> clause");
20951 	    *pc = OMP_CLAUSE_CHAIN (*pc);
20952 	    continue;
20953 	  }
20954       pc = &OMP_CLAUSE_CHAIN (*pc);
20955     }
20956 
20957   if (map_seen != 3)
20958     {
20959       if (map_seen == 0)
20960 	error_at (loc,
20961 		  "%<#pragma omp target enter data%> must contain at least "
20962 		  "one %<map%> clause");
20963       return true;
20964     }
20965 
20966   tree stmt = make_node (OMP_TARGET_ENTER_DATA);
20967   TREE_TYPE (stmt) = void_type_node;
20968   OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses;
20969   SET_EXPR_LOCATION (stmt, loc);
20970   add_stmt (stmt);
20971   return true;
20972 }
20973 
20974 /* OpenMP 4.5:
20975    # pragma omp target exit data target-data-clause[optseq] new-line  */
20976 
20977 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK			\
20978 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE)	\
20979 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)		\
20980 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
20981 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)	\
20982 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20983 
20984 static bool
c_parser_omp_target_exit_data(location_t loc,c_parser * parser,enum pragma_context context)20985 c_parser_omp_target_exit_data (location_t loc, c_parser *parser,
20986 			       enum pragma_context context)
20987 {
20988   bool data_seen = false;
20989   if (c_parser_next_token_is (parser, CPP_NAME))
20990     {
20991       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20992       if (strcmp (p, "data") == 0)
20993 	{
20994 	  c_parser_consume_token (parser);
20995 	  data_seen = true;
20996 	}
20997     }
20998   if (!data_seen)
20999     {
21000       c_parser_error (parser, "expected %<data%>");
21001       c_parser_skip_to_pragma_eol (parser);
21002       return false;
21003     }
21004 
21005   if (context == pragma_stmt)
21006     {
21007       error_at (loc, "%<#pragma %s%> may only be used in compound statements",
21008 		"omp target exit data");
21009       c_parser_skip_to_pragma_eol (parser, false);
21010       return true;
21011     }
21012 
21013   tree clauses
21014     = c_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK,
21015 				"#pragma omp target exit data");
21016   c_omp_adjust_map_clauses (clauses, false);
21017   int map_seen = 0;
21018   for (tree *pc = &clauses; *pc;)
21019     {
21020       if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
21021 	switch (OMP_CLAUSE_MAP_KIND (*pc))
21022 	  {
21023 	  case GOMP_MAP_FROM:
21024 	  case GOMP_MAP_ALWAYS_FROM:
21025 	  case GOMP_MAP_RELEASE:
21026 	  case GOMP_MAP_DELETE:
21027 	    map_seen = 3;
21028 	    break;
21029 	  case GOMP_MAP_FIRSTPRIVATE_POINTER:
21030 	  case GOMP_MAP_ALWAYS_POINTER:
21031 	  case GOMP_MAP_ATTACH_DETACH:
21032 	    break;
21033 	  default:
21034 	    map_seen |= 1;
21035 	    error_at (OMP_CLAUSE_LOCATION (*pc),
21036 		      "%<#pragma omp target exit data%> with map-type other "
21037 		      "than %<from%>, %<release%> or %<delete%> on %<map%>"
21038 		      " clause");
21039 	    *pc = OMP_CLAUSE_CHAIN (*pc);
21040 	    continue;
21041 	  }
21042       pc = &OMP_CLAUSE_CHAIN (*pc);
21043     }
21044 
21045   if (map_seen != 3)
21046     {
21047       if (map_seen == 0)
21048 	error_at (loc,
21049 		  "%<#pragma omp target exit data%> must contain at least one "
21050 		  "%<map%> clause");
21051       return true;
21052     }
21053 
21054   tree stmt = make_node (OMP_TARGET_EXIT_DATA);
21055   TREE_TYPE (stmt) = void_type_node;
21056   OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses;
21057   SET_EXPR_LOCATION (stmt, loc);
21058   add_stmt (stmt);
21059   return true;
21060 }
21061 
21062 /* OpenMP 4.0:
21063    # pragma omp target target-clause[optseq] new-line
21064      structured-block  */
21065 
21066 #define OMP_TARGET_CLAUSE_MASK					\
21067 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE)	\
21068 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)		\
21069 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
21070 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)	\
21071 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT)	\
21072 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
21073 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
21074 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)	\
21075 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP)	\
21076 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION)	\
21077 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT)	\
21078 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)\
21079 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR))
21080 
21081 static bool
c_parser_omp_target(c_parser * parser,enum pragma_context context,bool * if_p)21082 c_parser_omp_target (c_parser *parser, enum pragma_context context, bool *if_p)
21083 {
21084   location_t loc = c_parser_peek_token (parser)->location;
21085   c_parser_consume_pragma (parser);
21086   tree *pc = NULL, stmt, block;
21087 
21088   if (context != pragma_stmt && context != pragma_compound)
21089     {
21090       c_parser_error (parser, "expected declaration specifiers");
21091       c_parser_skip_to_pragma_eol (parser);
21092       return false;
21093     }
21094 
21095   if (flag_openmp)
21096     omp_requires_mask
21097       = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
21098 
21099   if (c_parser_next_token_is (parser, CPP_NAME))
21100     {
21101       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21102       enum tree_code ccode = ERROR_MARK;
21103 
21104       if (strcmp (p, "teams") == 0)
21105 	ccode = OMP_TEAMS;
21106       else if (strcmp (p, "parallel") == 0)
21107 	ccode = OMP_PARALLEL;
21108       else if (strcmp (p, "simd") == 0)
21109 	ccode = OMP_SIMD;
21110       if (ccode != ERROR_MARK)
21111 	{
21112 	  tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT];
21113 	  char p_name[sizeof ("#pragma omp target teams distribute "
21114 			      "parallel for simd")];
21115 
21116 	  c_parser_consume_token (parser);
21117 	  strcpy (p_name, "#pragma omp target");
21118 	  if (!flag_openmp)  /* flag_openmp_simd  */
21119 	    {
21120 	      tree stmt;
21121 	      switch (ccode)
21122 		{
21123 		case OMP_TEAMS:
21124 		  stmt = c_parser_omp_teams (loc, parser, p_name,
21125 					     OMP_TARGET_CLAUSE_MASK,
21126 					     cclauses, if_p);
21127 		  break;
21128 		case OMP_PARALLEL:
21129 		  stmt = c_parser_omp_parallel (loc, parser, p_name,
21130 						OMP_TARGET_CLAUSE_MASK,
21131 						cclauses, if_p);
21132 		  break;
21133 		case OMP_SIMD:
21134 		  stmt = c_parser_omp_simd (loc, parser, p_name,
21135 					    OMP_TARGET_CLAUSE_MASK,
21136 					    cclauses, if_p);
21137 		  break;
21138 		default:
21139 		  gcc_unreachable ();
21140 		}
21141 	      return stmt != NULL_TREE;
21142 	    }
21143 	  keep_next_level ();
21144 	  tree block = c_begin_compound_stmt (true), ret;
21145 	  switch (ccode)
21146 	    {
21147 	    case OMP_TEAMS:
21148 	      ret = c_parser_omp_teams (loc, parser, p_name,
21149 					OMP_TARGET_CLAUSE_MASK, cclauses,
21150 					if_p);
21151 	      break;
21152 	    case OMP_PARALLEL:
21153 	      ret = c_parser_omp_parallel (loc, parser, p_name,
21154 					   OMP_TARGET_CLAUSE_MASK, cclauses,
21155 					   if_p);
21156 	      break;
21157 	    case OMP_SIMD:
21158 	      ret = c_parser_omp_simd (loc, parser, p_name,
21159 				       OMP_TARGET_CLAUSE_MASK, cclauses,
21160 				       if_p);
21161 	      break;
21162 	    default:
21163 	      gcc_unreachable ();
21164 	    }
21165 	  block = c_end_compound_stmt (loc, block, true);
21166 	  if (ret == NULL_TREE)
21167 	    return false;
21168 	  if (ccode == OMP_TEAMS)
21169 	    /* For combined target teams, ensure the num_teams and
21170 	       thread_limit clause expressions are evaluated on the host,
21171 	       before entering the target construct.  */
21172 	    for (tree c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
21173 		 c; c = OMP_CLAUSE_CHAIN (c))
21174 	      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
21175 		  || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
21176 		for (int i = 0;
21177 		     i <= (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS); ++i)
21178 		  if (OMP_CLAUSE_OPERAND (c, i)
21179 		      && TREE_CODE (OMP_CLAUSE_OPERAND (c, i)) != INTEGER_CST)
21180 		    {
21181 		      tree expr = OMP_CLAUSE_OPERAND (c, i);
21182 		      tree tmp = create_tmp_var_raw (TREE_TYPE (expr));
21183 		      expr = build4 (TARGET_EXPR, TREE_TYPE (expr), tmp,
21184 				     expr, NULL_TREE, NULL_TREE);
21185 		      add_stmt (expr);
21186 		      OMP_CLAUSE_OPERAND (c, i) = expr;
21187 		      tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
21188 						  OMP_CLAUSE_FIRSTPRIVATE);
21189 		      OMP_CLAUSE_DECL (tc) = tmp;
21190 		      OMP_CLAUSE_CHAIN (tc)
21191 			= cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
21192 		      cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc;
21193 		    }
21194 	  tree stmt = make_node (OMP_TARGET);
21195 	  TREE_TYPE (stmt) = void_type_node;
21196 	  OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
21197 	  c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
21198 	  OMP_TARGET_BODY (stmt) = block;
21199 	  OMP_TARGET_COMBINED (stmt) = 1;
21200 	  SET_EXPR_LOCATION (stmt, loc);
21201 	  add_stmt (stmt);
21202 	  pc = &OMP_TARGET_CLAUSES (stmt);
21203 	  goto check_clauses;
21204 	}
21205       else if (!flag_openmp)  /* flag_openmp_simd  */
21206 	{
21207 	  c_parser_skip_to_pragma_eol (parser, false);
21208 	  return false;
21209 	}
21210       else if (strcmp (p, "data") == 0)
21211 	{
21212 	  c_parser_consume_token (parser);
21213 	  c_parser_omp_target_data (loc, parser, if_p);
21214 	  return true;
21215 	}
21216       else if (strcmp (p, "enter") == 0)
21217 	{
21218 	  c_parser_consume_token (parser);
21219 	  return c_parser_omp_target_enter_data (loc, parser, context);
21220 	}
21221       else if (strcmp (p, "exit") == 0)
21222 	{
21223 	  c_parser_consume_token (parser);
21224 	  return c_parser_omp_target_exit_data (loc, parser, context);
21225 	}
21226       else if (strcmp (p, "update") == 0)
21227 	{
21228 	  c_parser_consume_token (parser);
21229 	  return c_parser_omp_target_update (loc, parser, context);
21230 	}
21231     }
21232   if (!flag_openmp) /* flag_openmp_simd  */
21233     {
21234       c_parser_skip_to_pragma_eol (parser, false);
21235       return false;
21236     }
21237 
21238   stmt = make_node (OMP_TARGET);
21239   TREE_TYPE (stmt) = void_type_node;
21240 
21241   OMP_TARGET_CLAUSES (stmt)
21242     = c_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK,
21243 				"#pragma omp target", false);
21244   for (tree c = OMP_TARGET_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c))
21245     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION)
21246       {
21247 	tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
21248 	OMP_CLAUSE_DECL (nc) = OMP_CLAUSE_DECL (c);
21249 	OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_ALWAYS_TOFROM);
21250 	OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
21251 	OMP_CLAUSE_CHAIN (c) = nc;
21252       }
21253   OMP_TARGET_CLAUSES (stmt)
21254     = c_finish_omp_clauses (OMP_TARGET_CLAUSES (stmt), C_ORT_OMP_TARGET);
21255   c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
21256 
21257   pc = &OMP_TARGET_CLAUSES (stmt);
21258   keep_next_level ();
21259   block = c_begin_compound_stmt (true);
21260   add_stmt (c_parser_omp_structured_block (parser, if_p));
21261   OMP_TARGET_BODY (stmt) = c_end_compound_stmt (loc, block, true);
21262 
21263   SET_EXPR_LOCATION (stmt, loc);
21264   add_stmt (stmt);
21265 
21266 check_clauses:
21267   while (*pc)
21268     {
21269       if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
21270 	switch (OMP_CLAUSE_MAP_KIND (*pc))
21271 	  {
21272 	  case GOMP_MAP_TO:
21273 	  case GOMP_MAP_ALWAYS_TO:
21274 	  case GOMP_MAP_FROM:
21275 	  case GOMP_MAP_ALWAYS_FROM:
21276 	  case GOMP_MAP_TOFROM:
21277 	  case GOMP_MAP_ALWAYS_TOFROM:
21278 	  case GOMP_MAP_ALLOC:
21279 	  case GOMP_MAP_FIRSTPRIVATE_POINTER:
21280 	  case GOMP_MAP_ALWAYS_POINTER:
21281 	  case GOMP_MAP_ATTACH_DETACH:
21282 	    break;
21283 	  default:
21284 	    error_at (OMP_CLAUSE_LOCATION (*pc),
21285 		      "%<#pragma omp target%> with map-type other "
21286 		      "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
21287 		      "on %<map%> clause");
21288 	    *pc = OMP_CLAUSE_CHAIN (*pc);
21289 	    continue;
21290 	  }
21291       pc = &OMP_CLAUSE_CHAIN (*pc);
21292     }
21293   cfun->has_omp_target = true;
21294   return true;
21295 }
21296 
21297 /* OpenMP 4.0:
21298    # pragma omp declare simd declare-simd-clauses[optseq] new-line
21299 
21300    OpenMP 5.0:
21301    # pragma omp declare variant (identifier) match(context-selector) new-line
21302    */
21303 
21304 #define OMP_DECLARE_SIMD_CLAUSE_MASK				\
21305 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN)	\
21306 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR)	\
21307 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED)	\
21308 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)	\
21309 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH)	\
21310 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
21311 
21312 static void
c_parser_omp_declare_simd(c_parser * parser,enum pragma_context context)21313 c_parser_omp_declare_simd (c_parser *parser, enum pragma_context context)
21314 {
21315   c_token *token = c_parser_peek_token (parser);
21316   gcc_assert (token->type == CPP_NAME);
21317   tree kind = token->value;
21318   gcc_assert (strcmp (IDENTIFIER_POINTER (kind), "simd") == 0
21319 	      || strcmp (IDENTIFIER_POINTER (kind), "variant") == 0);
21320 
21321   auto_vec<c_token> clauses;
21322   while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
21323     {
21324       c_token *token = c_parser_peek_token (parser);
21325       if (token->type == CPP_EOF)
21326 	{
21327 	  c_parser_skip_to_pragma_eol (parser);
21328 	  return;
21329 	}
21330       clauses.safe_push (*token);
21331       c_parser_consume_token (parser);
21332     }
21333   clauses.safe_push (*c_parser_peek_token (parser));
21334   c_parser_skip_to_pragma_eol (parser);
21335 
21336   while (c_parser_next_token_is (parser, CPP_PRAGMA))
21337     {
21338       if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_DECLARE
21339 	  || c_parser_peek_2nd_token (parser)->type != CPP_NAME
21340 	  || c_parser_peek_2nd_token (parser)->value != kind)
21341 	{
21342 	  error ("%<#pragma omp declare %s%> must be followed by "
21343 		 "function declaration or definition or another "
21344 		 "%<#pragma omp declare %s%>",
21345 		 IDENTIFIER_POINTER (kind), IDENTIFIER_POINTER (kind));
21346 	  return;
21347 	}
21348       c_parser_consume_pragma (parser);
21349       while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
21350 	{
21351 	  c_token *token = c_parser_peek_token (parser);
21352 	  if (token->type == CPP_EOF)
21353 	    {
21354 	      c_parser_skip_to_pragma_eol (parser);
21355 	      return;
21356 	    }
21357 	  clauses.safe_push (*token);
21358 	  c_parser_consume_token (parser);
21359 	}
21360       clauses.safe_push (*c_parser_peek_token (parser));
21361       c_parser_skip_to_pragma_eol (parser);
21362     }
21363 
21364   /* Make sure nothing tries to read past the end of the tokens.  */
21365   c_token eof_token;
21366   memset (&eof_token, 0, sizeof (eof_token));
21367   eof_token.type = CPP_EOF;
21368   clauses.safe_push (eof_token);
21369   clauses.safe_push (eof_token);
21370 
21371   switch (context)
21372     {
21373     case pragma_external:
21374       if (c_parser_next_token_is (parser, CPP_KEYWORD)
21375 	  && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
21376 	{
21377 	  int ext = disable_extension_diagnostics ();
21378 	  do
21379 	    c_parser_consume_token (parser);
21380 	  while (c_parser_next_token_is (parser, CPP_KEYWORD)
21381 		 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
21382 	  c_parser_declaration_or_fndef (parser, true, true, true, false, true,
21383 					 NULL, &clauses);
21384 	  restore_extension_diagnostics (ext);
21385 	}
21386       else
21387 	c_parser_declaration_or_fndef (parser, true, true, true, false, true,
21388 				       NULL, &clauses);
21389       break;
21390     case pragma_struct:
21391     case pragma_param:
21392     case pragma_stmt:
21393       error ("%<#pragma omp declare %s%> must be followed by "
21394 	     "function declaration or definition",
21395 	     IDENTIFIER_POINTER (kind));
21396       break;
21397     case pragma_compound:
21398       if (c_parser_next_token_is (parser, CPP_KEYWORD)
21399 	  && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
21400 	{
21401 	  int ext = disable_extension_diagnostics ();
21402 	  do
21403 	    c_parser_consume_token (parser);
21404 	  while (c_parser_next_token_is (parser, CPP_KEYWORD)
21405 		 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
21406 	  if (c_parser_next_tokens_start_declaration (parser))
21407 	    {
21408 	      c_parser_declaration_or_fndef (parser, true, true, true, true,
21409 					     true, NULL, &clauses);
21410 	      restore_extension_diagnostics (ext);
21411 	      break;
21412 	    }
21413 	  restore_extension_diagnostics (ext);
21414 	}
21415       else if (c_parser_next_tokens_start_declaration (parser))
21416 	{
21417 	  c_parser_declaration_or_fndef (parser, true, true, true, true, true,
21418 					 NULL, &clauses);
21419 	  break;
21420 	}
21421       error ("%<#pragma omp declare %s%> must be followed by "
21422 	     "function declaration or definition",
21423 	     IDENTIFIER_POINTER (kind));
21424       break;
21425     default:
21426       gcc_unreachable ();
21427     }
21428 }
21429 
21430 static const char *const omp_construct_selectors[] = {
21431   "simd", "target", "teams", "parallel", "for", NULL };
21432 static const char *const omp_device_selectors[] = {
21433   "kind", "isa", "arch", NULL };
21434 static const char *const omp_implementation_selectors[] = {
21435   "vendor", "extension", "atomic_default_mem_order", "unified_address",
21436   "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL };
21437 static const char *const omp_user_selectors[] = {
21438   "condition", NULL };
21439 
21440 /* OpenMP 5.0:
21441 
21442    trait-selector:
21443      trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
21444 
21445    trait-score:
21446      score(score-expression)  */
21447 
21448 static tree
c_parser_omp_context_selector(c_parser * parser,tree set,tree parms)21449 c_parser_omp_context_selector (c_parser *parser, tree set, tree parms)
21450 {
21451   tree ret = NULL_TREE;
21452   do
21453     {
21454       tree selector;
21455       if (c_parser_next_token_is (parser, CPP_KEYWORD)
21456 	  || c_parser_next_token_is (parser, CPP_NAME))
21457 	selector = c_parser_peek_token (parser)->value;
21458       else
21459 	{
21460 	  c_parser_error (parser, "expected trait selector name");
21461 	  return error_mark_node;
21462 	}
21463 
21464       tree properties = NULL_TREE;
21465       const char *const *selectors = NULL;
21466       bool allow_score = true;
21467       bool allow_user = false;
21468       int property_limit = 0;
21469       enum { CTX_PROPERTY_NONE, CTX_PROPERTY_USER, CTX_PROPERTY_NAME_LIST,
21470 	     CTX_PROPERTY_ID, CTX_PROPERTY_EXPR,
21471 	     CTX_PROPERTY_SIMD } property_kind = CTX_PROPERTY_NONE;
21472       switch (IDENTIFIER_POINTER (set)[0])
21473 	{
21474 	case 'c': /* construct */
21475 	  selectors = omp_construct_selectors;
21476 	  allow_score = false;
21477 	  property_limit = 1;
21478 	  property_kind = CTX_PROPERTY_SIMD;
21479 	  break;
21480 	case 'd': /* device */
21481 	  selectors = omp_device_selectors;
21482 	  allow_score = false;
21483 	  allow_user = true;
21484 	  property_limit = 3;
21485 	  property_kind = CTX_PROPERTY_NAME_LIST;
21486 	  break;
21487 	case 'i': /* implementation */
21488 	  selectors = omp_implementation_selectors;
21489 	  allow_user = true;
21490 	  property_limit = 3;
21491 	  property_kind = CTX_PROPERTY_NAME_LIST;
21492 	  break;
21493 	case 'u': /* user */
21494 	  selectors = omp_user_selectors;
21495 	  property_limit = 1;
21496 	  property_kind = CTX_PROPERTY_EXPR;
21497 	  break;
21498 	default:
21499 	  gcc_unreachable ();
21500 	}
21501       for (int i = 0; ; i++)
21502 	{
21503 	  if (selectors[i] == NULL)
21504 	    {
21505 	      if (allow_user)
21506 		{
21507 		  property_kind = CTX_PROPERTY_USER;
21508 		  break;
21509 		}
21510 	      else
21511 		{
21512 		  error_at (c_parser_peek_token (parser)->location,
21513 			    "selector %qs not allowed for context selector "
21514 			    "set %qs", IDENTIFIER_POINTER (selector),
21515 			    IDENTIFIER_POINTER (set));
21516 		  c_parser_consume_token (parser);
21517 		  return error_mark_node;
21518 		}
21519 	    }
21520 	  if (i == property_limit)
21521 	    property_kind = CTX_PROPERTY_NONE;
21522 	  if (strcmp (selectors[i], IDENTIFIER_POINTER (selector)) == 0)
21523 	    break;
21524 	}
21525       if (property_kind == CTX_PROPERTY_NAME_LIST
21526 	  && IDENTIFIER_POINTER (set)[0] == 'i'
21527 	  && strcmp (IDENTIFIER_POINTER (selector),
21528 		     "atomic_default_mem_order") == 0)
21529 	property_kind = CTX_PROPERTY_ID;
21530 
21531       c_parser_consume_token (parser);
21532 
21533       if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
21534 	{
21535 	  if (property_kind == CTX_PROPERTY_NONE)
21536 	    {
21537 	      error_at (c_parser_peek_token (parser)->location,
21538 			"selector %qs does not accept any properties",
21539 			IDENTIFIER_POINTER (selector));
21540 	      return error_mark_node;
21541 	    }
21542 
21543 	  matching_parens parens;
21544 	  parens.require_open (parser);
21545 
21546 	  c_token *token = c_parser_peek_token (parser);
21547 	  if (allow_score
21548 	      && c_parser_next_token_is (parser, CPP_NAME)
21549 	      && strcmp (IDENTIFIER_POINTER (token->value), "score") == 0
21550 	      && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
21551 	    {
21552 	      c_parser_consume_token (parser);
21553 
21554 	      matching_parens parens2;
21555 	      parens2.require_open (parser);
21556 	      tree score = c_parser_expr_no_commas (parser, NULL).value;
21557 	      parens2.skip_until_found_close (parser);
21558 	      c_parser_require (parser, CPP_COLON, "expected %<:%>");
21559 	      if (score != error_mark_node)
21560 		{
21561 		  mark_exp_read (score);
21562 		  score = c_fully_fold (score, false, NULL);
21563 		  if (!INTEGRAL_TYPE_P (TREE_TYPE (score))
21564 		      || TREE_CODE (score) != INTEGER_CST)
21565 		    error_at (token->location, "score argument must be "
21566 			      "constant integer expression");
21567 		  else if (tree_int_cst_sgn (score) < 0)
21568 		    error_at (token->location, "score argument must be "
21569 			      "non-negative");
21570 		  else
21571 		    properties = tree_cons (get_identifier (" score"),
21572 					    score, properties);
21573 		}
21574 	      token = c_parser_peek_token (parser);
21575 	    }
21576 
21577 	  switch (property_kind)
21578 	    {
21579 	      tree t;
21580 	    case CTX_PROPERTY_USER:
21581 	      do
21582 		{
21583 		  t = c_parser_expr_no_commas (parser, NULL).value;
21584 		  if (TREE_CODE (t) == STRING_CST)
21585 		    properties = tree_cons (NULL_TREE, t, properties);
21586 		  else if (t != error_mark_node)
21587 		    {
21588 		      mark_exp_read (t);
21589 		      t = c_fully_fold (t, false, NULL);
21590 		      if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
21591 			  || !tree_fits_shwi_p (t))
21592 			error_at (token->location, "property must be "
21593 				  "constant integer expression or string "
21594 				  "literal");
21595 		      else
21596 			properties = tree_cons (NULL_TREE, t, properties);
21597 		    }
21598 		  else
21599 		    return error_mark_node;
21600 
21601 		  if (c_parser_next_token_is (parser, CPP_COMMA))
21602 		    c_parser_consume_token (parser);
21603 		  else
21604 		    break;
21605 		}
21606 	      while (1);
21607 	      break;
21608 	    case CTX_PROPERTY_ID:
21609 	      if (c_parser_next_token_is (parser, CPP_KEYWORD)
21610 		  || c_parser_next_token_is (parser, CPP_NAME))
21611 		{
21612 		  tree prop = c_parser_peek_token (parser)->value;
21613 		  c_parser_consume_token (parser);
21614 		  properties = tree_cons (prop, NULL_TREE, properties);
21615 		}
21616 	      else
21617 		{
21618 		  c_parser_error (parser, "expected identifier");
21619 		  return error_mark_node;
21620 		}
21621 	      break;
21622 	    case CTX_PROPERTY_NAME_LIST:
21623 	      do
21624 		{
21625 		  tree prop = NULL_TREE, value = NULL_TREE;
21626 		  if (c_parser_next_token_is (parser, CPP_KEYWORD)
21627 		      || c_parser_next_token_is (parser, CPP_NAME))
21628 		    {
21629 		      prop = c_parser_peek_token (parser)->value;
21630 		      c_parser_consume_token (parser);
21631 		    }
21632 		  else if (c_parser_next_token_is (parser, CPP_STRING))
21633 		    value = c_parser_string_literal (parser, false,
21634 						     false).value;
21635 		  else
21636 		    {
21637 		      c_parser_error (parser, "expected identifier or "
21638 					      "string literal");
21639 		      return error_mark_node;
21640 		    }
21641 
21642 		  properties = tree_cons (prop, value, properties);
21643 
21644 		  if (c_parser_next_token_is (parser, CPP_COMMA))
21645 		    c_parser_consume_token (parser);
21646 		  else
21647 		    break;
21648 		}
21649 	      while (1);
21650 	      break;
21651 	    case CTX_PROPERTY_EXPR:
21652 	      t = c_parser_expr_no_commas (parser, NULL).value;
21653 	      if (t != error_mark_node)
21654 		{
21655 		  mark_exp_read (t);
21656 		  t = c_fully_fold (t, false, NULL);
21657 		  if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
21658 		      || !tree_fits_shwi_p (t))
21659 		    error_at (token->location, "property must be "
21660 			      "constant integer expression");
21661 		  else
21662 		    properties = tree_cons (NULL_TREE, t, properties);
21663 		}
21664 	      else
21665 		return error_mark_node;
21666 	      break;
21667 	    case CTX_PROPERTY_SIMD:
21668 	      if (parms == NULL_TREE)
21669 		{
21670 		  error_at (token->location, "properties for %<simd%> "
21671 			    "selector may not be specified in "
21672 			    "%<metadirective%>");
21673 		  return error_mark_node;
21674 		}
21675 	      tree c;
21676 	      c = c_parser_omp_all_clauses (parser,
21677 					    OMP_DECLARE_SIMD_CLAUSE_MASK,
21678 					    "simd", true, 2);
21679 	      c = c_omp_declare_simd_clauses_to_numbers (parms
21680 							 == error_mark_node
21681 							 ? NULL_TREE : parms,
21682 							 c);
21683 	      properties = c;
21684 	      break;
21685 	    default:
21686 	      gcc_unreachable ();
21687 	    }
21688 
21689 	  parens.skip_until_found_close (parser);
21690 	  properties = nreverse (properties);
21691 	}
21692       else if (property_kind == CTX_PROPERTY_NAME_LIST
21693 	       || property_kind == CTX_PROPERTY_ID
21694 	       || property_kind == CTX_PROPERTY_EXPR)
21695 	{
21696 	  c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>");
21697 	  return error_mark_node;
21698 	}
21699 
21700       ret = tree_cons (selector, properties, ret);
21701 
21702       if (c_parser_next_token_is (parser, CPP_COMMA))
21703 	c_parser_consume_token (parser);
21704       else
21705 	break;
21706     }
21707   while (1);
21708 
21709   return nreverse (ret);
21710 }
21711 
21712 /* OpenMP 5.0:
21713 
21714    trait-set-selector[,trait-set-selector[,...]]
21715 
21716    trait-set-selector:
21717      trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
21718 
21719    trait-set-selector-name:
21720      constructor
21721      device
21722      implementation
21723      user  */
21724 
21725 static tree
c_parser_omp_context_selector_specification(c_parser * parser,tree parms)21726 c_parser_omp_context_selector_specification (c_parser *parser, tree parms)
21727 {
21728   tree ret = NULL_TREE;
21729   do
21730     {
21731       const char *setp = "";
21732       if (c_parser_next_token_is (parser, CPP_NAME))
21733 	setp = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21734       switch (setp[0])
21735 	{
21736 	case 'c':
21737 	  if (strcmp (setp, "construct") == 0)
21738 	    setp = NULL;
21739 	  break;
21740 	case 'd':
21741 	  if (strcmp (setp, "device") == 0)
21742 	    setp = NULL;
21743 	  break;
21744 	case 'i':
21745 	  if (strcmp (setp, "implementation") == 0)
21746 	    setp = NULL;
21747 	  break;
21748 	case 'u':
21749 	  if (strcmp (setp, "user") == 0)
21750 	    setp = NULL;
21751 	  break;
21752 	default:
21753 	  break;
21754 	}
21755       if (setp)
21756 	{
21757 	  c_parser_error (parser, "expected %<construct%>, %<device%>, "
21758 				  "%<implementation%> or %<user%>");
21759 	  return error_mark_node;
21760 	}
21761 
21762       tree set = c_parser_peek_token (parser)->value;
21763       c_parser_consume_token (parser);
21764 
21765       if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
21766 	return error_mark_node;
21767 
21768       matching_braces braces;
21769       if (!braces.require_open (parser))
21770 	return error_mark_node;
21771 
21772       tree selectors = c_parser_omp_context_selector (parser, set, parms);
21773       if (selectors == error_mark_node)
21774 	ret = error_mark_node;
21775       else if (ret != error_mark_node)
21776 	ret = tree_cons (set, selectors, ret);
21777 
21778       braces.skip_until_found_close (parser);
21779 
21780       if (c_parser_next_token_is (parser, CPP_COMMA))
21781 	c_parser_consume_token (parser);
21782       else
21783 	break;
21784     }
21785   while (1);
21786 
21787   if (ret == error_mark_node)
21788     return ret;
21789   return nreverse (ret);
21790 }
21791 
21792 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
21793    that into "omp declare variant base" attribute.  */
21794 
21795 static void
c_finish_omp_declare_variant(c_parser * parser,tree fndecl,tree parms)21796 c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms)
21797 {
21798   matching_parens parens;
21799   if (!parens.require_open (parser))
21800     {
21801      fail:
21802       c_parser_skip_to_pragma_eol (parser, false);
21803       return;
21804     }
21805 
21806   if (c_parser_next_token_is_not (parser, CPP_NAME)
21807       || c_parser_peek_token (parser)->id_kind != C_ID_ID)
21808     {
21809       c_parser_error (parser, "expected identifier");
21810       goto fail;
21811     }
21812 
21813   c_token *token = c_parser_peek_token (parser);
21814   tree variant = lookup_name (token->value);
21815 
21816   if (variant == NULL_TREE)
21817     {
21818       undeclared_variable (token->location, token->value);
21819       variant = error_mark_node;
21820     }
21821 
21822   c_parser_consume_token (parser);
21823 
21824   parens.require_close (parser);
21825 
21826   const char *clause = "";
21827   location_t match_loc = c_parser_peek_token (parser)->location;
21828   if (c_parser_next_token_is (parser, CPP_NAME))
21829     clause = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21830   if (strcmp (clause, "match"))
21831     {
21832       c_parser_error (parser, "expected %<match%>");
21833       goto fail;
21834     }
21835 
21836   c_parser_consume_token (parser);
21837 
21838   if (!parens.require_open (parser))
21839     goto fail;
21840 
21841   if (parms == NULL_TREE)
21842     parms = error_mark_node;
21843 
21844   tree ctx = c_parser_omp_context_selector_specification (parser, parms);
21845   if (ctx == error_mark_node)
21846     goto fail;
21847   ctx = omp_check_context_selector (match_loc, ctx);
21848   if (ctx != error_mark_node && variant != error_mark_node)
21849     {
21850       if (TREE_CODE (variant) != FUNCTION_DECL)
21851 	{
21852 	  error_at (token->location, "variant %qD is not a function", variant);
21853 	  variant = error_mark_node;
21854 	}
21855       else if (omp_get_context_selector (ctx, "construct", "simd") == NULL_TREE
21856 	       && !comptypes (TREE_TYPE (fndecl), TREE_TYPE (variant)))
21857 	{
21858 	  error_at (token->location, "variant %qD and base %qD have "
21859 				     "incompatible types", variant, fndecl);
21860 	  variant = error_mark_node;
21861 	}
21862       else if (fndecl_built_in_p (variant)
21863 	       && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
21864 			    "__builtin_", strlen ("__builtin_")) == 0
21865 		   || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
21866 			       "__sync_", strlen ("__sync_")) == 0
21867 		   || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
21868 			       "__atomic_", strlen ("__atomic_")) == 0))
21869 	{
21870 	  error_at (token->location, "variant %qD is a built-in", variant);
21871 	  variant = error_mark_node;
21872 	}
21873       if (variant != error_mark_node)
21874 	{
21875 	  C_DECL_USED (variant) = 1;
21876 	  tree construct = omp_get_context_selector (ctx, "construct", NULL);
21877 	  omp_mark_declare_variant (match_loc, variant, construct);
21878 	  if (omp_context_selector_matches (ctx))
21879 	    {
21880 	      tree attr
21881 		= tree_cons (get_identifier ("omp declare variant base"),
21882 			     build_tree_list (variant, ctx),
21883 			     DECL_ATTRIBUTES (fndecl));
21884 	      DECL_ATTRIBUTES (fndecl) = attr;
21885 	    }
21886 	}
21887     }
21888 
21889   parens.require_close (parser);
21890   c_parser_skip_to_pragma_eol (parser);
21891 }
21892 
21893 /* Finalize #pragma omp declare simd or #pragma omp declare variant
21894    clauses after FNDECL has been parsed, and put that into "omp declare simd"
21895    or "omp declare variant base" attribute.  */
21896 
21897 static void
c_finish_omp_declare_simd(c_parser * parser,tree fndecl,tree parms,vec<c_token> * pclauses)21898 c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms,
21899 			   vec<c_token> *pclauses)
21900 {
21901   vec<c_token> &clauses = *pclauses;
21902 
21903   /* Normally first token is CPP_NAME "simd" or "variant".  CPP_EOF there
21904      indicates error has been reported and CPP_PRAGMA that
21905      c_finish_omp_declare_simd has already processed the tokens.  */
21906   if (clauses.exists () && clauses[0].type == CPP_EOF)
21907     return;
21908   const char *kind = "simd";
21909   if (clauses.exists ()
21910       && (clauses[0].type == CPP_NAME || clauses[0].type == CPP_PRAGMA))
21911     kind = IDENTIFIER_POINTER (clauses[0].value);
21912   gcc_assert (strcmp (kind, "simd") == 0 || strcmp (kind, "variant") == 0);
21913   if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
21914     {
21915       error ("%<#pragma omp declare %s%> not immediately followed by "
21916 	     "a function declaration or definition", kind);
21917       clauses[0].type = CPP_EOF;
21918       return;
21919     }
21920   if (clauses.exists () && clauses[0].type != CPP_NAME)
21921     {
21922       error_at (DECL_SOURCE_LOCATION (fndecl),
21923 		"%<#pragma omp declare %s%> not immediately followed by "
21924 		"a single function declaration or definition", kind);
21925       clauses[0].type = CPP_EOF;
21926       return;
21927     }
21928 
21929   if (parms == NULL_TREE)
21930     parms = DECL_ARGUMENTS (fndecl);
21931 
21932   unsigned int tokens_avail = parser->tokens_avail;
21933   gcc_assert (parser->tokens == &parser->tokens_buf[0]);
21934 
21935   parser->tokens = clauses.address ();
21936   parser->tokens_avail = clauses.length ();
21937 
21938   /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end.  */
21939   while (parser->tokens_avail > 3)
21940     {
21941       c_token *token = c_parser_peek_token (parser);
21942       gcc_assert (token->type == CPP_NAME
21943 		  && strcmp (IDENTIFIER_POINTER (token->value), kind) == 0);
21944       c_parser_consume_token (parser);
21945       parser->in_pragma = true;
21946 
21947       if (strcmp (kind, "simd") == 0)
21948 	{
21949 	  tree c;
21950 	  c = c_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
21951 					"#pragma omp declare simd");
21952 	  c = c_omp_declare_simd_clauses_to_numbers (parms, c);
21953 	  if (c != NULL_TREE)
21954 	    c = tree_cons (NULL_TREE, c, NULL_TREE);
21955 	  c = build_tree_list (get_identifier ("omp declare simd"), c);
21956 	  TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl);
21957 	  DECL_ATTRIBUTES (fndecl) = c;
21958 	}
21959       else
21960 	{
21961 	  gcc_assert (strcmp (kind, "variant") == 0);
21962 	  c_finish_omp_declare_variant (parser, fndecl, parms);
21963 	}
21964     }
21965 
21966   parser->tokens = &parser->tokens_buf[0];
21967   parser->tokens_avail = tokens_avail;
21968   if (clauses.exists ())
21969     clauses[0].type = CPP_PRAGMA;
21970 }
21971 
21972 
21973 /* OpenMP 4.0:
21974    # pragma omp declare target new-line
21975    declarations and definitions
21976    # pragma omp end declare target new-line
21977 
21978    OpenMP 4.5:
21979    # pragma omp declare target ( extended-list ) new-line
21980 
21981    # pragma omp declare target declare-target-clauses[seq] new-line  */
21982 
21983 #define OMP_DECLARE_TARGET_CLAUSE_MASK				\
21984 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO)		\
21985 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)		\
21986 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
21987 
21988 static void
c_parser_omp_declare_target(c_parser * parser)21989 c_parser_omp_declare_target (c_parser *parser)
21990 {
21991   tree clauses = NULL_TREE;
21992   int device_type = 0;
21993   bool only_device_type = true;
21994   if (c_parser_next_token_is (parser, CPP_NAME))
21995     clauses = c_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
21996 					"#pragma omp declare target");
21997   else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
21998     {
21999       clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO_DECLARE,
22000 					      clauses);
22001       clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
22002       c_parser_skip_to_pragma_eol (parser);
22003     }
22004   else
22005     {
22006       c_parser_skip_to_pragma_eol (parser);
22007       current_omp_declare_target_attribute++;
22008       return;
22009     }
22010   for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
22011     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
22012       device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
22013   for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
22014     {
22015       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
22016 	continue;
22017       tree t = OMP_CLAUSE_DECL (c), id;
22018       tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
22019       tree at2 = lookup_attribute ("omp declare target link",
22020 				   DECL_ATTRIBUTES (t));
22021       only_device_type = false;
22022       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
22023 	{
22024 	  id = get_identifier ("omp declare target link");
22025 	  std::swap (at1, at2);
22026 	}
22027       else
22028 	id = get_identifier ("omp declare target");
22029       if (at2)
22030 	{
22031 	  error_at (OMP_CLAUSE_LOCATION (c),
22032 		    "%qD specified both in declare target %<link%> and %<to%>"
22033 		    " clauses", t);
22034 	  continue;
22035 	}
22036       if (!at1)
22037 	{
22038 	  DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
22039 	  if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t))
22040 	    continue;
22041 
22042 	  symtab_node *node = symtab_node::get (t);
22043 	  if (node != NULL)
22044 	    {
22045 	      node->offloadable = 1;
22046 	      if (ENABLE_OFFLOADING)
22047 		{
22048 		  g->have_offload = true;
22049 		  if (is_a <varpool_node *> (node))
22050 		    vec_safe_push (offload_vars, t);
22051 		}
22052 	    }
22053 	}
22054       if (TREE_CODE (t) != FUNCTION_DECL)
22055 	continue;
22056       if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0)
22057 	{
22058 	  tree at3 = lookup_attribute ("omp declare target host",
22059 				       DECL_ATTRIBUTES (t));
22060 	  if (at3 == NULL_TREE)
22061 	    {
22062 	      id = get_identifier ("omp declare target host");
22063 	      DECL_ATTRIBUTES (t)
22064 		= tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
22065 	    }
22066 	}
22067       if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0)
22068 	{
22069 	  tree at3 = lookup_attribute ("omp declare target nohost",
22070 				       DECL_ATTRIBUTES (t));
22071 	  if (at3 == NULL_TREE)
22072 	    {
22073 	      id = get_identifier ("omp declare target nohost");
22074 	      DECL_ATTRIBUTES (t)
22075 		= tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
22076 	    }
22077 	}
22078     }
22079   if (device_type && only_device_type)
22080     warning_at (OMP_CLAUSE_LOCATION (clauses), 0,
22081 		"directive with only %<device_type%> clauses ignored");
22082 }
22083 
22084 static void
c_parser_omp_end_declare_target(c_parser * parser)22085 c_parser_omp_end_declare_target (c_parser *parser)
22086 {
22087   location_t loc = c_parser_peek_token (parser)->location;
22088   c_parser_consume_pragma (parser);
22089   if (c_parser_next_token_is (parser, CPP_NAME)
22090       && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
22091 		 "declare") == 0)
22092     {
22093       c_parser_consume_token (parser);
22094       if (c_parser_next_token_is (parser, CPP_NAME)
22095 	  && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
22096 		     "target") == 0)
22097 	c_parser_consume_token (parser);
22098       else
22099 	{
22100 	  c_parser_error (parser, "expected %<target%>");
22101 	  c_parser_skip_to_pragma_eol (parser);
22102 	  return;
22103 	}
22104     }
22105   else
22106     {
22107       c_parser_error (parser, "expected %<declare%>");
22108       c_parser_skip_to_pragma_eol (parser);
22109       return;
22110     }
22111   c_parser_skip_to_pragma_eol (parser);
22112   if (!current_omp_declare_target_attribute)
22113     error_at (loc, "%<#pragma omp end declare target%> without corresponding "
22114 		   "%<#pragma omp declare target%>");
22115   else
22116     current_omp_declare_target_attribute--;
22117 }
22118 
22119 
22120 /* OpenMP 4.0
22121    #pragma omp declare reduction (reduction-id : typename-list : expression) \
22122       initializer-clause[opt] new-line
22123 
22124    initializer-clause:
22125       initializer (omp_priv = initializer)
22126       initializer (function-name (argument-list))  */
22127 
22128 static void
c_parser_omp_declare_reduction(c_parser * parser,enum pragma_context context)22129 c_parser_omp_declare_reduction (c_parser *parser, enum pragma_context context)
22130 {
22131   unsigned int tokens_avail = 0, i;
22132   vec<tree> types = vNULL;
22133   vec<c_token> clauses = vNULL;
22134   enum tree_code reduc_code = ERROR_MARK;
22135   tree reduc_id = NULL_TREE;
22136   tree type;
22137   location_t rloc = c_parser_peek_token (parser)->location;
22138 
22139   if (context == pragma_struct || context == pragma_param)
22140     {
22141       error ("%<#pragma omp declare reduction%> not at file or block scope");
22142       goto fail;
22143     }
22144 
22145   if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
22146     goto fail;
22147 
22148   switch (c_parser_peek_token (parser)->type)
22149     {
22150     case CPP_PLUS:
22151       reduc_code = PLUS_EXPR;
22152       break;
22153     case CPP_MULT:
22154       reduc_code = MULT_EXPR;
22155       break;
22156     case CPP_MINUS:
22157       reduc_code = MINUS_EXPR;
22158       break;
22159     case CPP_AND:
22160       reduc_code = BIT_AND_EXPR;
22161       break;
22162     case CPP_XOR:
22163       reduc_code = BIT_XOR_EXPR;
22164       break;
22165     case CPP_OR:
22166       reduc_code = BIT_IOR_EXPR;
22167       break;
22168     case CPP_AND_AND:
22169       reduc_code = TRUTH_ANDIF_EXPR;
22170       break;
22171     case CPP_OR_OR:
22172       reduc_code = TRUTH_ORIF_EXPR;
22173       break;
22174     case CPP_NAME:
22175       const char *p;
22176       p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22177       if (strcmp (p, "min") == 0)
22178 	{
22179 	  reduc_code = MIN_EXPR;
22180 	  break;
22181 	}
22182       if (strcmp (p, "max") == 0)
22183 	{
22184 	  reduc_code = MAX_EXPR;
22185 	  break;
22186 	}
22187       reduc_id = c_parser_peek_token (parser)->value;
22188       break;
22189     default:
22190       c_parser_error (parser,
22191 		      "expected %<+%>, %<*%>, %<-%>, %<&%>, "
22192 		      "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
22193       goto fail;
22194     }
22195 
22196   tree orig_reduc_id, reduc_decl;
22197   orig_reduc_id = reduc_id;
22198   reduc_id = c_omp_reduction_id (reduc_code, reduc_id);
22199   reduc_decl = c_omp_reduction_decl (reduc_id);
22200   c_parser_consume_token (parser);
22201 
22202   if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
22203     goto fail;
22204 
22205   while (true)
22206     {
22207       location_t loc = c_parser_peek_token (parser)->location;
22208       struct c_type_name *ctype = c_parser_type_name (parser);
22209       if (ctype != NULL)
22210 	{
22211 	  type = groktypename (ctype, NULL, NULL);
22212 	  if (type == error_mark_node)
22213 	    ;
22214 	  else if ((INTEGRAL_TYPE_P (type)
22215 		    || TREE_CODE (type) == REAL_TYPE
22216 		    || TREE_CODE (type) == COMPLEX_TYPE)
22217 		   && orig_reduc_id == NULL_TREE)
22218 	    error_at (loc, "predeclared arithmetic type in "
22219 			   "%<#pragma omp declare reduction%>");
22220 	  else if (TREE_CODE (type) == FUNCTION_TYPE
22221 		   || TREE_CODE (type) == ARRAY_TYPE)
22222 	    error_at (loc, "function or array type in "
22223 		      "%<#pragma omp declare reduction%>");
22224 	  else if (TYPE_ATOMIC (type))
22225 	    error_at (loc, "%<_Atomic%> qualified type in "
22226 			   "%<#pragma omp declare reduction%>");
22227 	  else if (TYPE_QUALS_NO_ADDR_SPACE (type))
22228 	    error_at (loc, "const, volatile or restrict qualified type in "
22229 			   "%<#pragma omp declare reduction%>");
22230 	  else
22231 	    {
22232 	      tree t;
22233 	      for (t = DECL_INITIAL (reduc_decl); t; t = TREE_CHAIN (t))
22234 		if (comptypes (TREE_PURPOSE (t), type))
22235 		  {
22236 		    error_at (loc, "redeclaration of %qs "
22237 				   "%<#pragma omp declare reduction%> for "
22238 				   "type %qT",
22239 				   IDENTIFIER_POINTER (reduc_id)
22240 				   + sizeof ("omp declare reduction ") - 1,
22241 				   type);
22242 		    location_t ploc
22243 		      = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t),
22244 							    0));
22245 		    error_at (ploc, "previous %<#pragma omp declare "
22246 				    "reduction%>");
22247 		    break;
22248 		  }
22249 	      if (t == NULL_TREE)
22250 		types.safe_push (type);
22251 	    }
22252 	  if (c_parser_next_token_is (parser, CPP_COMMA))
22253 	    c_parser_consume_token (parser);
22254 	  else
22255 	    break;
22256 	}
22257       else
22258 	break;
22259     }
22260 
22261   if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")
22262       || types.is_empty ())
22263     {
22264      fail:
22265       clauses.release ();
22266       types.release ();
22267       while (true)
22268 	{
22269 	  c_token *token = c_parser_peek_token (parser);
22270 	  if (token->type == CPP_EOF || token->type == CPP_PRAGMA_EOL)
22271 	    break;
22272 	  c_parser_consume_token (parser);
22273 	}
22274       c_parser_skip_to_pragma_eol (parser);
22275       return;
22276     }
22277 
22278   if (types.length () > 1)
22279     {
22280       while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
22281 	{
22282 	  c_token *token = c_parser_peek_token (parser);
22283 	  if (token->type == CPP_EOF)
22284 	    goto fail;
22285 	  clauses.safe_push (*token);
22286 	  c_parser_consume_token (parser);
22287 	}
22288       clauses.safe_push (*c_parser_peek_token (parser));
22289       c_parser_skip_to_pragma_eol (parser);
22290 
22291       /* Make sure nothing tries to read past the end of the tokens.  */
22292       c_token eof_token;
22293       memset (&eof_token, 0, sizeof (eof_token));
22294       eof_token.type = CPP_EOF;
22295       clauses.safe_push (eof_token);
22296       clauses.safe_push (eof_token);
22297     }
22298 
22299   int errs = errorcount;
22300   FOR_EACH_VEC_ELT (types, i, type)
22301     {
22302       tokens_avail = parser->tokens_avail;
22303       gcc_assert (parser->tokens == &parser->tokens_buf[0]);
22304       if (!clauses.is_empty ())
22305 	{
22306 	  parser->tokens = clauses.address ();
22307 	  parser->tokens_avail = clauses.length ();
22308 	  parser->in_pragma = true;
22309 	}
22310 
22311       bool nested = current_function_decl != NULL_TREE;
22312       if (nested)
22313 	c_push_function_context ();
22314       tree fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
22315 				reduc_id, default_function_type);
22316       current_function_decl = fndecl;
22317       allocate_struct_function (fndecl, true);
22318       push_scope ();
22319       tree stmt = push_stmt_list ();
22320       /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
22321 	 warn about these.  */
22322       tree omp_out = build_decl (BUILTINS_LOCATION, VAR_DECL,
22323 				 get_identifier ("omp_out"), type);
22324       DECL_ARTIFICIAL (omp_out) = 1;
22325       DECL_CONTEXT (omp_out) = fndecl;
22326       pushdecl (omp_out);
22327       tree omp_in = build_decl (BUILTINS_LOCATION, VAR_DECL,
22328 				get_identifier ("omp_in"), type);
22329       DECL_ARTIFICIAL (omp_in) = 1;
22330       DECL_CONTEXT (omp_in) = fndecl;
22331       pushdecl (omp_in);
22332       struct c_expr combiner = c_parser_expression (parser);
22333       struct c_expr initializer;
22334       tree omp_priv = NULL_TREE, omp_orig = NULL_TREE;
22335       bool bad = false;
22336       initializer.set_error ();
22337       if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
22338 	bad = true;
22339       else if (c_parser_next_token_is (parser, CPP_NAME)
22340 	       && strcmp (IDENTIFIER_POINTER
22341 				(c_parser_peek_token (parser)->value),
22342 			  "initializer") == 0)
22343 	{
22344 	  c_parser_consume_token (parser);
22345 	  pop_scope ();
22346 	  push_scope ();
22347 	  omp_priv = build_decl (BUILTINS_LOCATION, VAR_DECL,
22348 				 get_identifier ("omp_priv"), type);
22349 	  DECL_ARTIFICIAL (omp_priv) = 1;
22350 	  DECL_INITIAL (omp_priv) = error_mark_node;
22351 	  DECL_CONTEXT (omp_priv) = fndecl;
22352 	  pushdecl (omp_priv);
22353 	  omp_orig = build_decl (BUILTINS_LOCATION, VAR_DECL,
22354 				 get_identifier ("omp_orig"), type);
22355 	  DECL_ARTIFICIAL (omp_orig) = 1;
22356 	  DECL_CONTEXT (omp_orig) = fndecl;
22357 	  pushdecl (omp_orig);
22358 	  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
22359 	    bad = true;
22360 	  else if (!c_parser_next_token_is (parser, CPP_NAME))
22361 	    {
22362 	      c_parser_error (parser, "expected %<omp_priv%> or "
22363 				      "function-name");
22364 	      bad = true;
22365 	    }
22366 	  else if (strcmp (IDENTIFIER_POINTER
22367 				(c_parser_peek_token (parser)->value),
22368 			   "omp_priv") != 0)
22369 	    {
22370 	      if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
22371 		  || c_parser_peek_token (parser)->id_kind != C_ID_ID)
22372 		{
22373 		  c_parser_error (parser, "expected function-name %<(%>");
22374 		  bad = true;
22375 		}
22376 	      else
22377 		initializer = c_parser_postfix_expression (parser);
22378 	      if (initializer.value
22379 		  && TREE_CODE (initializer.value) == CALL_EXPR)
22380 		{
22381 		  int j;
22382 		  tree c = initializer.value;
22383 		  for (j = 0; j < call_expr_nargs (c); j++)
22384 		    {
22385 		      tree a = CALL_EXPR_ARG (c, j);
22386 		      STRIP_NOPS (a);
22387 		      if (TREE_CODE (a) == ADDR_EXPR
22388 			  && TREE_OPERAND (a, 0) == omp_priv)
22389 			break;
22390 		    }
22391 		  if (j == call_expr_nargs (c))
22392 		    error ("one of the initializer call arguments should be "
22393 			   "%<&omp_priv%>");
22394 		}
22395 	    }
22396 	  else
22397 	    {
22398 	      c_parser_consume_token (parser);
22399 	      if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
22400 		bad = true;
22401 	      else
22402 		{
22403 		  tree st = push_stmt_list ();
22404 		  location_t loc = c_parser_peek_token (parser)->location;
22405 		  rich_location richloc (line_table, loc);
22406 		  start_init (omp_priv, NULL_TREE, 0, &richloc);
22407 		  struct c_expr init = c_parser_initializer (parser, omp_priv);
22408 		  finish_init ();
22409 		  finish_decl (omp_priv, loc, init.value,
22410 		      	       init.original_type, NULL_TREE);
22411 		  pop_stmt_list (st);
22412 		}
22413 	    }
22414 	  if (!bad
22415 	      && !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
22416 	    bad = true;
22417 	}
22418 
22419       if (!bad)
22420 	{
22421 	  c_parser_skip_to_pragma_eol (parser);
22422 
22423 	  tree t = tree_cons (type, make_tree_vec (omp_priv ? 6 : 3),
22424 			      DECL_INITIAL (reduc_decl));
22425 	  DECL_INITIAL (reduc_decl) = t;
22426 	  DECL_SOURCE_LOCATION (omp_out) = rloc;
22427 	  TREE_VEC_ELT (TREE_VALUE (t), 0) = omp_out;
22428 	  TREE_VEC_ELT (TREE_VALUE (t), 1) = omp_in;
22429 	  TREE_VEC_ELT (TREE_VALUE (t), 2) = combiner.value;
22430 	  walk_tree (&combiner.value, c_check_omp_declare_reduction_r,
22431 		     &TREE_VEC_ELT (TREE_VALUE (t), 0), NULL);
22432 	  if (omp_priv)
22433 	    {
22434 	      DECL_SOURCE_LOCATION (omp_priv) = rloc;
22435 	      TREE_VEC_ELT (TREE_VALUE (t), 3) = omp_priv;
22436 	      TREE_VEC_ELT (TREE_VALUE (t), 4) = omp_orig;
22437 	      TREE_VEC_ELT (TREE_VALUE (t), 5) = initializer.value;
22438 	      walk_tree (&initializer.value, c_check_omp_declare_reduction_r,
22439 			 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
22440 	      walk_tree (&DECL_INITIAL (omp_priv),
22441 			 c_check_omp_declare_reduction_r,
22442 			 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
22443 	    }
22444 	}
22445 
22446       pop_stmt_list (stmt);
22447       pop_scope ();
22448       if (cfun->language != NULL)
22449 	{
22450 	  ggc_free (cfun->language);
22451 	  cfun->language = NULL;
22452 	}
22453       set_cfun (NULL);
22454       current_function_decl = NULL_TREE;
22455       if (nested)
22456 	c_pop_function_context ();
22457 
22458       if (!clauses.is_empty ())
22459 	{
22460 	  parser->tokens = &parser->tokens_buf[0];
22461 	  parser->tokens_avail = tokens_avail;
22462 	}
22463       if (bad)
22464 	goto fail;
22465       if (errs != errorcount)
22466 	break;
22467     }
22468 
22469   clauses.release ();
22470   types.release ();
22471 }
22472 
22473 
22474 /* OpenMP 4.0
22475    #pragma omp declare simd declare-simd-clauses[optseq] new-line
22476    #pragma omp declare reduction (reduction-id : typename-list : expression) \
22477       initializer-clause[opt] new-line
22478    #pragma omp declare target new-line
22479 
22480    OpenMP 5.0
22481    #pragma omp declare variant (identifier) match (context-selector)  */
22482 
22483 static bool
c_parser_omp_declare(c_parser * parser,enum pragma_context context)22484 c_parser_omp_declare (c_parser *parser, enum pragma_context context)
22485 {
22486   c_parser_consume_pragma (parser);
22487   if (c_parser_next_token_is (parser, CPP_NAME))
22488     {
22489       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22490       if (strcmp (p, "simd") == 0)
22491 	{
22492 	  /* c_parser_consume_token (parser); done in
22493 	     c_parser_omp_declare_simd.  */
22494 	  c_parser_omp_declare_simd (parser, context);
22495 	  return true;
22496 	}
22497       if (strcmp (p, "reduction") == 0)
22498 	{
22499 	  c_parser_consume_token (parser);
22500 	  c_parser_omp_declare_reduction (parser, context);
22501 	  return false;
22502 	}
22503       if (!flag_openmp)  /* flag_openmp_simd  */
22504 	{
22505 	  c_parser_skip_to_pragma_eol (parser, false);
22506 	  return false;
22507 	}
22508       if (strcmp (p, "target") == 0)
22509 	{
22510 	  c_parser_consume_token (parser);
22511 	  c_parser_omp_declare_target (parser);
22512 	  return false;
22513 	}
22514       if (strcmp (p, "variant") == 0)
22515 	{
22516 	  /* c_parser_consume_token (parser); done in
22517 	     c_parser_omp_declare_simd.  */
22518 	  c_parser_omp_declare_simd (parser, context);
22519 	  return true;
22520 	}
22521     }
22522 
22523   c_parser_error (parser, "expected %<simd%>, %<reduction%>, "
22524 			  "%<target%> or %<variant%>");
22525   c_parser_skip_to_pragma_eol (parser);
22526   return false;
22527 }
22528 
22529 /* OpenMP 5.0
22530    #pragma omp requires clauses[optseq] new-line  */
22531 
22532 static void
c_parser_omp_requires(c_parser * parser)22533 c_parser_omp_requires (c_parser *parser)
22534 {
22535   bool first = true;
22536   enum omp_requires new_req = (enum omp_requires) 0;
22537 
22538   c_parser_consume_pragma (parser);
22539 
22540   location_t loc = c_parser_peek_token (parser)->location;
22541   while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
22542     {
22543       if (!first
22544 	  && c_parser_next_token_is (parser, CPP_COMMA)
22545 	  && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
22546 	c_parser_consume_token (parser);
22547 
22548       first = false;
22549 
22550       if (c_parser_next_token_is (parser, CPP_NAME))
22551 	{
22552 	  const char *p
22553 	    = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22554 	  location_t cloc = c_parser_peek_token (parser)->location;
22555 	  enum omp_requires this_req = (enum omp_requires) 0;
22556 
22557 	  if (!strcmp (p, "unified_address"))
22558 	    this_req = OMP_REQUIRES_UNIFIED_ADDRESS;
22559 	  else if (!strcmp (p, "unified_shared_memory"))
22560 	    this_req = OMP_REQUIRES_UNIFIED_SHARED_MEMORY;
22561 	  else if (!strcmp (p, "dynamic_allocators"))
22562 	    this_req = OMP_REQUIRES_DYNAMIC_ALLOCATORS;
22563 	  else if (!strcmp (p, "reverse_offload"))
22564 	    this_req = OMP_REQUIRES_REVERSE_OFFLOAD;
22565 	  else if (!strcmp (p, "atomic_default_mem_order"))
22566 	    {
22567 	      c_parser_consume_token (parser);
22568 
22569 	      matching_parens parens;
22570 	      if (parens.require_open (parser))
22571 		{
22572 		  if (c_parser_next_token_is (parser, CPP_NAME))
22573 		    {
22574 		      tree v = c_parser_peek_token (parser)->value;
22575 		      p = IDENTIFIER_POINTER (v);
22576 
22577 		      if (!strcmp (p, "seq_cst"))
22578 			this_req
22579 			  = (enum omp_requires) OMP_MEMORY_ORDER_SEQ_CST;
22580 		      else if (!strcmp (p, "relaxed"))
22581 			this_req
22582 			  = (enum omp_requires) OMP_MEMORY_ORDER_RELAXED;
22583 		      else if (!strcmp (p, "acq_rel"))
22584 			this_req
22585 			  = (enum omp_requires) OMP_MEMORY_ORDER_ACQ_REL;
22586 		    }
22587 		  if (this_req == 0)
22588 		    {
22589 		      error_at (c_parser_peek_token (parser)->location,
22590 				"expected %<seq_cst%>, %<relaxed%> or "
22591 				"%<acq_rel%>");
22592 		      switch (c_parser_peek_token (parser)->type)
22593 			{
22594 			case CPP_EOF:
22595 			case CPP_PRAGMA_EOL:
22596 			case CPP_CLOSE_PAREN:
22597 			  break;
22598 			default:
22599 			  if (c_parser_peek_2nd_token (parser)->type
22600 			      == CPP_CLOSE_PAREN)
22601 			    c_parser_consume_token (parser);
22602 			  break;
22603 			}
22604 		    }
22605 		  else
22606 		    c_parser_consume_token (parser);
22607 
22608 		  parens.skip_until_found_close (parser);
22609 		  if (this_req == 0)
22610 		    {
22611 		      c_parser_skip_to_pragma_eol (parser, false);
22612 		      return;
22613 		    }
22614 		}
22615 	      p = NULL;
22616 	    }
22617 	  else
22618 	    {
22619 	      error_at (cloc, "expected %<unified_address%>, "
22620 			      "%<unified_shared_memory%>, "
22621 			      "%<dynamic_allocators%>, "
22622 			       "%<reverse_offload%> "
22623 			       "or %<atomic_default_mem_order%> clause");
22624 	      c_parser_skip_to_pragma_eol (parser, false);
22625 	      return;
22626 	    }
22627 	  if (p && this_req != OMP_REQUIRES_DYNAMIC_ALLOCATORS)
22628 	    sorry_at (cloc, "%qs clause on %<requires%> directive not "
22629 			    "supported yet", p);
22630 	  if (p)
22631 	    c_parser_consume_token (parser);
22632 	  if (this_req)
22633 	    {
22634 	      if ((this_req & ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
22635 		{
22636 		  if ((this_req & new_req) != 0)
22637 		    error_at (cloc, "too many %qs clauses", p);
22638 		  if (this_req != OMP_REQUIRES_DYNAMIC_ALLOCATORS
22639 		      && (omp_requires_mask & OMP_REQUIRES_TARGET_USED) != 0)
22640 		    error_at (cloc, "%qs clause used lexically after first "
22641 				    "target construct or offloading API", p);
22642 		}
22643 	      else if ((new_req & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
22644 		{
22645 		  error_at (cloc, "too many %qs clauses",
22646 			    "atomic_default_mem_order");
22647 		  this_req = (enum omp_requires) 0;
22648 		}
22649 	      else if ((omp_requires_mask
22650 			& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
22651 		{
22652 		  error_at (cloc, "more than one %<atomic_default_mem_order%>"
22653 				  " clause in a single compilation unit");
22654 		  this_req
22655 		    = (enum omp_requires)
22656 		       (omp_requires_mask
22657 			& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER);
22658 		}
22659 	      else if ((omp_requires_mask
22660 			& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED) != 0)
22661 		error_at (cloc, "%<atomic_default_mem_order%> clause used "
22662 				"lexically after first %<atomic%> construct "
22663 				"without memory order clause");
22664 	      new_req = (enum omp_requires) (new_req | this_req);
22665 	      omp_requires_mask
22666 		= (enum omp_requires) (omp_requires_mask | this_req);
22667 	      continue;
22668 	    }
22669 	}
22670       break;
22671     }
22672   c_parser_skip_to_pragma_eol (parser);
22673 
22674   if (new_req == 0)
22675     error_at (loc, "%<pragma omp requires%> requires at least one clause");
22676 }
22677 
22678 /* Helper function for c_parser_omp_taskloop.
22679    Disallow zero sized or potentially zero sized task reductions.  */
22680 
22681 static tree
c_finish_taskloop_clauses(tree clauses)22682 c_finish_taskloop_clauses (tree clauses)
22683 {
22684   tree *pc = &clauses;
22685   for (tree c = clauses; c; c = *pc)
22686     {
22687       bool remove = false;
22688       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
22689 	{
22690 	  tree type = strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c)));
22691 	  if (integer_zerop (TYPE_SIZE_UNIT (type)))
22692 	    {
22693 	      error_at (OMP_CLAUSE_LOCATION (c),
22694 			"zero sized type %qT in %<reduction%> clause", type);
22695 	      remove = true;
22696 	    }
22697 	  else if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
22698 	    {
22699 	      error_at (OMP_CLAUSE_LOCATION (c),
22700 			"variable sized type %qT in %<reduction%> clause",
22701 			type);
22702 	      remove = true;
22703 	    }
22704 	}
22705       if (remove)
22706 	*pc = OMP_CLAUSE_CHAIN (c);
22707       else
22708 	pc = &OMP_CLAUSE_CHAIN (c);
22709     }
22710   return clauses;
22711 }
22712 
22713 /* OpenMP 4.5:
22714    #pragma omp taskloop taskloop-clause[optseq] new-line
22715      for-loop
22716 
22717    #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
22718      for-loop  */
22719 
22720 #define OMP_TASKLOOP_CLAUSE_MASK				\
22721 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED)	\
22722 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
22723 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
22724 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)	\
22725 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT)	\
22726 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE)	\
22727 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS)	\
22728 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)	\
22729 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED)	\
22730 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
22731 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL)	\
22732 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE)	\
22733 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP)	\
22734 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY)	\
22735 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)	\
22736 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)	\
22737 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
22738 
22739 static tree
c_parser_omp_taskloop(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)22740 c_parser_omp_taskloop (location_t loc, c_parser *parser,
22741 		       char *p_name, omp_clause_mask mask, tree *cclauses,
22742 		       bool *if_p)
22743 {
22744   tree clauses, block, ret;
22745 
22746   strcat (p_name, " taskloop");
22747   mask |= OMP_TASKLOOP_CLAUSE_MASK;
22748   /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
22749      clause.  */
22750   if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
22751     mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION);
22752 
22753   if (c_parser_next_token_is (parser, CPP_NAME))
22754     {
22755       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22756 
22757       if (strcmp (p, "simd") == 0)
22758 	{
22759 	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
22760 	  if (cclauses == NULL)
22761 	    cclauses = cclauses_buf;
22762 	  c_parser_consume_token (parser);
22763 	  if (!flag_openmp)  /* flag_openmp_simd  */
22764 	    return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
22765 				      if_p);
22766 	  block = c_begin_compound_stmt (true);
22767 	  ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
22768 	  block = c_end_compound_stmt (loc, block, true);
22769 	  if (ret == NULL)
22770 	    return ret;
22771 	  ret = make_node (OMP_TASKLOOP);
22772 	  TREE_TYPE (ret) = void_type_node;
22773 	  OMP_FOR_BODY (ret) = block;
22774 	  OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
22775 	  OMP_FOR_CLAUSES (ret)
22776 	    = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret));
22777 	  SET_EXPR_LOCATION (ret, loc);
22778 	  add_stmt (ret);
22779 	  return ret;
22780 	}
22781     }
22782   if (!flag_openmp)  /* flag_openmp_simd  */
22783     {
22784       c_parser_skip_to_pragma_eol (parser, false);
22785       return NULL_TREE;
22786     }
22787 
22788   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
22789   if (cclauses)
22790     {
22791       omp_split_clauses (loc, OMP_TASKLOOP, mask, clauses, cclauses);
22792       clauses = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
22793     }
22794 
22795   clauses = c_finish_taskloop_clauses (clauses);
22796   block = c_begin_compound_stmt (true);
22797   ret = c_parser_omp_for_loop (loc, parser, OMP_TASKLOOP, clauses, NULL, if_p);
22798   block = c_end_compound_stmt (loc, block, true);
22799   add_stmt (block);
22800 
22801   return ret;
22802 }
22803 
22804 /* OpenMP 5.1
22805    #pragma omp nothing new-line  */
22806 
22807 static void
c_parser_omp_nothing(c_parser * parser)22808 c_parser_omp_nothing (c_parser *parser)
22809 {
22810   c_parser_consume_pragma (parser);
22811   c_parser_skip_to_pragma_eol (parser);
22812 }
22813 
22814 /* OpenMP 5.1
22815    #pragma omp error clauses[optseq] new-line  */
22816 
22817 static bool
c_parser_omp_error(c_parser * parser,enum pragma_context context)22818 c_parser_omp_error (c_parser *parser, enum pragma_context context)
22819 {
22820   int at_compilation = -1;
22821   int severity_fatal = -1;
22822   tree message = NULL_TREE;
22823   bool first = true;
22824   bool bad = false;
22825   location_t loc = c_parser_peek_token (parser)->location;
22826 
22827   c_parser_consume_pragma (parser);
22828 
22829   while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
22830     {
22831       if (!first
22832 	  && c_parser_next_token_is (parser, CPP_COMMA)
22833 	  && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
22834 	c_parser_consume_token (parser);
22835 
22836       first = false;
22837 
22838       if (!c_parser_next_token_is (parser, CPP_NAME))
22839 	break;
22840 
22841       const char *p
22842 	= IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22843       location_t cloc = c_parser_peek_token (parser)->location;
22844       static const char *args[] = {
22845 	"execution", "compilation", "warning", "fatal"
22846       };
22847       int *v = NULL;
22848       int idx = 0, n = -1;
22849       tree m = NULL_TREE;
22850 
22851       if (!strcmp (p, "at"))
22852 	v = &at_compilation;
22853       else if (!strcmp (p, "severity"))
22854 	{
22855 	  v = &severity_fatal;
22856 	  idx += 2;
22857 	}
22858       else if (strcmp (p, "message"))
22859 	{
22860 	  error_at (cloc,
22861 		    "expected %<at%>, %<severity%> or %<message%> clause");
22862 	  c_parser_skip_to_pragma_eol (parser, false);
22863 	  return false;
22864 	}
22865 
22866       c_parser_consume_token (parser);
22867 
22868       matching_parens parens;
22869       if (parens.require_open (parser))
22870 	{
22871 	  if (v == NULL)
22872 	    {
22873 	      location_t expr_loc = c_parser_peek_token (parser)->location;
22874 	      c_expr expr = c_parser_expr_no_commas (parser, NULL);
22875 	      expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
22876 	      m = convert (const_string_type_node, expr.value);
22877 	      m = c_fully_fold (m, false, NULL);
22878 	    }
22879 	  else
22880 	    {
22881 	      if (c_parser_next_token_is (parser, CPP_NAME))
22882 		{
22883 		  tree val = c_parser_peek_token (parser)->value;
22884 		  const char *q = IDENTIFIER_POINTER (val);
22885 
22886 		  if (!strcmp (q, args[idx]))
22887 		    n = 0;
22888 		  else if (!strcmp (q, args[idx + 1]))
22889 		    n = 1;
22890 		}
22891 	      if (n == -1)
22892 		{
22893 		  error_at (c_parser_peek_token (parser)->location,
22894 			    "expected %qs or %qs", args[idx], args[idx + 1]);
22895 		  bad = true;
22896 		  switch (c_parser_peek_token (parser)->type)
22897 		    {
22898 		    case CPP_EOF:
22899 		    case CPP_PRAGMA_EOL:
22900 		    case CPP_CLOSE_PAREN:
22901 		      break;
22902 		    default:
22903 		      if (c_parser_peek_2nd_token (parser)->type
22904 			  == CPP_CLOSE_PAREN)
22905 			c_parser_consume_token (parser);
22906 		      break;
22907 		    }
22908 		}
22909 	      else
22910 		c_parser_consume_token (parser);
22911 	    }
22912 
22913 	  parens.skip_until_found_close (parser);
22914 
22915 	  if (v == NULL)
22916 	    {
22917 	      if (message)
22918 		{
22919 		  error_at (cloc, "too many %qs clauses", p);
22920 		  bad = true;
22921 		}
22922 	      else
22923 		message = m;
22924 	    }
22925 	  else if (n != -1)
22926 	    {
22927 	      if (*v != -1)
22928 		{
22929 		  error_at (cloc, "too many %qs clauses", p);
22930 		  bad = true;
22931 		}
22932 	      else
22933 		*v = n;
22934 	    }
22935 	}
22936       else
22937 	bad = true;
22938     }
22939   c_parser_skip_to_pragma_eol (parser);
22940   if (bad)
22941     return true;
22942 
22943   if (at_compilation == -1)
22944     at_compilation = 1;
22945   if (severity_fatal == -1)
22946     severity_fatal = 1;
22947   if (!at_compilation)
22948     {
22949       if (context != pragma_compound)
22950 	{
22951 	  error_at (loc, "%<#pragma omp error%> with %<at(execution)%> clause "
22952 			 "may only be used in compound statements");
22953 	  return true;
22954 	}
22955       tree fndecl
22956 	= builtin_decl_explicit (severity_fatal ? BUILT_IN_GOMP_ERROR
22957 						: BUILT_IN_GOMP_WARNING);
22958       if (!message)
22959 	message = build_zero_cst (const_string_type_node);
22960       tree stmt = build_call_expr_loc (loc, fndecl, 2, message,
22961 				       build_all_ones_cst (size_type_node));
22962       add_stmt (stmt);
22963       return true;
22964     }
22965   const char *msg = NULL;
22966   if (message)
22967     {
22968       msg = c_getstr (message);
22969       if (msg == NULL)
22970 	msg = _("<message unknown at compile time>");
22971     }
22972   if (msg)
22973     emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
22974 		     "%<pragma omp error%> encountered: %s", msg);
22975   else
22976     emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
22977 		     "%<pragma omp error%> encountered");
22978   return false;
22979 }
22980 
22981 /* Main entry point to parsing most OpenMP pragmas.  */
22982 
22983 static void
c_parser_omp_construct(c_parser * parser,bool * if_p)22984 c_parser_omp_construct (c_parser *parser, bool *if_p)
22985 {
22986   enum pragma_kind p_kind;
22987   location_t loc;
22988   tree stmt;
22989   char p_name[sizeof "#pragma omp teams distribute parallel for simd"];
22990   omp_clause_mask mask (0);
22991 
22992   loc = c_parser_peek_token (parser)->location;
22993   p_kind = c_parser_peek_token (parser)->pragma_kind;
22994   c_parser_consume_pragma (parser);
22995 
22996   switch (p_kind)
22997     {
22998     case PRAGMA_OACC_ATOMIC:
22999       c_parser_omp_atomic (loc, parser, true);
23000       return;
23001     case PRAGMA_OACC_CACHE:
23002       strcpy (p_name, "#pragma acc");
23003       stmt = c_parser_oacc_cache (loc, parser);
23004       break;
23005     case PRAGMA_OACC_DATA:
23006       stmt = c_parser_oacc_data (loc, parser, if_p);
23007       break;
23008     case PRAGMA_OACC_HOST_DATA:
23009       stmt = c_parser_oacc_host_data (loc, parser, if_p);
23010       break;
23011     case PRAGMA_OACC_KERNELS:
23012     case PRAGMA_OACC_PARALLEL:
23013     case PRAGMA_OACC_SERIAL:
23014       strcpy (p_name, "#pragma acc");
23015       stmt = c_parser_oacc_compute (loc, parser, p_kind, p_name, if_p);
23016       break;
23017     case PRAGMA_OACC_LOOP:
23018       strcpy (p_name, "#pragma acc");
23019       stmt = c_parser_oacc_loop (loc, parser, p_name, mask, NULL, if_p);
23020       break;
23021     case PRAGMA_OACC_WAIT:
23022       strcpy (p_name, "#pragma wait");
23023       stmt = c_parser_oacc_wait (loc, parser, p_name);
23024       break;
23025     case PRAGMA_OMP_ALLOCATE:
23026       c_parser_omp_allocate (loc, parser);
23027       return;
23028     case PRAGMA_OMP_ATOMIC:
23029       c_parser_omp_atomic (loc, parser, false);
23030       return;
23031     case PRAGMA_OMP_CRITICAL:
23032       stmt = c_parser_omp_critical (loc, parser, if_p);
23033       break;
23034     case PRAGMA_OMP_DISTRIBUTE:
23035       strcpy (p_name, "#pragma omp");
23036       stmt = c_parser_omp_distribute (loc, parser, p_name, mask, NULL, if_p);
23037       break;
23038     case PRAGMA_OMP_FOR:
23039       strcpy (p_name, "#pragma omp");
23040       stmt = c_parser_omp_for (loc, parser, p_name, mask, NULL, if_p);
23041       break;
23042     case PRAGMA_OMP_LOOP:
23043       strcpy (p_name, "#pragma omp");
23044       stmt = c_parser_omp_loop (loc, parser, p_name, mask, NULL, if_p);
23045       break;
23046     case PRAGMA_OMP_MASKED:
23047       strcpy (p_name, "#pragma omp");
23048       stmt = c_parser_omp_masked (loc, parser, p_name, mask, NULL, if_p);
23049       break;
23050     case PRAGMA_OMP_MASTER:
23051       strcpy (p_name, "#pragma omp");
23052       stmt = c_parser_omp_master (loc, parser, p_name, mask, NULL, if_p);
23053       break;
23054     case PRAGMA_OMP_PARALLEL:
23055       strcpy (p_name, "#pragma omp");
23056       stmt = c_parser_omp_parallel (loc, parser, p_name, mask, NULL, if_p);
23057       break;
23058     case PRAGMA_OMP_SCOPE:
23059       stmt = c_parser_omp_scope (loc, parser, if_p);
23060       break;
23061     case PRAGMA_OMP_SECTIONS:
23062       strcpy (p_name, "#pragma omp");
23063       stmt = c_parser_omp_sections (loc, parser, p_name, mask, NULL);
23064       break;
23065     case PRAGMA_OMP_SIMD:
23066       strcpy (p_name, "#pragma omp");
23067       stmt = c_parser_omp_simd (loc, parser, p_name, mask, NULL, if_p);
23068       break;
23069     case PRAGMA_OMP_SINGLE:
23070       stmt = c_parser_omp_single (loc, parser, if_p);
23071       break;
23072     case PRAGMA_OMP_TASK:
23073       stmt = c_parser_omp_task (loc, parser, if_p);
23074       break;
23075     case PRAGMA_OMP_TASKGROUP:
23076       stmt = c_parser_omp_taskgroup (loc, parser, if_p);
23077       break;
23078     case PRAGMA_OMP_TASKLOOP:
23079       strcpy (p_name, "#pragma omp");
23080       stmt = c_parser_omp_taskloop (loc, parser, p_name, mask, NULL, if_p);
23081       break;
23082     case PRAGMA_OMP_TEAMS:
23083       strcpy (p_name, "#pragma omp");
23084       stmt = c_parser_omp_teams (loc, parser, p_name, mask, NULL, if_p);
23085       break;
23086     default:
23087       gcc_unreachable ();
23088     }
23089 
23090   if (stmt && stmt != error_mark_node)
23091     gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION);
23092 }
23093 
23094 
23095 /* OpenMP 2.5:
23096    # pragma omp threadprivate (variable-list) */
23097 
23098 static void
c_parser_omp_threadprivate(c_parser * parser)23099 c_parser_omp_threadprivate (c_parser *parser)
23100 {
23101   tree vars, t;
23102   location_t loc;
23103 
23104   c_parser_consume_pragma (parser);
23105   loc = c_parser_peek_token (parser)->location;
23106   vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
23107 
23108   /* Mark every variable in VARS to be assigned thread local storage.  */
23109   for (t = vars; t; t = TREE_CHAIN (t))
23110     {
23111       tree v = TREE_PURPOSE (t);
23112 
23113       /* FIXME diagnostics: Ideally we should keep individual
23114 	 locations for all the variables in the var list to make the
23115 	 following errors more precise.  Perhaps
23116 	 c_parser_omp_var_list_parens() should construct a list of
23117 	 locations to go along with the var list.  */
23118 
23119       /* If V had already been marked threadprivate, it doesn't matter
23120 	 whether it had been used prior to this point.  */
23121       if (!VAR_P (v))
23122 	error_at (loc, "%qD is not a variable", v);
23123       else if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v))
23124 	error_at (loc, "%qE declared %<threadprivate%> after first use", v);
23125       else if (! is_global_var (v))
23126 	error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v);
23127       else if (TREE_TYPE (v) == error_mark_node)
23128 	;
23129       else if (! COMPLETE_TYPE_P (TREE_TYPE (v)))
23130 	error_at (loc, "%<threadprivate%> %qE has incomplete type", v);
23131       else
23132 	{
23133 	  if (! DECL_THREAD_LOCAL_P (v))
23134 	    {
23135 	      set_decl_tls_model (v, decl_default_tls_model (v));
23136 	      /* If rtl has been already set for this var, call
23137 		 make_decl_rtl once again, so that encode_section_info
23138 		 has a chance to look at the new decl flags.  */
23139 	      if (DECL_RTL_SET_P (v))
23140 		make_decl_rtl (v);
23141 	    }
23142 	  C_DECL_THREADPRIVATE_P (v) = 1;
23143 	}
23144     }
23145 
23146   c_parser_skip_to_pragma_eol (parser);
23147 }
23148 
23149 /* Parse a transaction attribute (GCC Extension).
23150 
23151    transaction-attribute:
23152      gnu-attributes
23153      attribute-specifier
23154 */
23155 
23156 static tree
c_parser_transaction_attributes(c_parser * parser)23157 c_parser_transaction_attributes (c_parser *parser)
23158 {
23159   if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
23160     return c_parser_gnu_attributes (parser);
23161 
23162   if (!c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
23163     return NULL_TREE;
23164   return c_parser_std_attribute_specifier (parser, true);
23165 }
23166 
23167 /* Parse a __transaction_atomic or __transaction_relaxed statement
23168    (GCC Extension).
23169 
23170    transaction-statement:
23171      __transaction_atomic transaction-attribute[opt] compound-statement
23172      __transaction_relaxed compound-statement
23173 
23174    Note that the only valid attribute is: "outer".
23175 */
23176 
23177 static tree
c_parser_transaction(c_parser * parser,enum rid keyword)23178 c_parser_transaction (c_parser *parser, enum rid keyword)
23179 {
23180   unsigned int old_in = parser->in_transaction;
23181   unsigned int this_in = 1, new_in;
23182   location_t loc = c_parser_peek_token (parser)->location;
23183   tree stmt, attrs;
23184 
23185   gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
23186       || keyword == RID_TRANSACTION_RELAXED)
23187       && c_parser_next_token_is_keyword (parser, keyword));
23188   c_parser_consume_token (parser);
23189 
23190   if (keyword == RID_TRANSACTION_RELAXED)
23191     this_in |= TM_STMT_ATTR_RELAXED;
23192   else
23193     {
23194       attrs = c_parser_transaction_attributes (parser);
23195       if (attrs)
23196 	this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
23197     }
23198 
23199   /* Keep track if we're in the lexical scope of an outer transaction.  */
23200   new_in = this_in | (old_in & TM_STMT_ATTR_OUTER);
23201 
23202   parser->in_transaction = new_in;
23203   stmt = c_parser_compound_statement (parser);
23204   parser->in_transaction = old_in;
23205 
23206   if (flag_tm)
23207     stmt = c_finish_transaction (loc, stmt, this_in);
23208   else
23209     error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
23210 	"%<__transaction_atomic%> without transactional memory support enabled"
23211 	: "%<__transaction_relaxed %> "
23212 	"without transactional memory support enabled"));
23213 
23214   return stmt;
23215 }
23216 
23217 /* Parse a __transaction_atomic or __transaction_relaxed expression
23218    (GCC Extension).
23219 
23220    transaction-expression:
23221      __transaction_atomic ( expression )
23222      __transaction_relaxed ( expression )
23223 */
23224 
23225 static struct c_expr
c_parser_transaction_expression(c_parser * parser,enum rid keyword)23226 c_parser_transaction_expression (c_parser *parser, enum rid keyword)
23227 {
23228   struct c_expr ret;
23229   unsigned int old_in = parser->in_transaction;
23230   unsigned int this_in = 1;
23231   location_t loc = c_parser_peek_token (parser)->location;
23232   tree attrs;
23233 
23234   gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
23235       || keyword == RID_TRANSACTION_RELAXED)
23236       && c_parser_next_token_is_keyword (parser, keyword));
23237   c_parser_consume_token (parser);
23238 
23239   if (keyword == RID_TRANSACTION_RELAXED)
23240     this_in |= TM_STMT_ATTR_RELAXED;
23241   else
23242     {
23243       attrs = c_parser_transaction_attributes (parser);
23244       if (attrs)
23245 	this_in |= parse_tm_stmt_attr (attrs, 0);
23246     }
23247 
23248   parser->in_transaction = this_in;
23249   matching_parens parens;
23250   if (parens.require_open (parser))
23251     {
23252       tree expr = c_parser_expression (parser).value;
23253       ret.original_type = TREE_TYPE (expr);
23254       ret.value = build1 (TRANSACTION_EXPR, ret.original_type, expr);
23255       if (this_in & TM_STMT_ATTR_RELAXED)
23256 	TRANSACTION_EXPR_RELAXED (ret.value) = 1;
23257       SET_EXPR_LOCATION (ret.value, loc);
23258       ret.original_code = TRANSACTION_EXPR;
23259       if (!parens.require_close (parser))
23260 	{
23261 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
23262 	  goto error;
23263 	}
23264     }
23265   else
23266     {
23267      error:
23268       ret.set_error ();
23269       ret.original_code = ERROR_MARK;
23270       ret.original_type = NULL;
23271     }
23272   parser->in_transaction = old_in;
23273 
23274   if (!flag_tm)
23275     error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
23276 	"%<__transaction_atomic%> without transactional memory support enabled"
23277 	: "%<__transaction_relaxed %> "
23278 	"without transactional memory support enabled"));
23279 
23280   set_c_expr_source_range (&ret, loc, loc);
23281 
23282   return ret;
23283 }
23284 
23285 /* Parse a __transaction_cancel statement (GCC Extension).
23286 
23287    transaction-cancel-statement:
23288      __transaction_cancel transaction-attribute[opt] ;
23289 
23290    Note that the only valid attribute is "outer".
23291 */
23292 
23293 static tree
c_parser_transaction_cancel(c_parser * parser)23294 c_parser_transaction_cancel (c_parser *parser)
23295 {
23296   location_t loc = c_parser_peek_token (parser)->location;
23297   tree attrs;
23298   bool is_outer = false;
23299 
23300   gcc_assert (c_parser_next_token_is_keyword (parser, RID_TRANSACTION_CANCEL));
23301   c_parser_consume_token (parser);
23302 
23303   attrs = c_parser_transaction_attributes (parser);
23304   if (attrs)
23305     is_outer = (parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER) != 0);
23306 
23307   if (!flag_tm)
23308     {
23309       error_at (loc, "%<__transaction_cancel%> without "
23310 		"transactional memory support enabled");
23311       goto ret_error;
23312     }
23313   else if (parser->in_transaction & TM_STMT_ATTR_RELAXED)
23314     {
23315       error_at (loc, "%<__transaction_cancel%> within a "
23316 		"%<__transaction_relaxed%>");
23317       goto ret_error;
23318     }
23319   else if (is_outer)
23320     {
23321       if ((parser->in_transaction & TM_STMT_ATTR_OUTER) == 0
23322 	  && !is_tm_may_cancel_outer (current_function_decl))
23323 	{
23324 	  error_at (loc, "outer %<__transaction_cancel%> not "
23325 		    "within outer %<__transaction_atomic%> or "
23326 		    "a %<transaction_may_cancel_outer%> function");
23327 	  goto ret_error;
23328 	}
23329     }
23330   else if (parser->in_transaction == 0)
23331     {
23332       error_at (loc, "%<__transaction_cancel%> not within "
23333 		"%<__transaction_atomic%>");
23334       goto ret_error;
23335     }
23336 
23337   return add_stmt (build_tm_abort_call (loc, is_outer));
23338 
23339  ret_error:
23340   return build1 (NOP_EXPR, void_type_node, error_mark_node);
23341 }
23342 
23343 /* Parse a single source file.  */
23344 
23345 void
c_parse_file(void)23346 c_parse_file (void)
23347 {
23348   /* Use local storage to begin.  If the first token is a pragma, parse it.
23349      If it is #pragma GCC pch_preprocess, then this will load a PCH file
23350      which will cause garbage collection.  */
23351   c_parser tparser;
23352 
23353   memset (&tparser, 0, sizeof tparser);
23354   tparser.translate_strings_p = true;
23355   tparser.tokens = &tparser.tokens_buf[0];
23356   the_parser = &tparser;
23357 
23358   if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS)
23359     c_parser_pragma_pch_preprocess (&tparser);
23360   else
23361     c_common_no_more_pch ();
23362 
23363   the_parser = ggc_alloc<c_parser> ();
23364   *the_parser = tparser;
23365   if (tparser.tokens == &tparser.tokens_buf[0])
23366     the_parser->tokens = &the_parser->tokens_buf[0];
23367 
23368   /* Initialize EH, if we've been told to do so.  */
23369   if (flag_exceptions)
23370     using_eh_for_cleanups ();
23371 
23372   c_parser_translation_unit (the_parser);
23373   the_parser = NULL;
23374 }
23375 
23376 /* Parse the body of a function declaration marked with "__RTL".
23377 
23378    The RTL parser works on the level of characters read from a
23379    FILE *, whereas c_parser works at the level of tokens.
23380    Square this circle by consuming all of the tokens up to and
23381    including the closing brace, recording the start/end of the RTL
23382    fragment, and reopening the file and re-reading the relevant
23383    lines within the RTL parser.
23384 
23385    This requires the opening and closing braces of the C function
23386    to be on separate lines from the RTL they wrap.
23387 
23388    Take ownership of START_WITH_PASS, if non-NULL.  */
23389 
23390 location_t
c_parser_parse_rtl_body(c_parser * parser,char * start_with_pass)23391 c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass)
23392 {
23393   if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
23394     {
23395       free (start_with_pass);
23396       return c_parser_peek_token (parser)->location;
23397     }
23398 
23399   location_t start_loc = c_parser_peek_token (parser)->location;
23400 
23401   /* Consume all tokens, up to the closing brace, handling
23402      matching pairs of braces in the rtl dump.  */
23403   int num_open_braces = 1;
23404   while (1)
23405     {
23406       switch (c_parser_peek_token (parser)->type)
23407 	{
23408 	case CPP_OPEN_BRACE:
23409 	  num_open_braces++;
23410 	  break;
23411 	case CPP_CLOSE_BRACE:
23412 	  if (--num_open_braces == 0)
23413 	    goto found_closing_brace;
23414 	  break;
23415 	case CPP_EOF:
23416 	  error_at (start_loc, "no closing brace");
23417 	  free (start_with_pass);
23418 	  return c_parser_peek_token (parser)->location;
23419 	default:
23420 	  break;
23421 	}
23422       c_parser_consume_token (parser);
23423     }
23424 
23425  found_closing_brace:
23426   /* At the closing brace; record its location.  */
23427   location_t end_loc = c_parser_peek_token (parser)->location;
23428 
23429   /* Consume the closing brace.  */
23430   c_parser_consume_token (parser);
23431 
23432   /* Invoke the RTL parser.  */
23433   if (!read_rtl_function_body_from_file_range (start_loc, end_loc))
23434     {
23435       free (start_with_pass);
23436       return end_loc;
23437     }
23438 
23439  /*  Run the backend on the cfun created above, transferring ownership of
23440      START_WITH_PASS.  */
23441   run_rtl_passes (start_with_pass);
23442   return end_loc;
23443 }
23444 
23445 #include "gt-c-c-parser.h"
23446