1 /* Parser for C and Objective-C.
2    Copyright (C) 1987-2021 Free Software Foundation, Inc.
3 
4    Parser actions based on the old Bison parser; structure somewhat
5    influenced by and fragments based on the C++ parser.
6 
7 This file is part of GCC.
8 
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
13 
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3.  If not see
21 <http://www.gnu.org/licenses/>.  */
22 
23 /* TODO:
24 
25    Make sure all relevant comments, and all relevant code from all
26    actions, brought over from old parser.  Verify exact correspondence
27    of syntax accepted.
28 
29    Add testcases covering every input symbol in every state in old and
30    new parsers.
31 
32    Include full syntax for GNU C, including erroneous cases accepted
33    with error messages, in syntax productions in comments.
34 
35    Make more diagnostics in the front end generally take an explicit
36    location rather than implicitly using input_location.  */
37 
38 #include "config.h"
39 #define INCLUDE_UNIQUE_PTR
40 #include "system.h"
41 #include "coretypes.h"
42 #include "target.h"
43 #include "function.h"
44 #include "c-tree.h"
45 #include "timevar.h"
46 #include "stringpool.h"
47 #include "cgraph.h"
48 #include "attribs.h"
49 #include "stor-layout.h"
50 #include "varasm.h"
51 #include "trans-mem.h"
52 #include "c-family/c-pragma.h"
53 #include "c-lang.h"
54 #include "c-family/c-objc.h"
55 #include "plugin.h"
56 #include "omp-general.h"
57 #include "omp-offload.h"
58 #include "builtins.h"
59 #include "gomp-constants.h"
60 #include "c-family/c-indentation.h"
61 #include "gimple-expr.h"
62 #include "context.h"
63 #include "gcc-rich-location.h"
64 #include "c-parser.h"
65 #include "gimple-parser.h"
66 #include "read-rtl-function.h"
67 #include "run-rtl-passes.h"
68 #include "intl.h"
69 #include "c-family/name-hint.h"
70 #include "tree-iterator.h"
71 #include "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
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)1069   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)1079   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       return "";
1136     case CPP_CLOSE_PAREN:
1137       return "(";
1138     case CPP_CLOSE_BRACE:
1139       return "{";
1140     }
1141 }
1142 
1143 /* If the next token is of the indicated TYPE, consume it.  Otherwise,
1144    issue the error MSGID.  If MSGID is NULL then a message has already
1145    been produced and no message will be produced this time.  Returns
1146    true if found, false otherwise.
1147 
1148    If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1149    within any error as the location of an "opening" token matching
1150    the close token TYPE (e.g. the location of the '(' when TYPE is
1151    CPP_CLOSE_PAREN).
1152 
1153    If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly
1154    one type (e.g. "expected %<)%>") and thus it may be reasonable to
1155    attempt to generate a fix-it hint for the problem.
1156    Otherwise msgid describes multiple token types (e.g.
1157    "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to
1158    generate a fix-it hint.  */
1159 
1160 bool
c_parser_require(c_parser * parser,enum cpp_ttype type,const char * msgid,location_t matching_location,bool type_is_unique)1161 c_parser_require (c_parser *parser,
1162 		  enum cpp_ttype type,
1163 		  const char *msgid,
1164 		  location_t matching_location,
1165 		  bool type_is_unique)
1166 {
1167   if (c_parser_next_token_is (parser, type))
1168     {
1169       c_parser_consume_token (parser);
1170       return true;
1171     }
1172   else
1173     {
1174       location_t next_token_loc = c_parser_peek_token (parser)->location;
1175       gcc_rich_location richloc (next_token_loc);
1176 
1177       /* Potentially supply a fix-it hint, suggesting to add the
1178 	 missing token immediately after the *previous* token.
1179 	 This may move the primary location within richloc.  */
1180       if (!parser->error && type_is_unique)
1181 	maybe_suggest_missing_token_insertion (&richloc, type,
1182 					       parser->last_token_location);
1183 
1184       /* If matching_location != UNKNOWN_LOCATION, highlight it.
1185 	 Attempt to consolidate diagnostics by printing it as a
1186 	 secondary range within the main diagnostic.  */
1187       bool added_matching_location = false;
1188       if (matching_location != UNKNOWN_LOCATION)
1189 	added_matching_location
1190 	  = richloc.add_location_if_nearby (matching_location);
1191 
1192       if (c_parser_error_richloc (parser, msgid, &richloc))
1193 	/* If we weren't able to consolidate matching_location, then
1194 	   print it as a secondary diagnostic.  */
1195 	if (matching_location != UNKNOWN_LOCATION && !added_matching_location)
1196 	  inform (matching_location, "to match this %qs",
1197 		  get_matching_symbol (type));
1198 
1199       return false;
1200     }
1201 }
1202 
1203 /* If the next token is the indicated keyword, consume it.  Otherwise,
1204    issue the error MSGID.  Returns true if found, false otherwise.  */
1205 
1206 static bool
c_parser_require_keyword(c_parser * parser,enum rid keyword,const char * msgid)1207 c_parser_require_keyword (c_parser *parser,
1208 			  enum rid keyword,
1209 			  const char *msgid)
1210 {
1211   if (c_parser_next_token_is_keyword (parser, keyword))
1212     {
1213       c_parser_consume_token (parser);
1214       return true;
1215     }
1216   else
1217     {
1218       c_parser_error (parser, msgid);
1219       return false;
1220     }
1221 }
1222 
1223 /* Like c_parser_require, except that tokens will be skipped until the
1224    desired token is found.  An error message is still produced if the
1225    next token is not as expected.  If MSGID is NULL then a message has
1226    already been produced and no message will be produced this
1227    time.
1228 
1229    If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1230    within any error as the location of an "opening" token matching
1231    the close token TYPE (e.g. the location of the '(' when TYPE is
1232    CPP_CLOSE_PAREN).  */
1233 
1234 void
c_parser_skip_until_found(c_parser * parser,enum cpp_ttype type,const char * msgid,location_t matching_location)1235 c_parser_skip_until_found (c_parser *parser,
1236 			   enum cpp_ttype type,
1237 			   const char *msgid,
1238 			   location_t matching_location)
1239 {
1240   unsigned nesting_depth = 0;
1241 
1242   if (c_parser_require (parser, type, msgid, matching_location))
1243     return;
1244 
1245   /* Skip tokens until the desired token is found.  */
1246   while (true)
1247     {
1248       /* Peek at the next token.  */
1249       c_token *token = c_parser_peek_token (parser);
1250       /* If we've reached the token we want, consume it and stop.  */
1251       if (token->type == type && !nesting_depth)
1252 	{
1253 	  c_parser_consume_token (parser);
1254 	  break;
1255 	}
1256 
1257       /* If we've run out of tokens, stop.  */
1258       if (token->type == CPP_EOF)
1259 	return;
1260       if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1261 	return;
1262       if (token->type == CPP_OPEN_BRACE
1263 	  || token->type == CPP_OPEN_PAREN
1264 	  || token->type == CPP_OPEN_SQUARE)
1265 	++nesting_depth;
1266       else if (token->type == CPP_CLOSE_BRACE
1267 	       || token->type == CPP_CLOSE_PAREN
1268 	       || token->type == CPP_CLOSE_SQUARE)
1269 	{
1270 	  if (nesting_depth-- == 0)
1271 	    break;
1272 	}
1273       /* Consume this token.  */
1274       c_parser_consume_token (parser);
1275     }
1276   parser->error = false;
1277 }
1278 
1279 /* Skip tokens until the end of a parameter is found, but do not
1280    consume the comma, semicolon or closing delimiter.  */
1281 
1282 static void
c_parser_skip_to_end_of_parameter(c_parser * parser)1283 c_parser_skip_to_end_of_parameter (c_parser *parser)
1284 {
1285   unsigned nesting_depth = 0;
1286 
1287   while (true)
1288     {
1289       c_token *token = c_parser_peek_token (parser);
1290       if ((token->type == CPP_COMMA || token->type == CPP_SEMICOLON)
1291 	  && !nesting_depth)
1292 	break;
1293       /* If we've run out of tokens, stop.  */
1294       if (token->type == CPP_EOF)
1295 	return;
1296       if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1297 	return;
1298       if (token->type == CPP_OPEN_BRACE
1299 	  || token->type == CPP_OPEN_PAREN
1300 	  || token->type == CPP_OPEN_SQUARE)
1301 	++nesting_depth;
1302       else if (token->type == CPP_CLOSE_BRACE
1303 	       || token->type == CPP_CLOSE_PAREN
1304 	       || token->type == CPP_CLOSE_SQUARE)
1305 	{
1306 	  if (nesting_depth-- == 0)
1307 	    break;
1308 	}
1309       /* Consume this token.  */
1310       c_parser_consume_token (parser);
1311     }
1312   parser->error = false;
1313 }
1314 
1315 /* Expect to be at the end of the pragma directive and consume an
1316    end of line marker.  */
1317 
1318 static void
1319 c_parser_skip_to_pragma_eol (c_parser *parser, bool error_if_not_eol = true)
1320 {
1321   gcc_assert (parser->in_pragma);
1322   parser->in_pragma = false;
1323 
1324   if (error_if_not_eol && c_parser_peek_token (parser)->type != CPP_PRAGMA_EOL)
1325     c_parser_error (parser, "expected end of line");
1326 
1327   cpp_ttype token_type;
1328   do
1329     {
1330       c_token *token = c_parser_peek_token (parser);
1331       token_type = token->type;
1332       if (token_type == CPP_EOF)
1333 	break;
1334       c_parser_consume_token (parser);
1335     }
1336   while (token_type != CPP_PRAGMA_EOL);
1337 
1338   parser->error = false;
1339 }
1340 
1341 /* Skip tokens until we have consumed an entire block, or until we
1342    have consumed a non-nested ';'.  */
1343 
1344 static void
c_parser_skip_to_end_of_block_or_statement(c_parser * parser)1345 c_parser_skip_to_end_of_block_or_statement (c_parser *parser)
1346 {
1347   unsigned nesting_depth = 0;
1348   bool save_error = parser->error;
1349 
1350   while (true)
1351     {
1352       c_token *token;
1353 
1354       /* Peek at the next token.  */
1355       token = c_parser_peek_token (parser);
1356 
1357       switch (token->type)
1358 	{
1359 	case CPP_EOF:
1360 	  return;
1361 
1362 	case CPP_PRAGMA_EOL:
1363 	  if (parser->in_pragma)
1364 	    return;
1365 	  break;
1366 
1367 	case CPP_SEMICOLON:
1368 	  /* If the next token is a ';', we have reached the
1369 	     end of the statement.  */
1370 	  if (!nesting_depth)
1371 	    {
1372 	      /* Consume the ';'.  */
1373 	      c_parser_consume_token (parser);
1374 	      goto finished;
1375 	    }
1376 	  break;
1377 
1378 	case CPP_CLOSE_BRACE:
1379 	  /* If the next token is a non-nested '}', then we have
1380 	     reached the end of the current block.  */
1381 	  if (nesting_depth == 0 || --nesting_depth == 0)
1382 	    {
1383 	      c_parser_consume_token (parser);
1384 	      goto finished;
1385 	    }
1386 	  break;
1387 
1388 	case CPP_OPEN_BRACE:
1389 	  /* If it the next token is a '{', then we are entering a new
1390 	     block.  Consume the entire block.  */
1391 	  ++nesting_depth;
1392 	  break;
1393 
1394 	case CPP_PRAGMA:
1395 	  /* If we see a pragma, consume the whole thing at once.  We
1396 	     have some safeguards against consuming pragmas willy-nilly.
1397 	     Normally, we'd expect to be here with parser->error set,
1398 	     which disables these safeguards.  But it's possible to get
1399 	     here for secondary error recovery, after parser->error has
1400 	     been cleared.  */
1401 	  c_parser_consume_pragma (parser);
1402 	  c_parser_skip_to_pragma_eol (parser);
1403 	  parser->error = save_error;
1404 	  continue;
1405 
1406 	default:
1407 	  break;
1408 	}
1409 
1410       c_parser_consume_token (parser);
1411     }
1412 
1413  finished:
1414   parser->error = false;
1415 }
1416 
1417 /* CPP's options (initialized by c-opts.c).  */
1418 extern cpp_options *cpp_opts;
1419 
1420 /* Save the warning flags which are controlled by __extension__.  */
1421 
1422 static inline int
disable_extension_diagnostics(void)1423 disable_extension_diagnostics (void)
1424 {
1425   int ret = (pedantic
1426 	     | (warn_pointer_arith << 1)
1427 	     | (warn_traditional << 2)
1428 	     | (flag_iso << 3)
1429 	     | (warn_long_long << 4)
1430 	     | (warn_cxx_compat << 5)
1431 	     | (warn_overlength_strings << 6)
1432 	     /* warn_c90_c99_compat has three states: -1/0/1, so we must
1433 		play tricks to properly restore it.  */
1434 	     | ((warn_c90_c99_compat == 1) << 7)
1435 	     | ((warn_c90_c99_compat == -1) << 8)
1436 	     /* Similarly for warn_c99_c11_compat.  */
1437 	     | ((warn_c99_c11_compat == 1) << 9)
1438 	     | ((warn_c99_c11_compat == -1) << 10)
1439 	     /* Similarly for warn_c11_c2x_compat.  */
1440 	     | ((warn_c11_c2x_compat == 1) << 11)
1441 	     | ((warn_c11_c2x_compat == -1) << 12)
1442 	     );
1443   cpp_opts->cpp_pedantic = pedantic = 0;
1444   warn_pointer_arith = 0;
1445   cpp_opts->cpp_warn_traditional = warn_traditional = 0;
1446   flag_iso = 0;
1447   cpp_opts->cpp_warn_long_long = warn_long_long = 0;
1448   warn_cxx_compat = 0;
1449   warn_overlength_strings = 0;
1450   warn_c90_c99_compat = 0;
1451   warn_c99_c11_compat = 0;
1452   warn_c11_c2x_compat = 0;
1453   return ret;
1454 }
1455 
1456 /* Restore the warning flags which are controlled by __extension__.
1457    FLAGS is the return value from disable_extension_diagnostics.  */
1458 
1459 static inline void
restore_extension_diagnostics(int flags)1460 restore_extension_diagnostics (int flags)
1461 {
1462   cpp_opts->cpp_pedantic = pedantic = flags & 1;
1463   warn_pointer_arith = (flags >> 1) & 1;
1464   cpp_opts->cpp_warn_traditional = warn_traditional = (flags >> 2) & 1;
1465   flag_iso = (flags >> 3) & 1;
1466   cpp_opts->cpp_warn_long_long = warn_long_long = (flags >> 4) & 1;
1467   warn_cxx_compat = (flags >> 5) & 1;
1468   warn_overlength_strings = (flags >> 6) & 1;
1469   /* See above for why is this needed.  */
1470   warn_c90_c99_compat = (flags >> 7) & 1 ? 1 : ((flags >> 8) & 1 ? -1 : 0);
1471   warn_c99_c11_compat = (flags >> 9) & 1 ? 1 : ((flags >> 10) & 1 ? -1 : 0);
1472   warn_c11_c2x_compat = (flags >> 11) & 1 ? 1 : ((flags >> 12) & 1 ? -1 : 0);
1473 }
1474 
1475 /* Helper data structure for parsing #pragma acc routine.  */
1476 struct oacc_routine_data {
1477   bool error_seen; /* Set if error has been reported.  */
1478   bool fndecl_seen; /* Set if one fn decl/definition has been seen already.  */
1479   tree clauses;
1480   location_t loc;
1481 };
1482 
1483 /* Used for parsing objc foreach statements.  */
1484 static tree objc_foreach_break_label, objc_foreach_continue_label;
1485 
1486 static bool c_parser_nth_token_starts_std_attributes (c_parser *,
1487 						      unsigned int);
1488 static tree c_parser_std_attribute_specifier_sequence (c_parser *);
1489 static void c_parser_external_declaration (c_parser *);
1490 static void c_parser_asm_definition (c_parser *);
1491 static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
1492 					   bool, bool, tree *, vec<c_token>,
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 *);
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 
1581 enum pragma_context { pragma_external, pragma_struct, pragma_param,
1582 		      pragma_stmt, pragma_compound };
1583 static bool c_parser_pragma (c_parser *, enum pragma_context, bool *);
1584 static void c_parser_omp_cancellation_point (c_parser *, enum pragma_context);
1585 static bool c_parser_omp_target (c_parser *, enum pragma_context, bool *);
1586 static void c_parser_omp_end_declare_target (c_parser *);
1587 static void c_parser_omp_declare (c_parser *, enum pragma_context);
1588 static void c_parser_omp_requires (c_parser *);
1589 static bool c_parser_omp_ordered (c_parser *, enum pragma_context, bool *);
1590 static void c_parser_oacc_routine (c_parser *, enum pragma_context);
1591 
1592 /* These Objective-C parser functions are only ever called when
1593    compiling Objective-C.  */
1594 static void c_parser_objc_class_definition (c_parser *, tree);
1595 static void c_parser_objc_class_instance_variables (c_parser *);
1596 static void c_parser_objc_class_declaration (c_parser *);
1597 static void c_parser_objc_alias_declaration (c_parser *);
1598 static void c_parser_objc_protocol_definition (c_parser *, tree);
1599 static bool c_parser_objc_method_type (c_parser *);
1600 static void c_parser_objc_method_definition (c_parser *);
1601 static void c_parser_objc_methodprotolist (c_parser *);
1602 static void c_parser_objc_methodproto (c_parser *);
1603 static tree c_parser_objc_method_decl (c_parser *, bool, tree *, tree *);
1604 static tree c_parser_objc_type_name (c_parser *);
1605 static tree c_parser_objc_protocol_refs (c_parser *);
1606 static void c_parser_objc_try_catch_finally_statement (c_parser *);
1607 static void c_parser_objc_synchronized_statement (c_parser *);
1608 static tree c_parser_objc_selector (c_parser *);
1609 static tree c_parser_objc_selector_arg (c_parser *);
1610 static tree c_parser_objc_receiver (c_parser *);
1611 static tree c_parser_objc_message_args (c_parser *);
1612 static tree c_parser_objc_keywordexpr (c_parser *);
1613 static void c_parser_objc_at_property_declaration (c_parser *);
1614 static void c_parser_objc_at_synthesize_declaration (c_parser *);
1615 static void c_parser_objc_at_dynamic_declaration (c_parser *);
1616 static bool c_parser_objc_diagnose_bad_element_prefix
1617   (c_parser *, struct c_declspecs *);
1618 static location_t c_parser_parse_rtl_body (c_parser *, char *);
1619 
1620 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
1621 
1622    translation-unit:
1623      external-declarations
1624 
1625    external-declarations:
1626      external-declaration
1627      external-declarations external-declaration
1628 
1629    GNU extensions:
1630 
1631    translation-unit:
1632      empty
1633 */
1634 
1635 static void
c_parser_translation_unit(c_parser * parser)1636 c_parser_translation_unit (c_parser *parser)
1637 {
1638   if (c_parser_next_token_is (parser, CPP_EOF))
1639     {
1640       pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1641 	       "ISO C forbids an empty translation unit");
1642     }
1643   else
1644     {
1645       void *obstack_position = obstack_alloc (&parser_obstack, 0);
1646       mark_valid_location_for_stdc_pragma (false);
1647       do
1648 	{
1649 	  ggc_collect ();
1650 	  c_parser_external_declaration (parser);
1651 	  obstack_free (&parser_obstack, obstack_position);
1652 	}
1653       while (c_parser_next_token_is_not (parser, CPP_EOF));
1654     }
1655 
1656   unsigned int i;
1657   tree decl;
1658   FOR_EACH_VEC_ELT (incomplete_record_decls, i, decl)
1659     if (DECL_SIZE (decl) == NULL_TREE && TREE_TYPE (decl) != error_mark_node)
1660       error ("storage size of %q+D isn%'t known", decl);
1661 
1662   if (current_omp_declare_target_attribute)
1663     {
1664       if (!errorcount)
1665         error ("%<#pragma omp declare target%> without corresponding "
1666 	       "%<#pragma omp end declare target%>");
1667       current_omp_declare_target_attribute = 0;
1668     }
1669 }
1670 
1671 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
1672 
1673    external-declaration:
1674      function-definition
1675      declaration
1676 
1677    GNU extensions:
1678 
1679    external-declaration:
1680      asm-definition
1681      ;
1682      __extension__ external-declaration
1683 
1684    Objective-C:
1685 
1686    external-declaration:
1687      objc-class-definition
1688      objc-class-declaration
1689      objc-alias-declaration
1690      objc-protocol-definition
1691      objc-method-definition
1692      @end
1693 */
1694 
1695 static void
c_parser_external_declaration(c_parser * parser)1696 c_parser_external_declaration (c_parser *parser)
1697 {
1698   int ext;
1699   switch (c_parser_peek_token (parser)->type)
1700     {
1701     case CPP_KEYWORD:
1702       switch (c_parser_peek_token (parser)->keyword)
1703 	{
1704 	case RID_EXTENSION:
1705 	  ext = disable_extension_diagnostics ();
1706 	  c_parser_consume_token (parser);
1707 	  c_parser_external_declaration (parser);
1708 	  restore_extension_diagnostics (ext);
1709 	  break;
1710 	case RID_ASM:
1711 	  c_parser_asm_definition (parser);
1712 	  break;
1713 	case RID_AT_INTERFACE:
1714 	case RID_AT_IMPLEMENTATION:
1715 	  gcc_assert (c_dialect_objc ());
1716 	  c_parser_objc_class_definition (parser, NULL_TREE);
1717 	  break;
1718 	case RID_AT_CLASS:
1719 	  gcc_assert (c_dialect_objc ());
1720 	  c_parser_objc_class_declaration (parser);
1721 	  break;
1722 	case RID_AT_ALIAS:
1723 	  gcc_assert (c_dialect_objc ());
1724 	  c_parser_objc_alias_declaration (parser);
1725 	  break;
1726 	case RID_AT_PROTOCOL:
1727 	  gcc_assert (c_dialect_objc ());
1728 	  c_parser_objc_protocol_definition (parser, NULL_TREE);
1729 	  break;
1730 	case RID_AT_PROPERTY:
1731 	  gcc_assert (c_dialect_objc ());
1732 	  c_parser_objc_at_property_declaration (parser);
1733 	  break;
1734 	case RID_AT_SYNTHESIZE:
1735 	  gcc_assert (c_dialect_objc ());
1736 	  c_parser_objc_at_synthesize_declaration (parser);
1737 	  break;
1738 	case RID_AT_DYNAMIC:
1739 	  gcc_assert (c_dialect_objc ());
1740 	  c_parser_objc_at_dynamic_declaration (parser);
1741 	  break;
1742 	case RID_AT_END:
1743 	  gcc_assert (c_dialect_objc ());
1744 	  c_parser_consume_token (parser);
1745 	  objc_finish_implementation ();
1746 	  break;
1747 	default:
1748 	  goto decl_or_fndef;
1749 	}
1750       break;
1751     case CPP_SEMICOLON:
1752       pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1753 	       "ISO C does not allow extra %<;%> outside of a function");
1754       c_parser_consume_token (parser);
1755       break;
1756     case CPP_PRAGMA:
1757       mark_valid_location_for_stdc_pragma (true);
1758       c_parser_pragma (parser, pragma_external, NULL);
1759       mark_valid_location_for_stdc_pragma (false);
1760       break;
1761     case CPP_PLUS:
1762     case CPP_MINUS:
1763       if (c_dialect_objc ())
1764 	{
1765 	  c_parser_objc_method_definition (parser);
1766 	  break;
1767 	}
1768       /* Else fall through, and yield a syntax error trying to parse
1769 	 as a declaration or function definition.  */
1770       /* FALLTHRU */
1771     default:
1772     decl_or_fndef:
1773       /* A declaration or a function definition (or, in Objective-C,
1774 	 an @interface or @protocol with prefix attributes).  We can
1775 	 only tell which after parsing the declaration specifiers, if
1776 	 any, and the first declarator.  */
1777       c_parser_declaration_or_fndef (parser, true, true, true, false, true,
1778 				     NULL, vNULL);
1779       break;
1780     }
1781 }
1782 
1783 static void c_finish_omp_declare_simd (c_parser *, tree, tree, vec<c_token>);
1784 static void c_finish_oacc_routine (struct oacc_routine_data *, tree, bool);
1785 
1786 /* Build and add a DEBUG_BEGIN_STMT statement with location LOC.  */
1787 
1788 static void
add_debug_begin_stmt(location_t loc)1789 add_debug_begin_stmt (location_t loc)
1790 {
1791   /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721.  */
1792   if (!MAY_HAVE_DEBUG_MARKER_STMTS || !building_stmt_list_p ())
1793     return;
1794 
1795   tree stmt = build0 (DEBUG_BEGIN_STMT, void_type_node);
1796   SET_EXPR_LOCATION (stmt, loc);
1797   add_stmt (stmt);
1798 }
1799 
1800 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
1801    6.7, 6.9.1, C11 6.7, 6.9.1).  If FNDEF_OK is true, a function definition
1802    is accepted; otherwise (old-style parameter declarations) only other
1803    declarations are accepted.  If STATIC_ASSERT_OK is true, a static
1804    assertion is accepted; otherwise (old-style parameter declarations)
1805    it is not.  If NESTED is true, we are inside a function or parsing
1806    old-style parameter declarations; any functions encountered are
1807    nested functions and declaration specifiers are required; otherwise
1808    we are at top level and functions are normal functions and
1809    declaration specifiers may be optional.  If EMPTY_OK is true, empty
1810    declarations are OK (subject to all other constraints); otherwise
1811    (old-style parameter declarations) they are diagnosed.  If
1812    START_ATTR_OK is true, the declaration specifiers may start with
1813    attributes (GNU or standard); otherwise they may not.
1814    OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
1815    declaration when parsing an Objective-C foreach statement.
1816    FALLTHRU_ATTR_P is used to signal whether this function parsed
1817    "__attribute__((fallthrough));".  ATTRS are any standard attributes
1818    parsed in the caller (in contexts where such attributes had to be
1819    parsed to determine whether what follows is a declaration or a
1820    statement); HAVE_ATTRS says whether there were any such attributes
1821    (even empty).
1822 
1823    declaration:
1824      declaration-specifiers init-declarator-list[opt] ;
1825      static_assert-declaration
1826 
1827    function-definition:
1828      declaration-specifiers[opt] declarator declaration-list[opt]
1829        compound-statement
1830 
1831    declaration-list:
1832      declaration
1833      declaration-list declaration
1834 
1835    init-declarator-list:
1836      init-declarator
1837      init-declarator-list , init-declarator
1838 
1839    init-declarator:
1840      declarator simple-asm-expr[opt] gnu-attributes[opt]
1841      declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
1842 
1843    GNU extensions:
1844 
1845    nested-function-definition:
1846      declaration-specifiers declarator declaration-list[opt]
1847        compound-statement
1848 
1849    attribute ;
1850 
1851    Objective-C:
1852      gnu-attributes objc-class-definition
1853      gnu-attributes objc-category-definition
1854      gnu-attributes objc-protocol-definition
1855 
1856    The simple-asm-expr and gnu-attributes are GNU extensions.
1857 
1858    This function does not handle __extension__; that is handled in its
1859    callers.  ??? Following the old parser, __extension__ may start
1860    external declarations, declarations in functions and declarations
1861    at the start of "for" loops, but not old-style parameter
1862    declarations.
1863 
1864    C99 requires declaration specifiers in a function definition; the
1865    absence is diagnosed through the diagnosis of implicit int.  In GNU
1866    C we also allow but diagnose declarations without declaration
1867    specifiers, but only at top level (elsewhere they conflict with
1868    other syntax).
1869 
1870    In Objective-C, declarations of the looping variable in a foreach
1871    statement are exceptionally terminated by 'in' (for example, 'for
1872    (NSObject *object in array) { ... }').
1873 
1874    OpenMP:
1875 
1876    declaration:
1877      threadprivate-directive
1878 
1879    GIMPLE:
1880 
1881    gimple-function-definition:
1882      declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
1883        declaration-list[opt] compound-statement
1884 
1885    rtl-function-definition:
1886      declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
1887        declaration-list[opt] compound-statement  */
1888 
1889 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)1890 c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
1891 			       bool static_assert_ok, bool empty_ok,
1892 			       bool nested, bool start_attr_ok,
1893 			       tree *objc_foreach_object_declaration,
1894 			       vec<c_token> omp_declare_simd_clauses,
1895 			       bool have_attrs, tree attrs,
1896 			       struct oacc_routine_data *oacc_routine_data,
1897 			       bool *fallthru_attr_p)
1898 {
1899   struct c_declspecs *specs;
1900   tree prefix_attrs;
1901   tree all_prefix_attrs;
1902   bool diagnosed_no_specs = false;
1903   location_t here = c_parser_peek_token (parser)->location;
1904 
1905   add_debug_begin_stmt (c_parser_peek_token (parser)->location);
1906 
1907   if (static_assert_ok
1908       && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
1909     {
1910       c_parser_static_assert_declaration (parser);
1911       return;
1912     }
1913   specs = build_null_declspecs ();
1914 
1915   /* Handle any standard attributes parsed in the caller.  */
1916   if (have_attrs)
1917     {
1918       declspecs_add_attrs (here, specs, attrs);
1919       specs->non_std_attrs_seen_p = false;
1920     }
1921 
1922   /* Try to detect an unknown type name when we have "A B" or "A *B".  */
1923   if (c_parser_peek_token (parser)->type == CPP_NAME
1924       && c_parser_peek_token (parser)->id_kind == C_ID_ID
1925       && (c_parser_peek_2nd_token (parser)->type == CPP_NAME
1926           || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
1927       && (!nested || !lookup_name (c_parser_peek_token (parser)->value)))
1928     {
1929       tree name = c_parser_peek_token (parser)->value;
1930 
1931       /* Issue a warning about NAME being an unknown type name, perhaps
1932 	 with some kind of hint.
1933 	 If the user forgot a "struct" etc, suggest inserting
1934 	 it.  Otherwise, attempt to look for misspellings.  */
1935       gcc_rich_location richloc (here);
1936       if (tag_exists_p (RECORD_TYPE, name))
1937 	{
1938 	  /* This is not C++ with its implicit typedef.  */
1939 	  richloc.add_fixit_insert_before ("struct ");
1940 	  error_at (&richloc,
1941 		    "unknown type name %qE;"
1942 		    " use %<struct%> keyword to refer to the type",
1943 		    name);
1944 	}
1945       else if (tag_exists_p (UNION_TYPE, name))
1946 	{
1947 	  richloc.add_fixit_insert_before ("union ");
1948 	  error_at (&richloc,
1949 		    "unknown type name %qE;"
1950 		    " use %<union%> keyword to refer to the type",
1951 		    name);
1952 	}
1953       else if (tag_exists_p (ENUMERAL_TYPE, name))
1954 	{
1955 	  richloc.add_fixit_insert_before ("enum ");
1956 	  error_at (&richloc,
1957 		    "unknown type name %qE;"
1958 		    " use %<enum%> keyword to refer to the type",
1959 		    name);
1960 	}
1961       else
1962 	{
1963 	  auto_diagnostic_group d;
1964 	  name_hint hint = lookup_name_fuzzy (name, FUZZY_LOOKUP_TYPENAME,
1965 					      here);
1966 	  if (const char *suggestion = hint.suggestion ())
1967 	    {
1968 	      richloc.add_fixit_replace (suggestion);
1969 	      error_at (&richloc,
1970 			"unknown type name %qE; did you mean %qs?",
1971 			name, suggestion);
1972 	    }
1973 	  else
1974 	    error_at (here, "unknown type name %qE", name);
1975 	}
1976 
1977       /* Parse declspecs normally to get a correct pointer type, but avoid
1978          a further "fails to be a type name" error.  Refuse nested functions
1979          since it is not how the user likely wants us to recover.  */
1980       c_parser_peek_token (parser)->type = CPP_KEYWORD;
1981       c_parser_peek_token (parser)->keyword = RID_VOID;
1982       c_parser_peek_token (parser)->value = error_mark_node;
1983       fndef_ok = !nested;
1984     }
1985 
1986   /* When there are standard attributes at the start of the
1987      declaration (to apply to the entity being declared), an
1988      init-declarator-list or function definition must be present.  */
1989   if (c_parser_nth_token_starts_std_attributes (parser, 1))
1990     have_attrs = true;
1991 
1992   c_parser_declspecs (parser, specs, true, true, start_attr_ok,
1993 		      true, true, start_attr_ok, true, cla_nonabstract_decl);
1994   if (parser->error)
1995     {
1996       c_parser_skip_to_end_of_block_or_statement (parser);
1997       return;
1998     }
1999   if (nested && !specs->declspecs_seen_p)
2000     {
2001       c_parser_error (parser, "expected declaration specifiers");
2002       c_parser_skip_to_end_of_block_or_statement (parser);
2003       return;
2004     }
2005 
2006   finish_declspecs (specs);
2007   bool auto_type_p = specs->typespec_word == cts_auto_type;
2008   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2009     {
2010       if (auto_type_p)
2011 	error_at (here, "%<__auto_type%> in empty declaration");
2012       else if (specs->typespec_kind == ctsk_none
2013 	       && attribute_fallthrough_p (specs->attrs))
2014 	{
2015 	  if (fallthru_attr_p != NULL)
2016 	    *fallthru_attr_p = true;
2017 	  if (nested)
2018 	    {
2019 	      tree fn = build_call_expr_internal_loc (here, IFN_FALLTHROUGH,
2020 						      void_type_node, 0);
2021 	      add_stmt (fn);
2022 	    }
2023 	  else
2024 	    pedwarn (here, OPT_Wattributes,
2025 		     "%<fallthrough%> attribute at top level");
2026 	}
2027       else if (empty_ok && !(have_attrs
2028 			     && specs->non_std_attrs_seen_p))
2029 	shadow_tag (specs);
2030       else
2031 	{
2032 	  shadow_tag_warned (specs, 1);
2033 	  pedwarn (here, 0, "empty declaration");
2034 	}
2035       c_parser_consume_token (parser);
2036       if (oacc_routine_data)
2037 	c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2038       return;
2039     }
2040 
2041   /* Provide better error recovery.  Note that a type name here is usually
2042      better diagnosed as a redeclaration.  */
2043   if (empty_ok
2044       && specs->typespec_kind == ctsk_tagdef
2045       && c_parser_next_token_starts_declspecs (parser)
2046       && !c_parser_next_token_is (parser, CPP_NAME))
2047     {
2048       c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
2049       parser->error = false;
2050       shadow_tag_warned (specs, 1);
2051       return;
2052     }
2053   else if (c_dialect_objc () && !auto_type_p)
2054     {
2055       /* Prefix attributes are an error on method decls.  */
2056       switch (c_parser_peek_token (parser)->type)
2057 	{
2058 	  case CPP_PLUS:
2059 	  case CPP_MINUS:
2060 	    if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2061 	      return;
2062 	    if (specs->attrs)
2063 	      {
2064 		warning_at (c_parser_peek_token (parser)->location,
2065 			    OPT_Wattributes,
2066 	       		    "prefix attributes are ignored for methods");
2067 		specs->attrs = NULL_TREE;
2068 	      }
2069 	    if (fndef_ok)
2070 	      c_parser_objc_method_definition (parser);
2071 	    else
2072 	      c_parser_objc_methodproto (parser);
2073 	    return;
2074 	    break;
2075 	  default:
2076 	    break;
2077 	}
2078       /* This is where we parse 'attributes @interface ...',
2079 	 'attributes @implementation ...', 'attributes @protocol ...'
2080 	 (where attributes could be, for example, __attribute__
2081 	 ((deprecated)).
2082       */
2083       switch (c_parser_peek_token (parser)->keyword)
2084 	{
2085 	case RID_AT_INTERFACE:
2086 	  {
2087 	    if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2088 	      return;
2089 	    c_parser_objc_class_definition (parser, specs->attrs);
2090 	    return;
2091 	  }
2092 	  break;
2093 	case RID_AT_IMPLEMENTATION:
2094 	  {
2095 	    if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2096 	      return;
2097 	    if (specs->attrs)
2098 	      {
2099 		warning_at (c_parser_peek_token (parser)->location,
2100 			OPT_Wattributes,
2101 			"prefix attributes are ignored for implementations");
2102 		specs->attrs = NULL_TREE;
2103 	      }
2104 	    c_parser_objc_class_definition (parser, NULL_TREE);
2105 	    return;
2106 	  }
2107 	  break;
2108 	case RID_AT_PROTOCOL:
2109 	  {
2110 	    if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2111 	      return;
2112 	    c_parser_objc_protocol_definition (parser, specs->attrs);
2113 	    return;
2114 	  }
2115 	  break;
2116 	case RID_AT_ALIAS:
2117 	case RID_AT_CLASS:
2118 	case RID_AT_END:
2119 	case RID_AT_PROPERTY:
2120 	  if (specs->attrs)
2121 	    {
2122 	      c_parser_error (parser, "unexpected attribute");
2123 	      specs->attrs = NULL;
2124 	    }
2125 	  break;
2126 	default:
2127 	  break;
2128 	}
2129     }
2130   else if (attribute_fallthrough_p (specs->attrs))
2131     warning_at (here, OPT_Wattributes,
2132 		"%<fallthrough%> attribute not followed by %<;%>");
2133 
2134   pending_xref_error ();
2135   prefix_attrs = specs->attrs;
2136   all_prefix_attrs = prefix_attrs;
2137   specs->attrs = NULL_TREE;
2138   while (true)
2139     {
2140       struct c_declarator *declarator;
2141       bool dummy = false;
2142       timevar_id_t tv;
2143       tree fnbody = NULL_TREE;
2144       /* Declaring either one or more declarators (in which case we
2145 	 should diagnose if there were no declaration specifiers) or a
2146 	 function definition (in which case the diagnostic for
2147 	 implicit int suffices).  */
2148       declarator = c_parser_declarator (parser,
2149 					specs->typespec_kind != ctsk_none,
2150 					C_DTR_NORMAL, &dummy);
2151       if (declarator == NULL)
2152 	{
2153 	  if (omp_declare_simd_clauses.exists ())
2154 	    c_finish_omp_declare_simd (parser, NULL_TREE, NULL_TREE,
2155 				       omp_declare_simd_clauses);
2156 	  if (oacc_routine_data)
2157 	    c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2158 	  c_parser_skip_to_end_of_block_or_statement (parser);
2159 	  return;
2160 	}
2161       if (auto_type_p && declarator->kind != cdk_id)
2162 	{
2163 	  error_at (here,
2164 		    "%<__auto_type%> requires a plain identifier"
2165 		    " as declarator");
2166 	  c_parser_skip_to_end_of_block_or_statement (parser);
2167 	  return;
2168 	}
2169       if (c_parser_next_token_is (parser, CPP_EQ)
2170 	  || c_parser_next_token_is (parser, CPP_COMMA)
2171 	  || c_parser_next_token_is (parser, CPP_SEMICOLON)
2172 	  || c_parser_next_token_is_keyword (parser, RID_ASM)
2173 	  || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)
2174 	  || c_parser_next_token_is_keyword (parser, RID_IN))
2175 	{
2176 	  tree asm_name = NULL_TREE;
2177 	  tree postfix_attrs = NULL_TREE;
2178 	  if (!diagnosed_no_specs && !specs->declspecs_seen_p)
2179 	    {
2180 	      diagnosed_no_specs = true;
2181 	      pedwarn (here, 0, "data definition has no type or storage class");
2182 	    }
2183 	  /* Having seen a data definition, there cannot now be a
2184 	     function definition.  */
2185 	  fndef_ok = false;
2186 	  if (c_parser_next_token_is_keyword (parser, RID_ASM))
2187 	    asm_name = c_parser_simple_asm_expr (parser);
2188 	  if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2189 	    {
2190 	      postfix_attrs = c_parser_gnu_attributes (parser);
2191 	      if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
2192 		{
2193 		  /* This means there is an attribute specifier after
2194 		     the declarator in a function definition.  Provide
2195 		     some more information for the user.  */
2196 		  error_at (here, "attributes should be specified before the "
2197 			    "declarator in a function definition");
2198 		  c_parser_skip_to_end_of_block_or_statement (parser);
2199 		  return;
2200 		}
2201 	    }
2202 	  if (c_parser_next_token_is (parser, CPP_EQ))
2203 	    {
2204 	      tree d;
2205 	      struct c_expr init;
2206 	      location_t init_loc;
2207 	      c_parser_consume_token (parser);
2208 	      if (auto_type_p)
2209 		{
2210 		  init_loc = c_parser_peek_token (parser)->location;
2211 		  rich_location richloc (line_table, init_loc);
2212 		  start_init (NULL_TREE, asm_name, global_bindings_p (), &richloc);
2213 		  /* A parameter is initialized, which is invalid.  Don't
2214 		     attempt to instrument the initializer.  */
2215 		  int flag_sanitize_save = flag_sanitize;
2216 		  if (nested && !empty_ok)
2217 		    flag_sanitize = 0;
2218 		  init = c_parser_expr_no_commas (parser, NULL);
2219 		  flag_sanitize = flag_sanitize_save;
2220 		  if (TREE_CODE (init.value) == COMPONENT_REF
2221 		      && DECL_C_BIT_FIELD (TREE_OPERAND (init.value, 1)))
2222 		    error_at (here,
2223 			      "%<__auto_type%> used with a bit-field"
2224 			      " initializer");
2225 		  init = convert_lvalue_to_rvalue (init_loc, init, true, true);
2226 		  tree init_type = TREE_TYPE (init.value);
2227 		  bool vm_type = variably_modified_type_p (init_type,
2228 							   NULL_TREE);
2229 		  if (vm_type)
2230 		    init.value = save_expr (init.value);
2231 		  finish_init ();
2232 		  specs->typespec_kind = ctsk_typeof;
2233 		  specs->locations[cdw_typedef] = init_loc;
2234 		  specs->typedef_p = true;
2235 		  specs->type = init_type;
2236 		  if (vm_type)
2237 		    {
2238 		      bool maybe_const = true;
2239 		      tree type_expr = c_fully_fold (init.value, false,
2240 						     &maybe_const);
2241 		      specs->expr_const_operands &= maybe_const;
2242 		      if (specs->expr)
2243 			specs->expr = build2 (COMPOUND_EXPR,
2244 					      TREE_TYPE (type_expr),
2245 					      specs->expr, type_expr);
2246 		      else
2247 			specs->expr = type_expr;
2248 		    }
2249 		  d = start_decl (declarator, specs, true,
2250 				  chainon (postfix_attrs, all_prefix_attrs));
2251 		  if (!d)
2252 		    d = error_mark_node;
2253 		  if (omp_declare_simd_clauses.exists ())
2254 		    c_finish_omp_declare_simd (parser, d, NULL_TREE,
2255 					       omp_declare_simd_clauses);
2256 		}
2257 	      else
2258 		{
2259 		  /* The declaration of the variable is in effect while
2260 		     its initializer is parsed.  */
2261 		  d = start_decl (declarator, specs, true,
2262 				  chainon (postfix_attrs, all_prefix_attrs));
2263 		  if (!d)
2264 		    d = error_mark_node;
2265 		  if (omp_declare_simd_clauses.exists ())
2266 		    c_finish_omp_declare_simd (parser, d, NULL_TREE,
2267 					       omp_declare_simd_clauses);
2268 		  init_loc = c_parser_peek_token (parser)->location;
2269 		  rich_location richloc (line_table, init_loc);
2270 		  start_init (d, asm_name, global_bindings_p (), &richloc);
2271 		  /* A parameter is initialized, which is invalid.  Don't
2272 		     attempt to instrument the initializer.  */
2273 		  int flag_sanitize_save = flag_sanitize;
2274 		  if (TREE_CODE (d) == PARM_DECL)
2275 		    flag_sanitize = 0;
2276 		  init = c_parser_initializer (parser);
2277 		  flag_sanitize = flag_sanitize_save;
2278 		  finish_init ();
2279 		}
2280 	      if (oacc_routine_data)
2281 		c_finish_oacc_routine (oacc_routine_data, d, false);
2282 	      if (d != error_mark_node)
2283 		{
2284 		  maybe_warn_string_init (init_loc, TREE_TYPE (d), init);
2285 		  finish_decl (d, init_loc, init.value,
2286 			       init.original_type, asm_name);
2287 		}
2288 	    }
2289 	  else
2290 	    {
2291 	      if (auto_type_p)
2292 		{
2293 		  error_at (here,
2294 			    "%<__auto_type%> requires an initialized "
2295 			    "data declaration");
2296 		  c_parser_skip_to_end_of_block_or_statement (parser);
2297 		  return;
2298 		}
2299 
2300 	      location_t lastloc = UNKNOWN_LOCATION;
2301 	      tree attrs = chainon (postfix_attrs, all_prefix_attrs);
2302 	      tree d = start_decl (declarator, specs, false, attrs, &lastloc);
2303 	      if (d && TREE_CODE (d) == FUNCTION_DECL)
2304 		{
2305 		  /* Find the innermost declarator that is neither cdk_id
2306 		     nor cdk_attrs.  */
2307 		  const struct c_declarator *decl = declarator;
2308 		  const struct c_declarator *last_non_id_attrs = NULL;
2309 
2310 		  while (decl)
2311 		    switch (decl->kind)
2312 		      {
2313 		      case cdk_array:
2314 		      case cdk_function:
2315 		      case cdk_pointer:
2316 			last_non_id_attrs = decl;
2317 			decl = decl->declarator;
2318 			break;
2319 
2320 		      case cdk_attrs:
2321 			decl = decl->declarator;
2322 			break;
2323 
2324 		      case cdk_id:
2325 			decl = 0;
2326 			break;
2327 
2328 		      default:
2329 			gcc_unreachable ();
2330 		      }
2331 
2332 		  /* If it exists and is cdk_function declaration whose
2333 		     arguments have not been set yet, use its arguments.  */
2334 		  if (last_non_id_attrs
2335 		      && last_non_id_attrs->kind == cdk_function)
2336 		    {
2337 		      tree parms = last_non_id_attrs->u.arg_info->parms;
2338 		      if (DECL_ARGUMENTS (d) == NULL_TREE
2339 			  && DECL_INITIAL (d) == NULL_TREE)
2340 			DECL_ARGUMENTS (d) = parms;
2341 
2342 		      warn_parm_array_mismatch (lastloc, d, parms);
2343 		    }
2344 		}
2345 	      if (omp_declare_simd_clauses.exists ())
2346 		{
2347 		  tree parms = NULL_TREE;
2348 		  if (d && TREE_CODE (d) == FUNCTION_DECL)
2349 		    {
2350 		      struct c_declarator *ce = declarator;
2351 		      while (ce != NULL)
2352 			if (ce->kind == cdk_function)
2353 			  {
2354 			    parms = ce->u.arg_info->parms;
2355 			    break;
2356 			  }
2357 			else
2358 			  ce = ce->declarator;
2359 		    }
2360 		  if (parms)
2361 		    temp_store_parm_decls (d, parms);
2362 		  c_finish_omp_declare_simd (parser, d, parms,
2363 					     omp_declare_simd_clauses);
2364 		  if (parms)
2365 		    temp_pop_parm_decls ();
2366 		}
2367 	      if (oacc_routine_data)
2368 		c_finish_oacc_routine (oacc_routine_data, d, false);
2369 	      if (d)
2370 		finish_decl (d, UNKNOWN_LOCATION, NULL_TREE,
2371 			     NULL_TREE, asm_name);
2372 
2373 	      if (c_parser_next_token_is_keyword (parser, RID_IN))
2374 		{
2375 		  if (d)
2376 		    *objc_foreach_object_declaration = d;
2377 		  else
2378 		    *objc_foreach_object_declaration = error_mark_node;
2379 		}
2380 	    }
2381 	  if (c_parser_next_token_is (parser, CPP_COMMA))
2382 	    {
2383 	      if (auto_type_p)
2384 		{
2385 		  error_at (here,
2386 			    "%<__auto_type%> may only be used with"
2387 			    " a single declarator");
2388 		  c_parser_skip_to_end_of_block_or_statement (parser);
2389 		  return;
2390 		}
2391 	      c_parser_consume_token (parser);
2392 	      if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2393 		all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
2394 					    prefix_attrs);
2395 	      else
2396 		all_prefix_attrs = prefix_attrs;
2397 	      continue;
2398 	    }
2399 	  else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2400 	    {
2401 	      c_parser_consume_token (parser);
2402 	      return;
2403 	    }
2404 	  else if (c_parser_next_token_is_keyword (parser, RID_IN))
2405 	    {
2406 	      /* This can only happen in Objective-C: we found the
2407 		 'in' that terminates the declaration inside an
2408 		 Objective-C foreach statement.  Do not consume the
2409 		 token, so that the caller can use it to determine
2410 		 that this indeed is a foreach context.  */
2411 	      return;
2412 	    }
2413 	  else
2414 	    {
2415 	      c_parser_error (parser, "expected %<,%> or %<;%>");
2416 	      c_parser_skip_to_end_of_block_or_statement (parser);
2417 	      return;
2418 	    }
2419 	}
2420       else if (auto_type_p)
2421 	{
2422 	  error_at (here,
2423 		    "%<__auto_type%> requires an initialized data declaration");
2424 	  c_parser_skip_to_end_of_block_or_statement (parser);
2425 	  return;
2426 	}
2427       else if (!fndef_ok)
2428 	{
2429 	  c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, "
2430 			  "%<asm%> or %<__attribute__%>");
2431 	  c_parser_skip_to_end_of_block_or_statement (parser);
2432 	  return;
2433 	}
2434       /* Function definition (nested or otherwise).  */
2435       if (nested)
2436 	{
2437 	  pedwarn (here, OPT_Wpedantic, "ISO C forbids nested functions");
2438 	  c_push_function_context ();
2439 	}
2440       if (!start_function (specs, declarator, all_prefix_attrs))
2441 	{
2442 	  /* At this point we've consumed:
2443 	       declaration-specifiers declarator
2444 	     and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2445 	     RID_ASM, RID_ATTRIBUTE, or RID_IN,
2446 	     but the
2447 	       declaration-specifiers declarator
2448 	     aren't grokkable as a function definition, so we have
2449 	     an error.  */
2450 	  gcc_assert (!c_parser_next_token_is (parser, CPP_SEMICOLON));
2451 	  if (c_parser_next_token_starts_declspecs (parser))
2452 	    {
2453 	      /* If we have
2454 		   declaration-specifiers declarator decl-specs
2455 		 then assume we have a missing semicolon, which would
2456 		 give us:
2457 		   declaration-specifiers declarator  decl-specs
2458 						    ^
2459 						    ;
2460 		   <~~~~~~~~~ declaration ~~~~~~~~~~>
2461 		 Use c_parser_require to get an error with a fix-it hint.  */
2462 	      c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>");
2463 	      parser->error = false;
2464 	    }
2465 	  else
2466 	    {
2467 	      /* This can appear in many cases looking nothing like a
2468 		 function definition, so we don't give a more specific
2469 		 error suggesting there was one.  */
2470 	      c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2471 			      "or %<__attribute__%>");
2472 	    }
2473 	  if (nested)
2474 	    c_pop_function_context ();
2475 	  break;
2476 	}
2477 
2478       if (DECL_DECLARED_INLINE_P (current_function_decl))
2479         tv = TV_PARSE_INLINE;
2480       else
2481         tv = TV_PARSE_FUNC;
2482       auto_timevar at (g_timer, tv);
2483 
2484       /* Parse old-style parameter declarations.  ??? Attributes are
2485 	 not allowed to start declaration specifiers here because of a
2486 	 syntax conflict between a function declaration with attribute
2487 	 suffix and a function definition with an attribute prefix on
2488 	 first old-style parameter declaration.  Following the old
2489 	 parser, they are not accepted on subsequent old-style
2490 	 parameter declarations either.  However, there is no
2491 	 ambiguity after the first declaration, nor indeed on the
2492 	 first as long as we don't allow postfix attributes after a
2493 	 declarator with a nonempty identifier list in a definition;
2494 	 and postfix attributes have never been accepted here in
2495 	 function definitions either.  */
2496       while (c_parser_next_token_is_not (parser, CPP_EOF)
2497 	     && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE))
2498 	c_parser_declaration_or_fndef (parser, false, false, false,
2499 				       true, false, NULL, vNULL);
2500       store_parm_decls ();
2501       if (omp_declare_simd_clauses.exists ())
2502 	c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE,
2503 				   omp_declare_simd_clauses);
2504       if (oacc_routine_data)
2505 	c_finish_oacc_routine (oacc_routine_data, current_function_decl, true);
2506       location_t startloc = c_parser_peek_token (parser)->location;
2507       DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
2508 	= startloc;
2509       location_t endloc = startloc;
2510 
2511       /* If the definition was marked with __RTL, use the RTL parser now,
2512 	 consuming the function body.  */
2513       if (specs->declspec_il == cdil_rtl)
2514 	{
2515 	  endloc = c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass);
2516 
2517 	  /* Normally, store_parm_decls sets next_is_function_body,
2518 	     anticipating a function body.  We need a push_scope/pop_scope
2519 	     pair to flush out this state, or subsequent function parsing
2520 	     will go wrong.  */
2521 	  push_scope ();
2522 	  pop_scope ();
2523 
2524 	  finish_function (endloc);
2525 	  return;
2526 	}
2527       /* If the definition was marked with __GIMPLE then parse the
2528          function body as GIMPLE.  */
2529       else if (specs->declspec_il != cdil_none)
2530 	{
2531 	  bool saved = in_late_binary_op;
2532 	  in_late_binary_op = true;
2533 	  c_parser_parse_gimple_body (parser, specs->gimple_or_rtl_pass,
2534 				      specs->declspec_il,
2535 				      specs->entry_bb_count);
2536 	  in_late_binary_op = saved;
2537 	}
2538       else
2539 	fnbody = c_parser_compound_statement (parser, &endloc);
2540       tree fndecl = current_function_decl;
2541       if (nested)
2542 	{
2543 	  tree decl = current_function_decl;
2544 	  /* Mark nested functions as needing static-chain initially.
2545 	     lower_nested_functions will recompute it but the
2546 	     DECL_STATIC_CHAIN flag is also used before that happens,
2547 	     by initializer_constant_valid_p.  See gcc.dg/nested-fn-2.c.  */
2548 	  DECL_STATIC_CHAIN (decl) = 1;
2549 	  add_stmt (fnbody);
2550 	  finish_function (endloc);
2551 	  c_pop_function_context ();
2552 	  add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));
2553 	}
2554       else
2555 	{
2556 	  if (fnbody)
2557 	    add_stmt (fnbody);
2558 	  finish_function (endloc);
2559 	}
2560       /* Get rid of the empty stmt list for GIMPLE/RTL.  */
2561       if (specs->declspec_il != cdil_none)
2562 	DECL_SAVED_TREE (fndecl) = NULL_TREE;
2563 
2564       break;
2565     }
2566 }
2567 
2568 /* Parse an asm-definition (asm() outside a function body).  This is a
2569    GNU extension.
2570 
2571    asm-definition:
2572      simple-asm-expr ;
2573 */
2574 
2575 static void
c_parser_asm_definition(c_parser * parser)2576 c_parser_asm_definition (c_parser *parser)
2577 {
2578   tree asm_str = c_parser_simple_asm_expr (parser);
2579   if (asm_str)
2580     symtab->finalize_toplevel_asm (asm_str);
2581   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
2582 }
2583 
2584 /* Parse a static assertion (C11 6.7.10).
2585 
2586    static_assert-declaration:
2587      static_assert-declaration-no-semi ;
2588 */
2589 
2590 static void
c_parser_static_assert_declaration(c_parser * parser)2591 c_parser_static_assert_declaration (c_parser *parser)
2592 {
2593   c_parser_static_assert_declaration_no_semi (parser);
2594   if (parser->error
2595       || !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
2596     c_parser_skip_to_end_of_block_or_statement (parser);
2597 }
2598 
2599 /* Parse a static assertion (C11 6.7.10), without the trailing
2600    semicolon.
2601 
2602    static_assert-declaration-no-semi:
2603      _Static_assert ( constant-expression , string-literal )
2604 
2605    C2X:
2606    static_assert-declaration-no-semi:
2607      _Static_assert ( constant-expression )
2608 */
2609 
2610 static void
c_parser_static_assert_declaration_no_semi(c_parser * parser)2611 c_parser_static_assert_declaration_no_semi (c_parser *parser)
2612 {
2613   location_t assert_loc, value_loc;
2614   tree value;
2615   tree string = NULL_TREE;
2616 
2617   gcc_assert (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT));
2618   assert_loc = c_parser_peek_token (parser)->location;
2619   if (flag_isoc99)
2620     pedwarn_c99 (assert_loc, OPT_Wpedantic,
2621 		 "ISO C99 does not support %<_Static_assert%>");
2622   else
2623     pedwarn_c99 (assert_loc, OPT_Wpedantic,
2624 		 "ISO C90 does not support %<_Static_assert%>");
2625   c_parser_consume_token (parser);
2626   matching_parens parens;
2627   if (!parens.require_open (parser))
2628     return;
2629   location_t value_tok_loc = c_parser_peek_token (parser)->location;
2630   value = c_parser_expr_no_commas (parser, NULL).value;
2631   value_loc = EXPR_LOC_OR_LOC (value, value_tok_loc);
2632   if (c_parser_next_token_is (parser, CPP_COMMA))
2633     {
2634       c_parser_consume_token (parser);
2635       switch (c_parser_peek_token (parser)->type)
2636 	{
2637 	case CPP_STRING:
2638 	case CPP_STRING16:
2639 	case CPP_STRING32:
2640 	case CPP_WSTRING:
2641 	case CPP_UTF8STRING:
2642 	  string = c_parser_string_literal (parser, false, true).value;
2643 	  break;
2644 	default:
2645 	  c_parser_error (parser, "expected string literal");
2646 	  return;
2647 	}
2648     }
2649   else if (flag_isoc11)
2650     /* If pedantic for pre-C11, the use of _Static_assert itself will
2651        have been diagnosed, so do not also diagnose the use of this
2652        new C2X feature of _Static_assert.  */
2653     pedwarn_c11 (assert_loc, OPT_Wpedantic,
2654 		 "ISO C11 does not support omitting the string in "
2655 		 "%<_Static_assert%>");
2656   parens.require_close (parser);
2657 
2658   if (!INTEGRAL_TYPE_P (TREE_TYPE (value)))
2659     {
2660       error_at (value_loc, "expression in static assertion is not an integer");
2661       return;
2662     }
2663   if (TREE_CODE (value) != INTEGER_CST)
2664     {
2665       value = c_fully_fold (value, false, NULL);
2666       /* Strip no-op conversions.  */
2667       STRIP_TYPE_NOPS (value);
2668       if (TREE_CODE (value) == INTEGER_CST)
2669 	pedwarn (value_loc, OPT_Wpedantic, "expression in static assertion "
2670 		 "is not an integer constant expression");
2671     }
2672   if (TREE_CODE (value) != INTEGER_CST)
2673     {
2674       error_at (value_loc, "expression in static assertion is not constant");
2675       return;
2676     }
2677   constant_expression_warning (value);
2678   if (integer_zerop (value))
2679     {
2680       if (string)
2681 	error_at (assert_loc, "static assertion failed: %E", string);
2682       else
2683 	error_at (assert_loc, "static assertion failed");
2684     }
2685 }
2686 
2687 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
2688    6.7, C11 6.7), adding them to SPECS (which may already include some).
2689    Storage class specifiers are accepted iff SCSPEC_OK; type
2690    specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
2691    accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start
2692    iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK.  In
2693    addition to the syntax shown, standard attributes are accepted at
2694    the start iff START_STD_ATTR_OK and at the end iff END_STD_ATTR_OK;
2695    unlike gnu-attributes, they are not accepted in the middle of the
2696    list.  (This combines various different syntax productions in the C
2697    standard, and in some cases gnu-attributes and standard attributes
2698    at the start may already have been parsed before this function is
2699    called.)
2700 
2701    declaration-specifiers:
2702      storage-class-specifier declaration-specifiers[opt]
2703      type-specifier declaration-specifiers[opt]
2704      type-qualifier declaration-specifiers[opt]
2705      function-specifier declaration-specifiers[opt]
2706      alignment-specifier declaration-specifiers[opt]
2707 
2708    Function specifiers (inline) are from C99, and are currently
2709    handled as storage class specifiers, as is __thread.  Alignment
2710    specifiers are from C11.
2711 
2712    C90 6.5.1, C99 6.7.1, C11 6.7.1:
2713    storage-class-specifier:
2714      typedef
2715      extern
2716      static
2717      auto
2718      register
2719      _Thread_local
2720 
2721    (_Thread_local is new in C11.)
2722 
2723    C99 6.7.4, C11 6.7.4:
2724    function-specifier:
2725      inline
2726      _Noreturn
2727 
2728    (_Noreturn is new in C11.)
2729 
2730    C90 6.5.2, C99 6.7.2, C11 6.7.2:
2731    type-specifier:
2732      void
2733      char
2734      short
2735      int
2736      long
2737      float
2738      double
2739      signed
2740      unsigned
2741      _Bool
2742      _Complex
2743      [_Imaginary removed in C99 TC2]
2744      struct-or-union-specifier
2745      enum-specifier
2746      typedef-name
2747      atomic-type-specifier
2748 
2749    (_Bool and _Complex are new in C99.)
2750    (atomic-type-specifier is new in C11.)
2751 
2752    C90 6.5.3, C99 6.7.3, C11 6.7.3:
2753 
2754    type-qualifier:
2755      const
2756      restrict
2757      volatile
2758      address-space-qualifier
2759      _Atomic
2760 
2761    (restrict is new in C99.)
2762    (_Atomic is new in C11.)
2763 
2764    GNU extensions:
2765 
2766    declaration-specifiers:
2767      gnu-attributes declaration-specifiers[opt]
2768 
2769    type-qualifier:
2770      address-space
2771 
2772    address-space:
2773      identifier recognized by the target
2774 
2775    storage-class-specifier:
2776      __thread
2777 
2778    type-specifier:
2779      typeof-specifier
2780      __auto_type
2781      __intN
2782      _Decimal32
2783      _Decimal64
2784      _Decimal128
2785      _Fract
2786      _Accum
2787      _Sat
2788 
2789   (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
2790    http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
2791 
2792    atomic-type-specifier
2793     _Atomic ( type-name )
2794 
2795    Objective-C:
2796 
2797    type-specifier:
2798      class-name objc-protocol-refs[opt]
2799      typedef-name objc-protocol-refs
2800      objc-protocol-refs
2801 */
2802 
2803 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)2804 c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
2805 		    bool scspec_ok, bool typespec_ok, bool start_attr_ok,
2806 		    bool alignspec_ok, bool auto_type_ok,
2807 		    bool start_std_attr_ok, bool end_std_attr_ok,
2808 		    enum c_lookahead_kind la)
2809 {
2810   bool attrs_ok = start_attr_ok;
2811   bool seen_type = specs->typespec_kind != ctsk_none;
2812 
2813   if (!typespec_ok)
2814     gcc_assert (la == cla_prefer_id);
2815 
2816   if (start_std_attr_ok
2817       && c_parser_nth_token_starts_std_attributes (parser, 1))
2818     {
2819       gcc_assert (!specs->non_std_attrs_seen_p);
2820       location_t loc = c_parser_peek_token (parser)->location;
2821       tree attrs = c_parser_std_attribute_specifier_sequence (parser);
2822       declspecs_add_attrs (loc, specs, attrs);
2823       specs->non_std_attrs_seen_p = false;
2824     }
2825 
2826   while (c_parser_next_token_is (parser, CPP_NAME)
2827 	 || c_parser_next_token_is (parser, CPP_KEYWORD)
2828 	 || (c_dialect_objc () && c_parser_next_token_is (parser, CPP_LESS)))
2829     {
2830       struct c_typespec t;
2831       tree attrs;
2832       tree align;
2833       location_t loc = c_parser_peek_token (parser)->location;
2834 
2835       /* If we cannot accept a type, exit if the next token must start
2836 	 one.  Also, if we already have seen a tagged definition,
2837 	 a typename would be an error anyway and likely the user
2838 	 has simply forgotten a semicolon, so we exit.  */
2839       if ((!typespec_ok || specs->typespec_kind == ctsk_tagdef)
2840 	  && c_parser_next_tokens_start_typename (parser, la)
2841 	  && !c_parser_next_token_is_qualifier (parser)
2842 	  && !c_parser_next_token_is_keyword (parser, RID_ALIGNAS))
2843 	break;
2844 
2845       if (c_parser_next_token_is (parser, CPP_NAME))
2846 	{
2847 	  c_token *name_token = c_parser_peek_token (parser);
2848 	  tree value = name_token->value;
2849 	  c_id_kind kind = name_token->id_kind;
2850 
2851 	  if (kind == C_ID_ADDRSPACE)
2852 	    {
2853 	      addr_space_t as
2854 		= name_token->keyword - RID_FIRST_ADDR_SPACE;
2855 	      declspecs_add_addrspace (name_token->location, specs, as);
2856 	      c_parser_consume_token (parser);
2857 	      attrs_ok = true;
2858 	      continue;
2859 	    }
2860 
2861 	  gcc_assert (!c_parser_next_token_is_qualifier (parser));
2862 
2863 	  /* If we cannot accept a type, and the next token must start one,
2864 	     exit.  Do the same if we already have seen a tagged definition,
2865 	     since it would be an error anyway and likely the user has simply
2866 	     forgotten a semicolon.  */
2867 	  if (seen_type || !c_parser_next_tokens_start_typename (parser, la))
2868 	    break;
2869 
2870 	  /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
2871 	     a C_ID_CLASSNAME.  */
2872 	  c_parser_consume_token (parser);
2873 	  seen_type = true;
2874 	  attrs_ok = true;
2875 	  if (kind == C_ID_ID)
2876 	    {
2877 	      error_at (loc, "unknown type name %qE", value);
2878 	      t.kind = ctsk_typedef;
2879 	      t.spec = error_mark_node;
2880 	    }
2881 	  else if (kind == C_ID_TYPENAME
2882 	           && (!c_dialect_objc ()
2883 	               || c_parser_next_token_is_not (parser, CPP_LESS)))
2884 	    {
2885 	      t.kind = ctsk_typedef;
2886 	      /* For a typedef name, record the meaning, not the name.
2887 		 In case of 'foo foo, bar;'.  */
2888 	      t.spec = lookup_name (value);
2889 	    }
2890 	  else
2891 	    {
2892 	      tree proto = NULL_TREE;
2893 	      gcc_assert (c_dialect_objc ());
2894 	      t.kind = ctsk_objc;
2895 	      if (c_parser_next_token_is (parser, CPP_LESS))
2896 		proto = c_parser_objc_protocol_refs (parser);
2897 	      t.spec = objc_get_protocol_qualified_type (value, proto);
2898 	    }
2899 	  t.expr = NULL_TREE;
2900 	  t.expr_const_operands = true;
2901 	  declspecs_add_type (name_token->location, specs, t);
2902 	  continue;
2903 	}
2904       if (c_parser_next_token_is (parser, CPP_LESS))
2905 	{
2906 	  /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
2907 	     nisse@lysator.liu.se.  */
2908 	  tree proto;
2909 	  gcc_assert (c_dialect_objc ());
2910 	  if (!typespec_ok || seen_type)
2911 	    break;
2912 	  proto = c_parser_objc_protocol_refs (parser);
2913 	  t.kind = ctsk_objc;
2914 	  t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto);
2915 	  t.expr = NULL_TREE;
2916 	  t.expr_const_operands = true;
2917 	  declspecs_add_type (loc, specs, t);
2918 	  continue;
2919 	}
2920       gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD));
2921       switch (c_parser_peek_token (parser)->keyword)
2922 	{
2923 	case RID_STATIC:
2924 	case RID_EXTERN:
2925 	case RID_REGISTER:
2926 	case RID_TYPEDEF:
2927 	case RID_INLINE:
2928 	case RID_NORETURN:
2929 	case RID_AUTO:
2930 	case RID_THREAD:
2931 	  if (!scspec_ok)
2932 	    goto out;
2933 	  attrs_ok = true;
2934 	  /* TODO: Distinguish between function specifiers (inline, noreturn)
2935 	     and storage class specifiers, either here or in
2936 	     declspecs_add_scspec.  */
2937 	  declspecs_add_scspec (loc, specs,
2938 				c_parser_peek_token (parser)->value);
2939 	  c_parser_consume_token (parser);
2940 	  break;
2941 	case RID_AUTO_TYPE:
2942 	  if (!auto_type_ok)
2943 	    goto out;
2944 	  /* Fall through.  */
2945 	case RID_UNSIGNED:
2946 	case RID_LONG:
2947 	case RID_SHORT:
2948 	case RID_SIGNED:
2949 	case RID_COMPLEX:
2950 	case RID_INT:
2951 	case RID_CHAR:
2952 	case RID_FLOAT:
2953 	case RID_DOUBLE:
2954 	case RID_VOID:
2955 	case RID_DFLOAT32:
2956 	case RID_DFLOAT64:
2957 	case RID_DFLOAT128:
2958 	CASE_RID_FLOATN_NX:
2959 	case RID_BOOL:
2960 	case RID_FRACT:
2961 	case RID_ACCUM:
2962 	case RID_SAT:
2963 	case RID_INT_N_0:
2964 	case RID_INT_N_1:
2965 	case RID_INT_N_2:
2966 	case RID_INT_N_3:
2967 	  if (!typespec_ok)
2968 	    goto out;
2969 	  attrs_ok = true;
2970 	  seen_type = true;
2971 	  if (c_dialect_objc ())
2972 	    parser->objc_need_raw_identifier = true;
2973 	  t.kind = ctsk_resword;
2974 	  t.spec = c_parser_peek_token (parser)->value;
2975 	  t.expr = NULL_TREE;
2976 	  t.expr_const_operands = true;
2977 	  declspecs_add_type (loc, specs, t);
2978 	  c_parser_consume_token (parser);
2979 	  break;
2980 	case RID_ENUM:
2981 	  if (!typespec_ok)
2982 	    goto out;
2983 	  attrs_ok = true;
2984 	  seen_type = true;
2985 	  t = c_parser_enum_specifier (parser);
2986           invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
2987 	  declspecs_add_type (loc, specs, t);
2988 	  break;
2989 	case RID_STRUCT:
2990 	case RID_UNION:
2991 	  if (!typespec_ok)
2992 	    goto out;
2993 	  attrs_ok = true;
2994 	  seen_type = true;
2995 	  t = c_parser_struct_or_union_specifier (parser);
2996           invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
2997 	  declspecs_add_type (loc, specs, t);
2998 	  break;
2999 	case RID_TYPEOF:
3000 	  /* ??? The old parser rejected typeof after other type
3001 	     specifiers, but is a syntax error the best way of
3002 	     handling this?  */
3003 	  if (!typespec_ok || seen_type)
3004 	    goto out;
3005 	  attrs_ok = true;
3006 	  seen_type = true;
3007 	  t = c_parser_typeof_specifier (parser);
3008 	  declspecs_add_type (loc, specs, t);
3009 	  break;
3010 	case RID_ATOMIC:
3011 	  /* C parser handling of Objective-C constructs needs
3012 	     checking for correct lvalue-to-rvalue conversions, and
3013 	     the code in build_modify_expr handling various
3014 	     Objective-C cases, and that in build_unary_op handling
3015 	     Objective-C cases for increment / decrement, also needs
3016 	     updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
3017 	     and objc_types_are_equivalent may also need updates.  */
3018 	  if (c_dialect_objc ())
3019 	    sorry ("%<_Atomic%> in Objective-C");
3020 	  if (flag_isoc99)
3021 	    pedwarn_c99 (loc, OPT_Wpedantic,
3022 			 "ISO C99 does not support the %<_Atomic%> qualifier");
3023 	  else
3024 	    pedwarn_c99 (loc, OPT_Wpedantic,
3025 			 "ISO C90 does not support the %<_Atomic%> qualifier");
3026 	  attrs_ok = true;
3027 	  tree value;
3028 	  value = c_parser_peek_token (parser)->value;
3029 	  c_parser_consume_token (parser);
3030 	  if (typespec_ok && c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3031 	    {
3032 	      /* _Atomic ( type-name ).  */
3033 	      seen_type = true;
3034 	      c_parser_consume_token (parser);
3035 	      struct c_type_name *type = c_parser_type_name (parser);
3036 	      t.kind = ctsk_typeof;
3037 	      t.spec = error_mark_node;
3038 	      t.expr = NULL_TREE;
3039 	      t.expr_const_operands = true;
3040 	      if (type != NULL)
3041 		t.spec = groktypename (type, &t.expr,
3042 				       &t.expr_const_operands);
3043 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3044 					 "expected %<)%>");
3045 	      if (t.spec != error_mark_node)
3046 		{
3047 		  if (TREE_CODE (t.spec) == ARRAY_TYPE)
3048 		    error_at (loc, "%<_Atomic%>-qualified array type");
3049 		  else if (TREE_CODE (t.spec) == FUNCTION_TYPE)
3050 		    error_at (loc, "%<_Atomic%>-qualified function type");
3051 		  else if (TYPE_QUALS (t.spec) != TYPE_UNQUALIFIED)
3052 		    error_at (loc, "%<_Atomic%> applied to a qualified type");
3053 		  else
3054 		    t.spec = c_build_qualified_type (t.spec, TYPE_QUAL_ATOMIC);
3055 		}
3056 	      declspecs_add_type (loc, specs, t);
3057 	    }
3058 	  else
3059 	    declspecs_add_qual (loc, specs, value);
3060 	  break;
3061 	case RID_CONST:
3062 	case RID_VOLATILE:
3063 	case RID_RESTRICT:
3064 	  attrs_ok = true;
3065 	  declspecs_add_qual (loc, specs, c_parser_peek_token (parser)->value);
3066 	  c_parser_consume_token (parser);
3067 	  break;
3068 	case RID_ATTRIBUTE:
3069 	  if (!attrs_ok)
3070 	    goto out;
3071 	  attrs = c_parser_gnu_attributes (parser);
3072 	  declspecs_add_attrs (loc, specs, attrs);
3073 	  break;
3074 	case RID_ALIGNAS:
3075 	  if (!alignspec_ok)
3076 	    goto out;
3077 	  align = c_parser_alignas_specifier (parser);
3078 	  declspecs_add_alignas (loc, specs, align);
3079 	  break;
3080 	case RID_GIMPLE:
3081 	  if (! flag_gimple)
3082 	    error_at (loc, "%<__GIMPLE%> only valid with %<-fgimple%>");
3083 	  c_parser_consume_token (parser);
3084 	  specs->declspec_il = cdil_gimple;
3085 	  specs->locations[cdw_gimple] = loc;
3086 	  c_parser_gimple_or_rtl_pass_list (parser, specs);
3087 	  break;
3088 	case RID_RTL:
3089 	  c_parser_consume_token (parser);
3090 	  specs->declspec_il = cdil_rtl;
3091 	  specs->locations[cdw_rtl] = loc;
3092 	  c_parser_gimple_or_rtl_pass_list (parser, specs);
3093 	  break;
3094 	default:
3095 	  goto out;
3096 	}
3097     }
3098  out:
3099   if (end_std_attr_ok
3100       && c_parser_nth_token_starts_std_attributes (parser, 1))
3101     specs->postfix_attrs = c_parser_std_attribute_specifier_sequence (parser);
3102 }
3103 
3104 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
3105 
3106    enum-specifier:
3107      enum gnu-attributes[opt] identifier[opt] { enumerator-list }
3108        gnu-attributes[opt]
3109      enum gnu-attributes[opt] identifier[opt] { enumerator-list , }
3110        gnu-attributes[opt]
3111      enum gnu-attributes[opt] identifier
3112 
3113    The form with trailing comma is new in C99.  The forms with
3114    gnu-attributes are GNU extensions.  In GNU C, we accept any expression
3115    without commas in the syntax (assignment expressions, not just
3116    conditional expressions); assignment expressions will be diagnosed
3117    as non-constant.
3118 
3119    enumerator-list:
3120      enumerator
3121      enumerator-list , enumerator
3122 
3123    enumerator:
3124      enumeration-constant attribute-specifier-sequence[opt]
3125      enumeration-constant attribute-specifier-sequence[opt]
3126        = constant-expression
3127 
3128    GNU Extensions:
3129 
3130    enumerator:
3131      enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3132      enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3133        = constant-expression
3134 
3135 */
3136 
3137 static struct c_typespec
c_parser_enum_specifier(c_parser * parser)3138 c_parser_enum_specifier (c_parser *parser)
3139 {
3140   struct c_typespec ret;
3141   bool have_std_attrs;
3142   tree std_attrs = NULL_TREE;
3143   tree attrs;
3144   tree ident = NULL_TREE;
3145   location_t enum_loc;
3146   location_t ident_loc = UNKNOWN_LOCATION;  /* Quiet warning.  */
3147   gcc_assert (c_parser_next_token_is_keyword (parser, RID_ENUM));
3148   c_parser_consume_token (parser);
3149   have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3150   if (have_std_attrs)
3151     std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3152   attrs = c_parser_gnu_attributes (parser);
3153   enum_loc = c_parser_peek_token (parser)->location;
3154   /* Set the location in case we create a decl now.  */
3155   c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3156   if (c_parser_next_token_is (parser, CPP_NAME))
3157     {
3158       ident = c_parser_peek_token (parser)->value;
3159       ident_loc = c_parser_peek_token (parser)->location;
3160       enum_loc = ident_loc;
3161       c_parser_consume_token (parser);
3162     }
3163   if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3164     {
3165       /* Parse an enum definition.  */
3166       struct c_enum_contents the_enum;
3167       tree type;
3168       tree postfix_attrs;
3169       /* We chain the enumerators in reverse order, then put them in
3170 	 forward order at the end.  */
3171       tree values;
3172       timevar_push (TV_PARSE_ENUM);
3173       type = start_enum (enum_loc, &the_enum, ident);
3174       values = NULL_TREE;
3175       c_parser_consume_token (parser);
3176       while (true)
3177 	{
3178 	  tree enum_id;
3179 	  tree enum_value;
3180 	  tree enum_decl;
3181 	  bool seen_comma;
3182 	  c_token *token;
3183 	  location_t comma_loc = UNKNOWN_LOCATION;  /* Quiet warning.  */
3184 	  location_t decl_loc, value_loc;
3185 	  if (c_parser_next_token_is_not (parser, CPP_NAME))
3186 	    {
3187 	      /* Give a nicer error for "enum {}".  */
3188 	      if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3189 		  && !parser->error)
3190 		{
3191 		  error_at (c_parser_peek_token (parser)->location,
3192 			    "empty enum is invalid");
3193 		  parser->error = true;
3194 		}
3195 	      else
3196 		c_parser_error (parser, "expected identifier");
3197 	      c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3198 	      values = error_mark_node;
3199 	      break;
3200 	    }
3201 	  token = c_parser_peek_token (parser);
3202 	  enum_id = token->value;
3203 	  /* Set the location in case we create a decl now.  */
3204 	  c_parser_set_source_position_from_token (token);
3205 	  decl_loc = value_loc = token->location;
3206 	  c_parser_consume_token (parser);
3207 	  /* Parse any specified attributes.  */
3208 	  tree std_attrs = NULL_TREE;
3209 	  if (c_parser_nth_token_starts_std_attributes (parser, 1))
3210 	    std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3211 	  tree enum_attrs = chainon (std_attrs,
3212 				     c_parser_gnu_attributes (parser));
3213 	  if (c_parser_next_token_is (parser, CPP_EQ))
3214 	    {
3215 	      c_parser_consume_token (parser);
3216 	      value_loc = c_parser_peek_token (parser)->location;
3217 	      enum_value = c_parser_expr_no_commas (parser, NULL).value;
3218 	    }
3219 	  else
3220 	    enum_value = NULL_TREE;
3221 	  enum_decl = build_enumerator (decl_loc, value_loc,
3222 					&the_enum, enum_id, enum_value);
3223 	  if (enum_attrs)
3224 	    decl_attributes (&TREE_PURPOSE (enum_decl), enum_attrs, 0);
3225 	  TREE_CHAIN (enum_decl) = values;
3226 	  values = enum_decl;
3227 	  seen_comma = false;
3228 	  if (c_parser_next_token_is (parser, CPP_COMMA))
3229 	    {
3230 	      comma_loc = c_parser_peek_token (parser)->location;
3231 	      seen_comma = true;
3232 	      c_parser_consume_token (parser);
3233 	    }
3234 	  if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3235 	    {
3236 	      if (seen_comma)
3237 		pedwarn_c90 (comma_loc, OPT_Wpedantic,
3238 			     "comma at end of enumerator list");
3239 	      c_parser_consume_token (parser);
3240 	      break;
3241 	    }
3242 	  if (!seen_comma)
3243 	    {
3244 	      c_parser_error (parser, "expected %<,%> or %<}%>");
3245 	      c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3246 	      values = error_mark_node;
3247 	      break;
3248 	    }
3249 	}
3250       postfix_attrs = c_parser_gnu_attributes (parser);
3251       ret.spec = finish_enum (type, nreverse (values),
3252 			      chainon (std_attrs,
3253 				       chainon (attrs, postfix_attrs)));
3254       ret.kind = ctsk_tagdef;
3255       ret.expr = NULL_TREE;
3256       ret.expr_const_operands = true;
3257       timevar_pop (TV_PARSE_ENUM);
3258       return ret;
3259     }
3260   else if (!ident)
3261     {
3262       c_parser_error (parser, "expected %<{%>");
3263       ret.spec = error_mark_node;
3264       ret.kind = ctsk_tagref;
3265       ret.expr = NULL_TREE;
3266       ret.expr_const_operands = true;
3267       return ret;
3268     }
3269   /* Attributes may only appear when the members are defined or in
3270      certain forward declarations (treat enum forward declarations in
3271      GNU C analogously to struct and union forward declarations in
3272      standard C).  */
3273   if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3274     c_parser_error (parser, "expected %<;%>");
3275   ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident, have_std_attrs,
3276 			 std_attrs);
3277   /* In ISO C, enumerated types can be referred to only if already
3278      defined.  */
3279   if (pedantic && !COMPLETE_TYPE_P (ret.spec))
3280     {
3281       gcc_assert (ident);
3282       pedwarn (enum_loc, OPT_Wpedantic,
3283 	       "ISO C forbids forward references to %<enum%> types");
3284     }
3285   return ret;
3286 }
3287 
3288 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3289 
3290    struct-or-union-specifier:
3291      struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3292        identifier[opt] { struct-contents } gnu-attributes[opt]
3293      struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3294        identifier
3295 
3296    struct-contents:
3297      struct-declaration-list
3298 
3299    struct-declaration-list:
3300      struct-declaration ;
3301      struct-declaration-list struct-declaration ;
3302 
3303    GNU extensions:
3304 
3305    struct-contents:
3306      empty
3307      struct-declaration
3308      struct-declaration-list struct-declaration
3309 
3310    struct-declaration-list:
3311      struct-declaration-list ;
3312      ;
3313 
3314    (Note that in the syntax here, unlike that in ISO C, the semicolons
3315    are included here rather than in struct-declaration, in order to
3316    describe the syntax with extra semicolons and missing semicolon at
3317    end.)
3318 
3319    Objective-C:
3320 
3321    struct-declaration-list:
3322      @defs ( class-name )
3323 
3324    (Note this does not include a trailing semicolon, but can be
3325    followed by further declarations, and gets a pedwarn-if-pedantic
3326    when followed by a semicolon.)  */
3327 
3328 static struct c_typespec
c_parser_struct_or_union_specifier(c_parser * parser)3329 c_parser_struct_or_union_specifier (c_parser *parser)
3330 {
3331   struct c_typespec ret;
3332   bool have_std_attrs;
3333   tree std_attrs = NULL_TREE;
3334   tree attrs;
3335   tree ident = NULL_TREE;
3336   location_t struct_loc;
3337   location_t ident_loc = UNKNOWN_LOCATION;
3338   enum tree_code code;
3339   switch (c_parser_peek_token (parser)->keyword)
3340     {
3341     case RID_STRUCT:
3342       code = RECORD_TYPE;
3343       break;
3344     case RID_UNION:
3345       code = UNION_TYPE;
3346       break;
3347     default:
3348       gcc_unreachable ();
3349     }
3350   struct_loc = c_parser_peek_token (parser)->location;
3351   c_parser_consume_token (parser);
3352   have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3353   if (have_std_attrs)
3354     std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3355   attrs = c_parser_gnu_attributes (parser);
3356 
3357   /* Set the location in case we create a decl now.  */
3358   c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3359 
3360   if (c_parser_next_token_is (parser, CPP_NAME))
3361     {
3362       ident = c_parser_peek_token (parser)->value;
3363       ident_loc = c_parser_peek_token (parser)->location;
3364       struct_loc = ident_loc;
3365       c_parser_consume_token (parser);
3366     }
3367   if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3368     {
3369       /* Parse a struct or union definition.  Start the scope of the
3370 	 tag before parsing components.  */
3371       class c_struct_parse_info *struct_info;
3372       tree type = start_struct (struct_loc, code, ident, &struct_info);
3373       tree postfix_attrs;
3374       /* We chain the components in reverse order, then put them in
3375 	 forward order at the end.  Each struct-declaration may
3376 	 declare multiple components (comma-separated), so we must use
3377 	 chainon to join them, although when parsing each
3378 	 struct-declaration we can use TREE_CHAIN directly.
3379 
3380 	 The theory behind all this is that there will be more
3381 	 semicolon separated fields than comma separated fields, and
3382 	 so we'll be minimizing the number of node traversals required
3383 	 by chainon.  */
3384       tree contents;
3385       timevar_push (TV_PARSE_STRUCT);
3386       contents = NULL_TREE;
3387       c_parser_consume_token (parser);
3388       /* Handle the Objective-C @defs construct,
3389 	 e.g. foo(sizeof(struct{ @defs(ClassName) }));.  */
3390       if (c_parser_next_token_is_keyword (parser, RID_AT_DEFS))
3391 	{
3392 	  tree name;
3393 	  gcc_assert (c_dialect_objc ());
3394 	  c_parser_consume_token (parser);
3395 	  matching_parens parens;
3396 	  if (!parens.require_open (parser))
3397 	    goto end_at_defs;
3398 	  if (c_parser_next_token_is (parser, CPP_NAME)
3399 	      && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)
3400 	    {
3401 	      name = c_parser_peek_token (parser)->value;
3402 	      c_parser_consume_token (parser);
3403 	    }
3404 	  else
3405 	    {
3406 	      c_parser_error (parser, "expected class name");
3407 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
3408 	      goto end_at_defs;
3409 	    }
3410 	  parens.skip_until_found_close (parser);
3411 	  contents = nreverse (objc_get_class_ivars (name));
3412 	}
3413     end_at_defs:
3414       /* Parse the struct-declarations and semicolons.  Problems with
3415 	 semicolons are diagnosed here; empty structures are diagnosed
3416 	 elsewhere.  */
3417       while (true)
3418 	{
3419 	  tree decls;
3420 	  /* Parse any stray semicolon.  */
3421 	  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3422 	    {
3423 	      location_t semicolon_loc
3424 		= c_parser_peek_token (parser)->location;
3425 	      gcc_rich_location richloc (semicolon_loc);
3426 	      richloc.add_fixit_remove ();
3427 	      pedwarn (&richloc, OPT_Wpedantic,
3428 		       "extra semicolon in struct or union specified");
3429 	      c_parser_consume_token (parser);
3430 	      continue;
3431 	    }
3432 	  /* Stop if at the end of the struct or union contents.  */
3433 	  if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3434 	    {
3435 	      c_parser_consume_token (parser);
3436 	      break;
3437 	    }
3438 	  /* Accept #pragmas at struct scope.  */
3439 	  if (c_parser_next_token_is (parser, CPP_PRAGMA))
3440 	    {
3441 	      c_parser_pragma (parser, pragma_struct, NULL);
3442 	      continue;
3443 	    }
3444 	  /* Parse some comma-separated declarations, but not the
3445 	     trailing semicolon if any.  */
3446 	  decls = c_parser_struct_declaration (parser);
3447 	  contents = chainon (decls, contents);
3448 	  /* If no semicolon follows, either we have a parse error or
3449 	     are at the end of the struct or union and should
3450 	     pedwarn.  */
3451 	  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3452 	    c_parser_consume_token (parser);
3453 	  else
3454 	    {
3455 	      if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3456 		pedwarn (c_parser_peek_token (parser)->location, 0,
3457 			 "no semicolon at end of struct or union");
3458 	      else if (parser->error
3459 		       || !c_parser_next_token_starts_declspecs (parser))
3460 		{
3461 		  c_parser_error (parser, "expected %<;%>");
3462 		  c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3463 		  break;
3464 		}
3465 
3466 	      /* If we come here, we have already emitted an error
3467 		 for an expected `;', identifier or `(', and we also
3468 	         recovered already.  Go on with the next field. */
3469 	    }
3470 	}
3471       postfix_attrs = c_parser_gnu_attributes (parser);
3472       ret.spec = finish_struct (struct_loc, type, nreverse (contents),
3473 				chainon (std_attrs,
3474 					 chainon (attrs, postfix_attrs)),
3475 				struct_info);
3476       ret.kind = ctsk_tagdef;
3477       ret.expr = NULL_TREE;
3478       ret.expr_const_operands = true;
3479       timevar_pop (TV_PARSE_STRUCT);
3480       return ret;
3481     }
3482   else if (!ident)
3483     {
3484       c_parser_error (parser, "expected %<{%>");
3485       ret.spec = error_mark_node;
3486       ret.kind = ctsk_tagref;
3487       ret.expr = NULL_TREE;
3488       ret.expr_const_operands = true;
3489       return ret;
3490     }
3491   /* Attributes may only appear when the members are defined or in
3492      certain forward declarations.  */
3493   if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3494     c_parser_error (parser, "expected %<;%>");
3495   /* ??? Existing practice is that GNU attributes are ignored after
3496      the struct or union keyword when not defining the members.  */
3497   ret = parser_xref_tag (ident_loc, code, ident, have_std_attrs, std_attrs);
3498   return ret;
3499 }
3500 
3501 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
3502    *without* the trailing semicolon.
3503 
3504    struct-declaration:
3505      attribute-specifier-sequence[opt] specifier-qualifier-list
3506        attribute-specifier-sequence[opt] struct-declarator-list
3507      static_assert-declaration-no-semi
3508 
3509    specifier-qualifier-list:
3510      type-specifier specifier-qualifier-list[opt]
3511      type-qualifier specifier-qualifier-list[opt]
3512      alignment-specifier specifier-qualifier-list[opt]
3513      gnu-attributes specifier-qualifier-list[opt]
3514 
3515    struct-declarator-list:
3516      struct-declarator
3517      struct-declarator-list , gnu-attributes[opt] struct-declarator
3518 
3519    struct-declarator:
3520      declarator gnu-attributes[opt]
3521      declarator[opt] : constant-expression gnu-attributes[opt]
3522 
3523    GNU extensions:
3524 
3525    struct-declaration:
3526      __extension__ struct-declaration
3527      specifier-qualifier-list
3528 
3529    Unlike the ISO C syntax, semicolons are handled elsewhere.  The use
3530    of gnu-attributes where shown is a GNU extension.  In GNU C, we accept
3531    any expression without commas in the syntax (assignment
3532    expressions, not just conditional expressions); assignment
3533    expressions will be diagnosed as non-constant.  */
3534 
3535 static tree
c_parser_struct_declaration(c_parser * parser)3536 c_parser_struct_declaration (c_parser *parser)
3537 {
3538   struct c_declspecs *specs;
3539   tree prefix_attrs;
3540   tree all_prefix_attrs;
3541   tree decls;
3542   location_t decl_loc;
3543   if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
3544     {
3545       int ext;
3546       tree decl;
3547       ext = disable_extension_diagnostics ();
3548       c_parser_consume_token (parser);
3549       decl = c_parser_struct_declaration (parser);
3550       restore_extension_diagnostics (ext);
3551       return decl;
3552     }
3553   if (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
3554     {
3555       c_parser_static_assert_declaration_no_semi (parser);
3556       return NULL_TREE;
3557     }
3558   specs = build_null_declspecs ();
3559   decl_loc = c_parser_peek_token (parser)->location;
3560   /* Strictly by the standard, we shouldn't allow _Alignas here,
3561      but it appears to have been intended to allow it there, so
3562      we're keeping it as it is until WG14 reaches a conclusion
3563      of N1731.
3564      <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf>  */
3565   c_parser_declspecs (parser, specs, false, true, true,
3566 		      true, false, true, true, cla_nonabstract_decl);
3567   if (parser->error)
3568     return NULL_TREE;
3569   if (!specs->declspecs_seen_p)
3570     {
3571       c_parser_error (parser, "expected specifier-qualifier-list");
3572       return NULL_TREE;
3573     }
3574   finish_declspecs (specs);
3575   if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3576       || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3577     {
3578       tree ret;
3579       if (specs->typespec_kind == ctsk_none)
3580 	{
3581 	  pedwarn (decl_loc, OPT_Wpedantic,
3582 		   "ISO C forbids member declarations with no members");
3583 	  shadow_tag_warned (specs, pedantic);
3584 	  ret = NULL_TREE;
3585 	}
3586       else
3587 	{
3588 	  /* Support for unnamed structs or unions as members of
3589 	     structs or unions (which is [a] useful and [b] supports
3590 	     MS P-SDK).  */
3591 	  tree attrs = NULL;
3592 
3593 	  ret = grokfield (c_parser_peek_token (parser)->location,
3594 			   build_id_declarator (NULL_TREE), specs,
3595 			   NULL_TREE, &attrs);
3596 	  if (ret)
3597 	    decl_attributes (&ret, attrs, 0);
3598 	}
3599       return ret;
3600     }
3601 
3602   /* Provide better error recovery.  Note that a type name here is valid,
3603      and will be treated as a field name.  */
3604   if (specs->typespec_kind == ctsk_tagdef
3605       && TREE_CODE (specs->type) != ENUMERAL_TYPE
3606       && c_parser_next_token_starts_declspecs (parser)
3607       && !c_parser_next_token_is (parser, CPP_NAME))
3608     {
3609       c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
3610       parser->error = false;
3611       return NULL_TREE;
3612     }
3613 
3614   pending_xref_error ();
3615   prefix_attrs = specs->attrs;
3616   all_prefix_attrs = prefix_attrs;
3617   specs->attrs = NULL_TREE;
3618   decls = NULL_TREE;
3619   while (true)
3620     {
3621       /* Declaring one or more declarators or un-named bit-fields.  */
3622       struct c_declarator *declarator;
3623       bool dummy = false;
3624       if (c_parser_next_token_is (parser, CPP_COLON))
3625 	declarator = build_id_declarator (NULL_TREE);
3626       else
3627 	declarator = c_parser_declarator (parser,
3628 					  specs->typespec_kind != ctsk_none,
3629 					  C_DTR_NORMAL, &dummy);
3630       if (declarator == NULL)
3631 	{
3632 	  c_parser_skip_to_end_of_block_or_statement (parser);
3633 	  break;
3634 	}
3635       if (c_parser_next_token_is (parser, CPP_COLON)
3636 	  || c_parser_next_token_is (parser, CPP_COMMA)
3637 	  || c_parser_next_token_is (parser, CPP_SEMICOLON)
3638 	  || c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3639 	  || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3640 	{
3641 	  tree postfix_attrs = NULL_TREE;
3642 	  tree width = NULL_TREE;
3643 	  tree d;
3644 	  if (c_parser_next_token_is (parser, CPP_COLON))
3645 	    {
3646 	      c_parser_consume_token (parser);
3647 	      width = c_parser_expr_no_commas (parser, NULL).value;
3648 	    }
3649 	  if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3650 	    postfix_attrs = c_parser_gnu_attributes (parser);
3651 	  d = grokfield (c_parser_peek_token (parser)->location,
3652 			 declarator, specs, width, &all_prefix_attrs);
3653 	  decl_attributes (&d, chainon (postfix_attrs,
3654 					all_prefix_attrs), 0);
3655 	  DECL_CHAIN (d) = decls;
3656 	  decls = d;
3657 	  if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3658 	    all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
3659 					prefix_attrs);
3660 	  else
3661 	    all_prefix_attrs = prefix_attrs;
3662 	  if (c_parser_next_token_is (parser, CPP_COMMA))
3663 	    c_parser_consume_token (parser);
3664 	  else if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3665 		   || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3666 	    {
3667 	      /* Semicolon consumed in caller.  */
3668 	      break;
3669 	    }
3670 	  else
3671 	    {
3672 	      c_parser_error (parser, "expected %<,%>, %<;%> or %<}%>");
3673 	      break;
3674 	    }
3675 	}
3676       else
3677 	{
3678 	  c_parser_error (parser,
3679 			  "expected %<:%>, %<,%>, %<;%>, %<}%> or "
3680 			  "%<__attribute__%>");
3681 	  break;
3682 	}
3683     }
3684   return decls;
3685 }
3686 
3687 /* Parse a typeof specifier (a GNU extension).
3688 
3689    typeof-specifier:
3690      typeof ( expression )
3691      typeof ( type-name )
3692 */
3693 
3694 static struct c_typespec
c_parser_typeof_specifier(c_parser * parser)3695 c_parser_typeof_specifier (c_parser *parser)
3696 {
3697   struct c_typespec ret;
3698   ret.kind = ctsk_typeof;
3699   ret.spec = error_mark_node;
3700   ret.expr = NULL_TREE;
3701   ret.expr_const_operands = true;
3702   gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF));
3703   c_parser_consume_token (parser);
3704   c_inhibit_evaluation_warnings++;
3705   in_typeof++;
3706   matching_parens parens;
3707   if (!parens.require_open (parser))
3708     {
3709       c_inhibit_evaluation_warnings--;
3710       in_typeof--;
3711       return ret;
3712     }
3713   if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
3714     {
3715       struct c_type_name *type = c_parser_type_name (parser);
3716       c_inhibit_evaluation_warnings--;
3717       in_typeof--;
3718       if (type != NULL)
3719 	{
3720 	  ret.spec = groktypename (type, &ret.expr, &ret.expr_const_operands);
3721 	  pop_maybe_used (variably_modified_type_p (ret.spec, NULL_TREE));
3722 	}
3723     }
3724   else
3725     {
3726       bool was_vm;
3727       location_t here = c_parser_peek_token (parser)->location;
3728       struct c_expr expr = c_parser_expression (parser);
3729       c_inhibit_evaluation_warnings--;
3730       in_typeof--;
3731       if (TREE_CODE (expr.value) == COMPONENT_REF
3732 	  && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
3733 	error_at (here, "%<typeof%> applied to a bit-field");
3734       mark_exp_read (expr.value);
3735       ret.spec = TREE_TYPE (expr.value);
3736       was_vm = variably_modified_type_p (ret.spec, NULL_TREE);
3737       /* This is returned with the type so that when the type is
3738 	 evaluated, this can be evaluated.  */
3739       if (was_vm)
3740 	ret.expr = c_fully_fold (expr.value, false, &ret.expr_const_operands);
3741       pop_maybe_used (was_vm);
3742     }
3743   parens.skip_until_found_close (parser);
3744   return ret;
3745 }
3746 
3747 /* Parse an alignment-specifier.
3748 
3749    C11 6.7.5:
3750 
3751    alignment-specifier:
3752      _Alignas ( type-name )
3753      _Alignas ( constant-expression )
3754 */
3755 
3756 static tree
c_parser_alignas_specifier(c_parser * parser)3757 c_parser_alignas_specifier (c_parser * parser)
3758 {
3759   tree ret = error_mark_node;
3760   location_t loc = c_parser_peek_token (parser)->location;
3761   gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNAS));
3762   c_parser_consume_token (parser);
3763   if (flag_isoc99)
3764     pedwarn_c99 (loc, OPT_Wpedantic,
3765 		 "ISO C99 does not support %<_Alignas%>");
3766   else
3767     pedwarn_c99 (loc, OPT_Wpedantic,
3768 		 "ISO C90 does not support %<_Alignas%>");
3769   matching_parens parens;
3770   if (!parens.require_open (parser))
3771     return ret;
3772   if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
3773     {
3774       struct c_type_name *type = c_parser_type_name (parser);
3775       if (type != NULL)
3776 	ret = c_sizeof_or_alignof_type (loc, groktypename (type, NULL, NULL),
3777 					false, true, 1);
3778     }
3779   else
3780     ret = c_parser_expr_no_commas (parser, NULL).value;
3781   parens.skip_until_found_close (parser);
3782   return ret;
3783 }
3784 
3785 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
3786    6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7).  If TYPE_SEEN_P then
3787    a typedef name may be redeclared; otherwise it may not.  KIND
3788    indicates which kind of declarator is wanted.  Returns a valid
3789    declarator except in the case of a syntax error in which case NULL is
3790    returned.  *SEEN_ID is set to true if an identifier being declared is
3791    seen; this is used to diagnose bad forms of abstract array declarators
3792    and to determine whether an identifier list is syntactically permitted.
3793 
3794    declarator:
3795      pointer[opt] direct-declarator
3796 
3797    direct-declarator:
3798      identifier
3799      ( gnu-attributes[opt] declarator )
3800      direct-declarator array-declarator
3801      direct-declarator ( parameter-type-list )
3802      direct-declarator ( identifier-list[opt] )
3803 
3804    pointer:
3805      * type-qualifier-list[opt]
3806      * type-qualifier-list[opt] pointer
3807 
3808    type-qualifier-list:
3809      type-qualifier
3810      gnu-attributes
3811      type-qualifier-list type-qualifier
3812      type-qualifier-list gnu-attributes
3813 
3814    array-declarator:
3815      [ type-qualifier-list[opt] assignment-expression[opt] ]
3816      [ static type-qualifier-list[opt] assignment-expression ]
3817      [ type-qualifier-list static assignment-expression ]
3818      [ type-qualifier-list[opt] * ]
3819 
3820    parameter-type-list:
3821      parameter-list
3822      parameter-list , ...
3823 
3824    parameter-list:
3825      parameter-declaration
3826      parameter-list , parameter-declaration
3827 
3828    parameter-declaration:
3829      declaration-specifiers declarator gnu-attributes[opt]
3830      declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
3831 
3832    identifier-list:
3833      identifier
3834      identifier-list , identifier
3835 
3836    abstract-declarator:
3837      pointer
3838      pointer[opt] direct-abstract-declarator
3839 
3840    direct-abstract-declarator:
3841      ( gnu-attributes[opt] abstract-declarator )
3842      direct-abstract-declarator[opt] array-declarator
3843      direct-abstract-declarator[opt] ( parameter-type-list[opt] )
3844 
3845    GNU extensions:
3846 
3847    direct-declarator:
3848      direct-declarator ( parameter-forward-declarations
3849 			 parameter-type-list[opt] )
3850 
3851    direct-abstract-declarator:
3852      direct-abstract-declarator[opt] ( parameter-forward-declarations
3853 				       parameter-type-list[opt] )
3854 
3855    parameter-forward-declarations:
3856      parameter-list ;
3857      parameter-forward-declarations parameter-list ;
3858 
3859    The uses of gnu-attributes shown above are GNU extensions.
3860 
3861    Some forms of array declarator are not included in C99 in the
3862    syntax for abstract declarators; these are disallowed elsewhere.
3863    This may be a defect (DR#289).
3864 
3865    This function also accepts an omitted abstract declarator as being
3866    an abstract declarator, although not part of the formal syntax.  */
3867 
3868 struct c_declarator *
c_parser_declarator(c_parser * parser,bool type_seen_p,c_dtr_syn kind,bool * seen_id)3869 c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
3870 		     bool *seen_id)
3871 {
3872   /* Parse any initial pointer part.  */
3873   if (c_parser_next_token_is (parser, CPP_MULT))
3874     {
3875       struct c_declspecs *quals_attrs = build_null_declspecs ();
3876       struct c_declarator *inner;
3877       c_parser_consume_token (parser);
3878       c_parser_declspecs (parser, quals_attrs, false, false, true,
3879 			  false, false, true, false, cla_prefer_id);
3880       inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
3881       if (inner == NULL)
3882 	return NULL;
3883       else
3884 	return make_pointer_declarator (quals_attrs, inner);
3885     }
3886   /* Now we have a direct declarator, direct abstract declarator or
3887      nothing (which counts as a direct abstract declarator here).  */
3888   return c_parser_direct_declarator (parser, type_seen_p, kind, seen_id);
3889 }
3890 
3891 /* Parse a direct declarator or direct abstract declarator; arguments
3892    as c_parser_declarator.  */
3893 
3894 static struct c_declarator *
c_parser_direct_declarator(c_parser * parser,bool type_seen_p,c_dtr_syn kind,bool * seen_id)3895 c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
3896 			    bool *seen_id)
3897 {
3898   /* The direct declarator must start with an identifier (possibly
3899      omitted) or a parenthesized declarator (possibly abstract).  In
3900      an ordinary declarator, initial parentheses must start a
3901      parenthesized declarator.  In an abstract declarator or parameter
3902      declarator, they could start a parenthesized declarator or a
3903      parameter list.  To tell which, the open parenthesis and any
3904      following gnu-attributes must be read.  If a declaration
3905      specifier or standard attributes follow, then it is a parameter
3906      list; if the specifier is a typedef name, there might be an
3907      ambiguity about redeclaring it, which is resolved in the
3908      direction of treating it as a typedef name.  If a close
3909      parenthesis follows, it is also an empty parameter list, as the
3910      syntax does not permit empty abstract declarators.  Otherwise, it
3911      is a parenthesized declarator (in which case the analysis may be
3912      repeated inside it, recursively).
3913 
3914      ??? There is an ambiguity in a parameter declaration "int
3915      (__attribute__((foo)) x)", where x is not a typedef name: it
3916      could be an abstract declarator for a function, or declare x with
3917      parentheses.  The proper resolution of this ambiguity needs
3918      documenting.  At present we follow an accident of the old
3919      parser's implementation, whereby the first parameter must have
3920      some declaration specifiers other than just gnu-attributes.  Thus as
3921      a parameter declaration it is treated as a parenthesized
3922      parameter named x, and as an abstract declarator it is
3923      rejected.
3924 
3925      ??? Also following the old parser, gnu-attributes inside an empty
3926      parameter list are ignored, making it a list not yielding a
3927      prototype, rather than giving an error or making it have one
3928      parameter with implicit type int.
3929 
3930      ??? Also following the old parser, typedef names may be
3931      redeclared in declarators, but not Objective-C class names.  */
3932 
3933   if (kind != C_DTR_ABSTRACT
3934       && c_parser_next_token_is (parser, CPP_NAME)
3935       && ((type_seen_p
3936 	   && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
3937 	       || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
3938 	  || c_parser_peek_token (parser)->id_kind == C_ID_ID))
3939     {
3940       struct c_declarator *inner
3941 	= build_id_declarator (c_parser_peek_token (parser)->value);
3942       *seen_id = true;
3943       inner->id_loc = c_parser_peek_token (parser)->location;
3944       c_parser_consume_token (parser);
3945       if (c_parser_nth_token_starts_std_attributes (parser, 1))
3946 	inner->u.id.attrs = c_parser_std_attribute_specifier_sequence (parser);
3947       return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3948     }
3949 
3950   if (kind != C_DTR_NORMAL
3951       && c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
3952       && !c_parser_nth_token_starts_std_attributes (parser, 1))
3953     {
3954       struct c_declarator *inner = build_id_declarator (NULL_TREE);
3955       inner->id_loc = c_parser_peek_token (parser)->location;
3956       return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3957     }
3958 
3959   /* Either we are at the end of an abstract declarator, or we have
3960      parentheses.  */
3961 
3962   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3963     {
3964       tree attrs;
3965       struct c_declarator *inner;
3966       c_parser_consume_token (parser);
3967       bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
3968 							    RID_ATTRIBUTE);
3969       attrs = c_parser_gnu_attributes (parser);
3970       if (kind != C_DTR_NORMAL
3971 	  && (c_parser_next_token_starts_declspecs (parser)
3972 	      || (!have_gnu_attrs
3973 		  && c_parser_nth_token_starts_std_attributes (parser, 1))
3974 	      || c_parser_next_token_is (parser, CPP_CLOSE_PAREN)))
3975 	{
3976 	  struct c_arg_info *args
3977 	    = c_parser_parms_declarator (parser, kind == C_DTR_NORMAL,
3978 					 attrs, have_gnu_attrs);
3979 	  if (args == NULL)
3980 	    return NULL;
3981 	  else
3982 	    {
3983 	      inner = build_id_declarator (NULL_TREE);
3984 	      if (!(args->types
3985 		    && args->types != error_mark_node
3986 		    && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
3987 		  && c_parser_nth_token_starts_std_attributes (parser, 1))
3988 		{
3989 		  tree std_attrs
3990 		    = c_parser_std_attribute_specifier_sequence (parser);
3991 		  if (std_attrs)
3992 		    inner = build_attrs_declarator (std_attrs, inner);
3993 		}
3994 	      inner = build_function_declarator (args, inner);
3995 	      return c_parser_direct_declarator_inner (parser, *seen_id,
3996 						       inner);
3997 	    }
3998 	}
3999       /* A parenthesized declarator.  */
4000       inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
4001       if (inner != NULL && attrs != NULL)
4002 	inner = build_attrs_declarator (attrs, inner);
4003       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4004 	{
4005 	  c_parser_consume_token (parser);
4006 	  if (inner == NULL)
4007 	    return NULL;
4008 	  else
4009 	    return c_parser_direct_declarator_inner (parser, *seen_id, inner);
4010 	}
4011       else
4012 	{
4013 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4014 				     "expected %<)%>");
4015 	  return NULL;
4016 	}
4017     }
4018   else
4019     {
4020       if (kind == C_DTR_NORMAL)
4021 	{
4022 	  c_parser_error (parser, "expected identifier or %<(%>");
4023 	  return NULL;
4024 	}
4025       else
4026 	return build_id_declarator (NULL_TREE);
4027     }
4028 }
4029 
4030 /* Parse part of a direct declarator or direct abstract declarator,
4031    given that some (in INNER) has already been parsed; ID_PRESENT is
4032    true if an identifier is present, false for an abstract
4033    declarator.  */
4034 
4035 static struct c_declarator *
c_parser_direct_declarator_inner(c_parser * parser,bool id_present,struct c_declarator * inner)4036 c_parser_direct_declarator_inner (c_parser *parser, bool id_present,
4037 				  struct c_declarator *inner)
4038 {
4039   /* Parse a sequence of array declarators and parameter lists.  */
4040   if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
4041       && !c_parser_nth_token_starts_std_attributes (parser, 1))
4042     {
4043       location_t brace_loc = c_parser_peek_token (parser)->location;
4044       struct c_declarator *declarator;
4045       struct c_declspecs *quals_attrs = build_null_declspecs ();
4046       bool static_seen;
4047       bool star_seen;
4048       struct c_expr dimen;
4049       dimen.value = NULL_TREE;
4050       dimen.original_code = ERROR_MARK;
4051       dimen.original_type = NULL_TREE;
4052       c_parser_consume_token (parser);
4053       c_parser_declspecs (parser, quals_attrs, false, false, true,
4054 			  false, false, false, false, cla_prefer_id);
4055       static_seen = c_parser_next_token_is_keyword (parser, RID_STATIC);
4056       if (static_seen)
4057 	c_parser_consume_token (parser);
4058       if (static_seen && !quals_attrs->declspecs_seen_p)
4059 	c_parser_declspecs (parser, quals_attrs, false, false, true,
4060 			    false, false, false, false, cla_prefer_id);
4061       if (!quals_attrs->declspecs_seen_p)
4062 	quals_attrs = NULL;
4063       /* If "static" is present, there must be an array dimension.
4064 	 Otherwise, there may be a dimension, "*", or no
4065 	 dimension.  */
4066       if (static_seen)
4067 	{
4068 	  star_seen = false;
4069 	  dimen = c_parser_expr_no_commas (parser, NULL);
4070 	}
4071       else
4072 	{
4073 	  if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4074 	    {
4075 	      dimen.value = NULL_TREE;
4076 	      star_seen = false;
4077 	    }
4078 	  else if (c_parser_next_token_is (parser, CPP_MULT))
4079 	    {
4080 	      if (c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_SQUARE)
4081 		{
4082 		  dimen.value = NULL_TREE;
4083 		  star_seen = true;
4084 		  c_parser_consume_token (parser);
4085 		}
4086 	      else
4087 		{
4088 		  star_seen = false;
4089 		  dimen = c_parser_expr_no_commas (parser, NULL);
4090 		}
4091 	    }
4092 	  else
4093 	    {
4094 	      star_seen = false;
4095 	      dimen = c_parser_expr_no_commas (parser, NULL);
4096 	    }
4097 	}
4098       if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4099 	c_parser_consume_token (parser);
4100       else
4101 	{
4102 	  c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
4103 				     "expected %<]%>");
4104 	  return NULL;
4105 	}
4106       if (dimen.value)
4107 	dimen = convert_lvalue_to_rvalue (brace_loc, dimen, true, true);
4108       declarator = build_array_declarator (brace_loc, dimen.value, quals_attrs,
4109 					   static_seen, star_seen);
4110       if (declarator == NULL)
4111 	return NULL;
4112       if (c_parser_nth_token_starts_std_attributes (parser, 1))
4113 	{
4114 	  tree std_attrs
4115 	    = c_parser_std_attribute_specifier_sequence (parser);
4116 	  if (std_attrs)
4117 	    inner = build_attrs_declarator (std_attrs, inner);
4118 	}
4119       inner = set_array_declarator_inner (declarator, inner);
4120       return c_parser_direct_declarator_inner (parser, id_present, inner);
4121     }
4122   else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
4123     {
4124       tree attrs;
4125       struct c_arg_info *args;
4126       c_parser_consume_token (parser);
4127       bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
4128 							    RID_ATTRIBUTE);
4129       attrs = c_parser_gnu_attributes (parser);
4130       args = c_parser_parms_declarator (parser, id_present, attrs,
4131 					have_gnu_attrs);
4132       if (args == NULL)
4133 	return NULL;
4134       else
4135 	{
4136 	  if (!(args->types
4137 		&& args->types != error_mark_node
4138 		&& TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
4139 	      && c_parser_nth_token_starts_std_attributes (parser, 1))
4140 	    {
4141 	      tree std_attrs
4142 		= c_parser_std_attribute_specifier_sequence (parser);
4143 	      if (std_attrs)
4144 		inner = build_attrs_declarator (std_attrs, inner);
4145 	    }
4146 	  inner = build_function_declarator (args, inner);
4147 	  return c_parser_direct_declarator_inner (parser, id_present, inner);
4148 	}
4149     }
4150   return inner;
4151 }
4152 
4153 /* Parse a parameter list or identifier list, including the closing
4154    parenthesis but not the opening one.  ATTRS are the gnu-attributes
4155    at the start of the list.  ID_LIST_OK is true if an identifier list
4156    is acceptable; such a list must not have attributes at the start.
4157    HAVE_GNU_ATTRS says whether any gnu-attributes (including empty
4158    attributes) were present (in which case standard attributes cannot
4159    occur).  */
4160 
4161 static struct c_arg_info *
c_parser_parms_declarator(c_parser * parser,bool id_list_ok,tree attrs,bool have_gnu_attrs)4162 c_parser_parms_declarator (c_parser *parser, bool id_list_ok, tree attrs,
4163 			   bool have_gnu_attrs)
4164 {
4165   push_scope ();
4166   declare_parm_level ();
4167   /* If the list starts with an identifier, it is an identifier list.
4168      Otherwise, it is either a prototype list or an empty list.  */
4169   if (id_list_ok
4170       && !attrs
4171       && c_parser_next_token_is (parser, CPP_NAME)
4172       && c_parser_peek_token (parser)->id_kind == C_ID_ID
4173 
4174       /* Look ahead to detect typos in type names.  */
4175       && c_parser_peek_2nd_token (parser)->type != CPP_NAME
4176       && c_parser_peek_2nd_token (parser)->type != CPP_MULT
4177       && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
4178       && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_SQUARE
4179       && c_parser_peek_2nd_token (parser)->type != CPP_KEYWORD)
4180     {
4181       tree list = NULL_TREE, *nextp = &list;
4182       while (c_parser_next_token_is (parser, CPP_NAME)
4183 	     && c_parser_peek_token (parser)->id_kind == C_ID_ID)
4184 	{
4185 	  *nextp = build_tree_list (NULL_TREE,
4186 				    c_parser_peek_token (parser)->value);
4187 	  nextp = & TREE_CHAIN (*nextp);
4188 	  c_parser_consume_token (parser);
4189 	  if (c_parser_next_token_is_not (parser, CPP_COMMA))
4190 	    break;
4191 	  c_parser_consume_token (parser);
4192 	  if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4193 	    {
4194 	      c_parser_error (parser, "expected identifier");
4195 	      break;
4196 	    }
4197 	}
4198       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4199 	{
4200 	  struct c_arg_info *ret = build_arg_info ();
4201 	  ret->types = list;
4202 	  c_parser_consume_token (parser);
4203 	  pop_scope ();
4204 	  return ret;
4205 	}
4206       else
4207 	{
4208 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4209 				     "expected %<)%>");
4210 	  pop_scope ();
4211 	  return NULL;
4212 	}
4213     }
4214   else
4215     {
4216       struct c_arg_info *ret
4217 	= c_parser_parms_list_declarator (parser, attrs, NULL, have_gnu_attrs);
4218       pop_scope ();
4219       return ret;
4220     }
4221 }
4222 
4223 /* Parse a parameter list (possibly empty), including the closing
4224    parenthesis but not the opening one.  ATTRS are the gnu-attributes
4225    at the start of the list; if HAVE_GNU_ATTRS, there were some such
4226    attributes (possibly empty, in which case ATTRS is NULL_TREE),
4227    which means standard attributes cannot start the list.  EXPR is
4228    NULL or an expression that needs to be evaluated for the side
4229    effects of array size expressions in the parameters.  */
4230 
4231 static struct c_arg_info *
c_parser_parms_list_declarator(c_parser * parser,tree attrs,tree expr,bool have_gnu_attrs)4232 c_parser_parms_list_declarator (c_parser *parser, tree attrs, tree expr,
4233 				bool have_gnu_attrs)
4234 {
4235   bool bad_parm = false;
4236 
4237   /* ??? Following the old parser, forward parameter declarations may
4238      use abstract declarators, and if no real parameter declarations
4239      follow the forward declarations then this is not diagnosed.  Also
4240      note as above that gnu-attributes are ignored as the only contents of
4241      the parentheses, or as the only contents after forward
4242      declarations.  */
4243   if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4244     {
4245       struct c_arg_info *ret = build_arg_info ();
4246       c_parser_consume_token (parser);
4247       return ret;
4248     }
4249   if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4250     {
4251       struct c_arg_info *ret = build_arg_info ();
4252 
4253       if (flag_allow_parameterless_variadic_functions)
4254         {
4255           /* F (...) is allowed.  */
4256           ret->types = NULL_TREE;
4257         }
4258       else
4259         {
4260           /* Suppress -Wold-style-definition for this case.  */
4261           ret->types = error_mark_node;
4262           error_at (c_parser_peek_token (parser)->location,
4263                     "ISO C requires a named argument before %<...%>");
4264         }
4265       c_parser_consume_token (parser);
4266       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4267 	{
4268 	  c_parser_consume_token (parser);
4269 	  return ret;
4270 	}
4271       else
4272 	{
4273 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4274 				     "expected %<)%>");
4275 	  return NULL;
4276 	}
4277     }
4278   /* Nonempty list of parameters, either terminated with semicolon
4279      (forward declarations; recurse) or with close parenthesis (normal
4280      function) or with ", ... )" (variadic function).  */
4281   while (true)
4282     {
4283       /* Parse a parameter.  */
4284       struct c_parm *parm = c_parser_parameter_declaration (parser, attrs,
4285 							    have_gnu_attrs);
4286       attrs = NULL_TREE;
4287       have_gnu_attrs = false;
4288       if (parm == NULL)
4289 	bad_parm = true;
4290       else
4291 	push_parm_decl (parm, &expr);
4292       if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4293 	{
4294 	  tree new_attrs;
4295 	  c_parser_consume_token (parser);
4296 	  mark_forward_parm_decls ();
4297 	  bool new_have_gnu_attrs
4298 	    = c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE);
4299 	  new_attrs = c_parser_gnu_attributes (parser);
4300 	  return c_parser_parms_list_declarator (parser, new_attrs, expr,
4301 						 new_have_gnu_attrs);
4302 	}
4303       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4304 	{
4305 	  c_parser_consume_token (parser);
4306 	  if (bad_parm)
4307 	    return NULL;
4308 	  else
4309 	    return get_parm_info (false, expr);
4310 	}
4311       if (!c_parser_require (parser, CPP_COMMA,
4312 			     "expected %<;%>, %<,%> or %<)%>",
4313 			     UNKNOWN_LOCATION, false))
4314 	{
4315 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4316 	  return NULL;
4317 	}
4318       if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4319 	{
4320 	  c_parser_consume_token (parser);
4321 	  if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4322 	    {
4323 	      c_parser_consume_token (parser);
4324 	      if (bad_parm)
4325 		return NULL;
4326 	      else
4327 		return get_parm_info (true, expr);
4328 	    }
4329 	  else
4330 	    {
4331 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4332 					 "expected %<)%>");
4333 	      return NULL;
4334 	    }
4335 	}
4336     }
4337 }
4338 
4339 /* Parse a parameter declaration.  ATTRS are the gnu-attributes at the
4340    start of the declaration if it is the first parameter;
4341    HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even
4342    empty) there.  */
4343 
4344 static struct c_parm *
c_parser_parameter_declaration(c_parser * parser,tree attrs,bool have_gnu_attrs)4345 c_parser_parameter_declaration (c_parser *parser, tree attrs,
4346 				bool have_gnu_attrs)
4347 {
4348   struct c_declspecs *specs;
4349   struct c_declarator *declarator;
4350   tree prefix_attrs;
4351   tree postfix_attrs = NULL_TREE;
4352   bool dummy = false;
4353 
4354   /* Accept #pragmas between parameter declarations.  */
4355   while (c_parser_next_token_is (parser, CPP_PRAGMA))
4356     c_parser_pragma (parser, pragma_param, NULL);
4357 
4358   if (!c_parser_next_token_starts_declspecs (parser)
4359       && !c_parser_nth_token_starts_std_attributes (parser, 1))
4360     {
4361       c_token *token = c_parser_peek_token (parser);
4362       if (parser->error)
4363 	return NULL;
4364       c_parser_set_source_position_from_token (token);
4365       if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
4366 	{
4367 	  auto_diagnostic_group d;
4368 	  name_hint hint = lookup_name_fuzzy (token->value,
4369 					      FUZZY_LOOKUP_TYPENAME,
4370 					      token->location);
4371 	  if (const char *suggestion = hint.suggestion ())
4372 	    {
4373 	      gcc_rich_location richloc (token->location);
4374 	      richloc.add_fixit_replace (suggestion);
4375 	      error_at (&richloc,
4376 			"unknown type name %qE; did you mean %qs?",
4377 			token->value, suggestion);
4378 	    }
4379 	  else
4380 	    error_at (token->location, "unknown type name %qE", token->value);
4381 	  parser->error = true;
4382 	}
4383       /* ??? In some Objective-C cases '...' isn't applicable so there
4384 	 should be a different message.  */
4385       else
4386 	c_parser_error (parser,
4387 			"expected declaration specifiers or %<...%>");
4388       c_parser_skip_to_end_of_parameter (parser);
4389       return NULL;
4390     }
4391 
4392   location_t start_loc = c_parser_peek_token (parser)->location;
4393 
4394   specs = build_null_declspecs ();
4395   if (attrs)
4396     {
4397       declspecs_add_attrs (input_location, specs, attrs);
4398       attrs = NULL_TREE;
4399     }
4400   c_parser_declspecs (parser, specs, true, true, true, true, false,
4401 		      !have_gnu_attrs, true, cla_nonabstract_decl);
4402   finish_declspecs (specs);
4403   pending_xref_error ();
4404   prefix_attrs = specs->attrs;
4405   specs->attrs = NULL_TREE;
4406   declarator = c_parser_declarator (parser,
4407 				    specs->typespec_kind != ctsk_none,
4408 				    C_DTR_PARM, &dummy);
4409   if (declarator == NULL)
4410     {
4411       c_parser_skip_until_found (parser, CPP_COMMA, NULL);
4412       return NULL;
4413     }
4414   if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4415     postfix_attrs = c_parser_gnu_attributes (parser);
4416 
4417   /* Generate a location for the parameter, ranging from the start of the
4418      initial token to the end of the final token.
4419 
4420      If we have a identifier, then use it for the caret location, e.g.
4421 
4422        extern int callee (int one, int (*two)(int, int), float three);
4423                                    ~~~~~~^~~~~~~~~~~~~~
4424 
4425      otherwise, reuse the start location for the caret location e.g.:
4426 
4427        extern int callee (int one, int (*)(int, int), float three);
4428                                    ^~~~~~~~~~~~~~~~~
4429   */
4430   location_t end_loc = parser->last_token_location;
4431 
4432   /* Find any cdk_id declarator; determine if we have an identifier.  */
4433   c_declarator *id_declarator = declarator;
4434   while (id_declarator && id_declarator->kind != cdk_id)
4435     id_declarator = id_declarator->declarator;
4436   location_t caret_loc = (id_declarator->u.id.id
4437 			  ? id_declarator->id_loc
4438 			  : start_loc);
4439   location_t param_loc = make_location (caret_loc, start_loc, end_loc);
4440 
4441   return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
4442 		       declarator, param_loc);
4443 }
4444 
4445 /* Parse a string literal in an asm expression.  It should not be
4446    translated, and wide string literals are an error although
4447    permitted by the syntax.  This is a GNU extension.
4448 
4449    asm-string-literal:
4450      string-literal
4451 */
4452 
4453 static tree
c_parser_asm_string_literal(c_parser * parser)4454 c_parser_asm_string_literal (c_parser *parser)
4455 {
4456   tree str;
4457   int save_flag = warn_overlength_strings;
4458   warn_overlength_strings = 0;
4459   str = c_parser_string_literal (parser, false, false).value;
4460   warn_overlength_strings = save_flag;
4461   return str;
4462 }
4463 
4464 /* Parse a simple asm expression.  This is used in restricted
4465    contexts, where a full expression with inputs and outputs does not
4466    make sense.  This is a GNU extension.
4467 
4468    simple-asm-expr:
4469      asm ( asm-string-literal )
4470 */
4471 
4472 static tree
c_parser_simple_asm_expr(c_parser * parser)4473 c_parser_simple_asm_expr (c_parser *parser)
4474 {
4475   tree str;
4476   gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
4477   c_parser_consume_token (parser);
4478   matching_parens parens;
4479   if (!parens.require_open (parser))
4480     return NULL_TREE;
4481   str = c_parser_asm_string_literal (parser);
4482   if (!parens.require_close (parser))
4483     {
4484       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4485       return NULL_TREE;
4486     }
4487   return str;
4488 }
4489 
4490 static tree
c_parser_gnu_attribute_any_word(c_parser * parser)4491 c_parser_gnu_attribute_any_word (c_parser *parser)
4492 {
4493   tree attr_name = NULL_TREE;
4494 
4495   if (c_parser_next_token_is (parser, CPP_KEYWORD))
4496     {
4497       /* ??? See comment above about what keywords are accepted here.  */
4498       bool ok;
4499       switch (c_parser_peek_token (parser)->keyword)
4500 	{
4501 	case RID_STATIC:
4502 	case RID_UNSIGNED:
4503 	case RID_LONG:
4504 	case RID_CONST:
4505 	case RID_EXTERN:
4506 	case RID_REGISTER:
4507 	case RID_TYPEDEF:
4508 	case RID_SHORT:
4509 	case RID_INLINE:
4510 	case RID_NORETURN:
4511 	case RID_VOLATILE:
4512 	case RID_SIGNED:
4513 	case RID_AUTO:
4514 	case RID_RESTRICT:
4515 	case RID_COMPLEX:
4516 	case RID_THREAD:
4517 	case RID_INT:
4518 	case RID_CHAR:
4519 	case RID_FLOAT:
4520 	case RID_DOUBLE:
4521 	case RID_VOID:
4522 	case RID_DFLOAT32:
4523 	case RID_DFLOAT64:
4524 	case RID_DFLOAT128:
4525 	CASE_RID_FLOATN_NX:
4526 	case RID_BOOL:
4527 	case RID_FRACT:
4528 	case RID_ACCUM:
4529 	case RID_SAT:
4530 	case RID_TRANSACTION_ATOMIC:
4531 	case RID_TRANSACTION_CANCEL:
4532 	case RID_ATOMIC:
4533 	case RID_AUTO_TYPE:
4534 	case RID_INT_N_0:
4535 	case RID_INT_N_1:
4536 	case RID_INT_N_2:
4537 	case RID_INT_N_3:
4538 	  ok = true;
4539 	  break;
4540 	default:
4541 	  ok = false;
4542 	  break;
4543 	}
4544       if (!ok)
4545 	return NULL_TREE;
4546 
4547       /* Accept __attribute__((__const)) as __attribute__((const)) etc.  */
4548       attr_name = ridpointers[(int) c_parser_peek_token (parser)->keyword];
4549     }
4550   else if (c_parser_next_token_is (parser, CPP_NAME))
4551     attr_name = c_parser_peek_token (parser)->value;
4552 
4553   return attr_name;
4554 }
4555 
4556 /* Parse attribute arguments.  This is a common form of syntax
4557    covering all currently valid GNU and standard attributes.
4558 
4559    gnu-attribute-arguments:
4560      identifier
4561      identifier , nonempty-expr-list
4562      expr-list
4563 
4564    where the "identifier" must not be declared as a type.  ??? Why not
4565    allow identifiers declared as types to start the arguments?  */
4566 
4567 static tree
c_parser_attribute_arguments(c_parser * parser,bool takes_identifier,bool require_string,bool allow_empty_args)4568 c_parser_attribute_arguments (c_parser *parser, bool takes_identifier,
4569 			      bool require_string, bool allow_empty_args)
4570 {
4571   vec<tree, va_gc> *expr_list;
4572   tree attr_args;
4573   /* Parse the attribute contents.  If they start with an
4574      identifier which is followed by a comma or close
4575      parenthesis, then the arguments start with that
4576      identifier; otherwise they are an expression list.
4577      In objective-c the identifier may be a classname.  */
4578   if (c_parser_next_token_is (parser, CPP_NAME)
4579       && (c_parser_peek_token (parser)->id_kind == C_ID_ID
4580 	  || (c_dialect_objc ()
4581 	      && c_parser_peek_token (parser)->id_kind
4582 	      == C_ID_CLASSNAME))
4583       && ((c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
4584 	  || (c_parser_peek_2nd_token (parser)->type
4585 	      == CPP_CLOSE_PAREN))
4586       && (takes_identifier
4587 	  || (c_dialect_objc ()
4588 	      && c_parser_peek_token (parser)->id_kind
4589 	      == C_ID_CLASSNAME)))
4590     {
4591       tree arg1 = c_parser_peek_token (parser)->value;
4592       c_parser_consume_token (parser);
4593       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4594 	attr_args = build_tree_list (NULL_TREE, arg1);
4595       else
4596 	{
4597 	  tree tree_list;
4598 	  c_parser_consume_token (parser);
4599 	  expr_list = c_parser_expr_list (parser, false, true,
4600 					  NULL, NULL, NULL, NULL);
4601 	  tree_list = build_tree_list_vec (expr_list);
4602 	  attr_args = tree_cons (NULL_TREE, arg1, tree_list);
4603 	  release_tree_vector (expr_list);
4604 	}
4605     }
4606   else
4607     {
4608       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4609 	{
4610 	  if (!allow_empty_args)
4611 	    error_at (c_parser_peek_token (parser)->location,
4612 		      "parentheses must be omitted if "
4613 		      "attribute argument list is empty");
4614 	  attr_args = NULL_TREE;
4615 	}
4616       else if (require_string)
4617 	{
4618 	  /* The only valid argument for this attribute is a string
4619 	     literal.  Handle this specially here to avoid accepting
4620 	     string literals with excess parentheses.  */
4621 	  tree string = c_parser_string_literal (parser, false, true).value;
4622 	  attr_args = build_tree_list (NULL_TREE, string);
4623 	}
4624       else
4625 	{
4626 	  expr_list = c_parser_expr_list (parser, false, true,
4627 					  NULL, NULL, NULL, NULL);
4628 	  attr_args = build_tree_list_vec (expr_list);
4629 	  release_tree_vector (expr_list);
4630 	}
4631     }
4632   return attr_args;
4633 }
4634 
4635 /* Parse (possibly empty) gnu-attributes.  This is a GNU extension.
4636 
4637    gnu-attributes:
4638      empty
4639      gnu-attributes gnu-attribute
4640 
4641    gnu-attribute:
4642      __attribute__ ( ( gnu-attribute-list ) )
4643 
4644    gnu-attribute-list:
4645      gnu-attrib
4646      gnu-attribute_list , gnu-attrib
4647 
4648    gnu-attrib:
4649      empty
4650      any-word
4651      any-word ( gnu-attribute-arguments )
4652 
4653    where "any-word" may be any identifier (including one declared as a
4654    type), a reserved word storage class specifier, type specifier or
4655    type qualifier.  ??? This still leaves out most reserved keywords
4656    (following the old parser), shouldn't we include them?
4657    When EXPECT_COMMA is true, expect the attribute to be preceded
4658    by a comma and fail if it isn't.
4659    When EMPTY_OK is true, allow and consume any number of consecutive
4660    commas with no attributes in between.  */
4661 
4662 static tree
4663 c_parser_gnu_attribute (c_parser *parser, tree attrs,
4664 			bool expect_comma = false, bool empty_ok = true)
4665 {
4666   bool comma_first = c_parser_next_token_is (parser, CPP_COMMA);
4667   if (!comma_first
4668       && !c_parser_next_token_is (parser, CPP_NAME)
4669       && !c_parser_next_token_is (parser, CPP_KEYWORD))
4670     return NULL_TREE;
4671 
4672   while (c_parser_next_token_is (parser, CPP_COMMA))
4673     {
4674       c_parser_consume_token (parser);
4675       if (!empty_ok)
4676 	return attrs;
4677     }
4678 
4679   tree attr_name = c_parser_gnu_attribute_any_word (parser);
4680   if (attr_name == NULL_TREE)
4681     return NULL_TREE;
4682 
4683   attr_name = canonicalize_attr_name (attr_name);
4684   c_parser_consume_token (parser);
4685 
4686   tree attr;
4687   if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
4688     {
4689       if (expect_comma && !comma_first)
4690 	{
4691 	  /* A comma is missing between the last attribute on the chain
4692 	     and this one.  */
4693 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4694 				     "expected %<)%>");
4695 	  return error_mark_node;
4696 	}
4697       attr = build_tree_list (attr_name, NULL_TREE);
4698       /* Add this attribute to the list.  */
4699       attrs = chainon (attrs, attr);
4700       return attrs;
4701     }
4702   c_parser_consume_token (parser);
4703 
4704   tree attr_args
4705     = c_parser_attribute_arguments (parser,
4706 				    attribute_takes_identifier_p (attr_name),
4707 				    false, true);
4708 
4709   attr = build_tree_list (attr_name, attr_args);
4710   if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4711     c_parser_consume_token (parser);
4712   else
4713     {
4714       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4715 				 "expected %<)%>");
4716       return error_mark_node;
4717     }
4718 
4719   if (expect_comma && !comma_first)
4720     {
4721       /* A comma is missing between the last attribute on the chain
4722 	 and this one.  */
4723       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4724 				 "expected %<)%>");
4725       return error_mark_node;
4726     }
4727 
4728   /* Add this attribute to the list.  */
4729   attrs = chainon (attrs, attr);
4730   return attrs;
4731 }
4732 
4733 static tree
c_parser_gnu_attributes(c_parser * parser)4734 c_parser_gnu_attributes (c_parser *parser)
4735 {
4736   tree attrs = NULL_TREE;
4737   while (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4738     {
4739       bool save_translate_strings_p = parser->translate_strings_p;
4740       parser->translate_strings_p = false;
4741       /* Consume the `__attribute__' keyword.  */
4742       c_parser_consume_token (parser);
4743       /* Look for the two `(' tokens.  */
4744       if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4745 	{
4746 	  parser->translate_strings_p = save_translate_strings_p;
4747 	  return attrs;
4748 	}
4749       if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4750 	{
4751 	  parser->translate_strings_p = save_translate_strings_p;
4752 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4753 	  return attrs;
4754 	}
4755       /* Parse the attribute list.  Require a comma between successive
4756 	 (possibly empty) attributes.  */
4757       for (bool expect_comma = false; ; expect_comma = true)
4758 	{
4759 	  /* Parse a single attribute.  */
4760 	  tree attr = c_parser_gnu_attribute (parser, attrs, expect_comma);
4761 	  if (attr == error_mark_node)
4762 	    return attrs;
4763 	  if (!attr)
4764 	    break;
4765 	  attrs = attr;
4766       }
4767 
4768       /* Look for the two `)' tokens.  */
4769       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4770 	c_parser_consume_token (parser);
4771       else
4772 	{
4773 	  parser->translate_strings_p = save_translate_strings_p;
4774 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4775 				     "expected %<)%>");
4776 	  return attrs;
4777 	}
4778       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4779 	c_parser_consume_token (parser);
4780       else
4781 	{
4782 	  parser->translate_strings_p = save_translate_strings_p;
4783 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4784 				     "expected %<)%>");
4785 	  return attrs;
4786 	}
4787       parser->translate_strings_p = save_translate_strings_p;
4788     }
4789 
4790   return attrs;
4791 }
4792 
4793 /* Parse an optional balanced token sequence.
4794 
4795    balanced-token-sequence:
4796      balanced-token
4797      balanced-token-sequence balanced-token
4798 
4799    balanced-token:
4800      ( balanced-token-sequence[opt] )
4801      [ balanced-token-sequence[opt] ]
4802      { balanced-token-sequence[opt] }
4803      any token other than ()[]{}
4804 */
4805 
4806 static void
c_parser_balanced_token_sequence(c_parser * parser)4807 c_parser_balanced_token_sequence (c_parser *parser)
4808 {
4809   while (true)
4810     {
4811       c_token *token = c_parser_peek_token (parser);
4812       switch (token->type)
4813 	{
4814 	case CPP_OPEN_BRACE:
4815 	  {
4816 	    matching_braces braces;
4817 	    braces.consume_open (parser);
4818 	    c_parser_balanced_token_sequence (parser);
4819 	    braces.require_close (parser);
4820 	    break;
4821 	  }
4822 
4823 	case CPP_OPEN_PAREN:
4824 	  {
4825 	    matching_parens parens;
4826 	    parens.consume_open (parser);
4827 	    c_parser_balanced_token_sequence (parser);
4828 	    parens.require_close (parser);
4829 	    break;
4830 	  }
4831 
4832 	case CPP_OPEN_SQUARE:
4833 	  c_parser_consume_token (parser);
4834 	  c_parser_balanced_token_sequence (parser);
4835 	  c_parser_require (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
4836 	  break;
4837 
4838 	case CPP_CLOSE_BRACE:
4839 	case CPP_CLOSE_PAREN:
4840 	case CPP_CLOSE_SQUARE:
4841 	case CPP_EOF:
4842 	  return;
4843 
4844 	default:
4845 	  c_parser_consume_token (parser);
4846 	  break;
4847 	}
4848     }
4849 }
4850 
4851 /* Parse standard (C2X) attributes (including GNU attributes in the
4852    gnu:: namespace).
4853 
4854    attribute-specifier-sequence:
4855      attribute-specifier-sequence[opt] attribute-specifier
4856 
4857    attribute-specifier:
4858      [ [ attribute-list ] ]
4859 
4860    attribute-list:
4861      attribute[opt]
4862      attribute-list, attribute[opt]
4863 
4864    attribute:
4865      attribute-token attribute-argument-clause[opt]
4866 
4867    attribute-token:
4868      standard-attribute
4869      attribute-prefixed-token
4870 
4871    standard-attribute:
4872      identifier
4873 
4874    attribute-prefixed-token:
4875      attribute-prefix :: identifier
4876 
4877    attribute-prefix:
4878      identifier
4879 
4880    attribute-argument-clause:
4881      ( balanced-token-sequence[opt] )
4882 
4883    Keywords are accepted as identifiers for this purpose.
4884 */
4885 
4886 static tree
c_parser_std_attribute(c_parser * parser,bool for_tm)4887 c_parser_std_attribute (c_parser *parser, bool for_tm)
4888 {
4889   c_token *token = c_parser_peek_token (parser);
4890   tree ns, name, attribute;
4891 
4892   /* Parse the attribute-token.  */
4893   if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
4894     {
4895       c_parser_error (parser, "expected identifier");
4896       return error_mark_node;
4897     }
4898   name = canonicalize_attr_name (token->value);
4899   c_parser_consume_token (parser);
4900   if (c_parser_next_token_is (parser, CPP_SCOPE))
4901     {
4902       ns = name;
4903       c_parser_consume_token (parser);
4904       token = c_parser_peek_token (parser);
4905       if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
4906 	{
4907 	  c_parser_error (parser, "expected identifier");
4908 	  return error_mark_node;
4909 	}
4910       name = canonicalize_attr_name (token->value);
4911       c_parser_consume_token (parser);
4912     }
4913   else
4914     ns = NULL_TREE;
4915   attribute = build_tree_list (build_tree_list (ns, name), NULL_TREE);
4916 
4917   /* Parse the arguments, if any.  */
4918   const attribute_spec *as = lookup_attribute_spec (TREE_PURPOSE (attribute));
4919   if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
4920     goto out;
4921   {
4922     location_t open_loc = c_parser_peek_token (parser)->location;
4923     matching_parens parens;
4924     parens.consume_open (parser);
4925     if ((as && as->max_length == 0)
4926 	/* Special-case the transactional-memory attribute "outer",
4927 	   which is specially handled but not registered as an
4928 	   attribute, to avoid allowing arbitrary balanced token
4929 	   sequences as arguments.  */
4930 	|| is_attribute_p ("outer", name))
4931       {
4932 	error_at (open_loc, "%qE attribute does not take any arguments", name);
4933 	parens.skip_until_found_close (parser);
4934 	return error_mark_node;
4935       }
4936     if (as)
4937       {
4938 	bool takes_identifier
4939 	  = (ns != NULL_TREE
4940 	     && strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0
4941 	     && attribute_takes_identifier_p (name));
4942 	bool require_string
4943 	  = (ns == NULL_TREE
4944 	     && (strcmp (IDENTIFIER_POINTER (name), "deprecated") == 0
4945 		 || strcmp (IDENTIFIER_POINTER (name), "nodiscard") == 0));
4946 	TREE_VALUE (attribute)
4947 	  = c_parser_attribute_arguments (parser, takes_identifier,
4948 					  require_string, false);
4949       }
4950     else
4951       c_parser_balanced_token_sequence (parser);
4952     parens.require_close (parser);
4953   }
4954  out:
4955   if (ns == NULL_TREE && !for_tm && !as)
4956     {
4957       /* An attribute with standard syntax and no namespace specified
4958 	 is a constraint violation if it is not one of the known
4959 	 standard attributes.  Diagnose it here with a pedwarn and
4960 	 then discard it to prevent a duplicate warning later.  */
4961       pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored",
4962 	       name);
4963       return error_mark_node;
4964     }
4965   return attribute;
4966 }
4967 
4968 static tree
c_parser_std_attribute_specifier(c_parser * parser,bool for_tm)4969 c_parser_std_attribute_specifier (c_parser *parser, bool for_tm)
4970 {
4971   location_t loc = c_parser_peek_token (parser)->location;
4972   if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
4973     return NULL_TREE;
4974   if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
4975     {
4976       c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
4977       return NULL_TREE;
4978     }
4979   if (!for_tm)
4980     pedwarn_c11 (loc, OPT_Wpedantic,
4981 		 "ISO C does not support %<[[]]%> attributes before C2X");
4982   tree attributes = NULL_TREE;
4983   while (true)
4984     {
4985       c_token *token = c_parser_peek_token (parser);
4986       if (token->type == CPP_CLOSE_SQUARE)
4987 	break;
4988       if (token->type == CPP_COMMA)
4989 	{
4990 	  c_parser_consume_token (parser);
4991 	  continue;
4992 	}
4993       tree attribute = c_parser_std_attribute (parser, for_tm);
4994       if (attribute != error_mark_node)
4995 	{
4996 	  TREE_CHAIN (attribute) = attributes;
4997 	  attributes = attribute;
4998 	}
4999       if (c_parser_next_token_is_not (parser, CPP_COMMA))
5000 	break;
5001     }
5002   c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5003   c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5004   return nreverse (attributes);
5005 }
5006 
5007 /* Look past an optional balanced token sequence of raw look-ahead
5008    tokens starting with the *Nth token.  *N is updated to point to the
5009    following token.  Return true if such a sequence was found, false
5010    if the tokens parsed were not balanced.  */
5011 
5012 static bool
c_parser_check_balanced_raw_token_sequence(c_parser * parser,unsigned int * n)5013 c_parser_check_balanced_raw_token_sequence (c_parser *parser, unsigned int *n)
5014 {
5015   while (true)
5016     {
5017       c_token *token = c_parser_peek_nth_token_raw (parser, *n);
5018       switch (token->type)
5019 	{
5020 	case CPP_OPEN_BRACE:
5021 	  {
5022 	    ++*n;
5023 	    if (c_parser_check_balanced_raw_token_sequence (parser, n))
5024 	      {
5025 		token = c_parser_peek_nth_token_raw (parser, *n);
5026 		if (token->type == CPP_CLOSE_BRACE)
5027 		  ++*n;
5028 		else
5029 		  return false;
5030 	      }
5031 	    else
5032 	      return false;
5033 	    break;
5034 	  }
5035 
5036 	case CPP_OPEN_PAREN:
5037 	  {
5038 	    ++*n;
5039 	    if (c_parser_check_balanced_raw_token_sequence (parser, n))
5040 	      {
5041 		token = c_parser_peek_nth_token_raw (parser, *n);
5042 		if (token->type == CPP_CLOSE_PAREN)
5043 		  ++*n;
5044 		else
5045 		  return false;
5046 	      }
5047 	    else
5048 	      return false;
5049 	    break;
5050 	  }
5051 
5052 	case CPP_OPEN_SQUARE:
5053 	  {
5054 	    ++*n;
5055 	    if (c_parser_check_balanced_raw_token_sequence (parser, n))
5056 	      {
5057 		token = c_parser_peek_nth_token_raw (parser, *n);
5058 		if (token->type == CPP_CLOSE_SQUARE)
5059 		  ++*n;
5060 		else
5061 		  return false;
5062 	      }
5063 	    else
5064 	      return false;
5065 	    break;
5066 	  }
5067 
5068 	case CPP_CLOSE_BRACE:
5069 	case CPP_CLOSE_PAREN:
5070 	case CPP_CLOSE_SQUARE:
5071 	case CPP_EOF:
5072 	  return true;
5073 
5074 	default:
5075 	  ++*n;
5076 	  break;
5077 	}
5078     }
5079 }
5080 
5081 /* Return whether standard attributes start with the Nth token.  */
5082 
5083 static bool
c_parser_nth_token_starts_std_attributes(c_parser * parser,unsigned int n)5084 c_parser_nth_token_starts_std_attributes (c_parser *parser, unsigned int n)
5085 {
5086   if (!(c_parser_peek_nth_token (parser, n)->type == CPP_OPEN_SQUARE
5087 	&& c_parser_peek_nth_token (parser, n + 1)->type == CPP_OPEN_SQUARE))
5088     return false;
5089   /* In C, '[[' must start attributes.  In Objective-C, we need to
5090      check whether '[[' is matched by ']]'.  */
5091   if (!c_dialect_objc ())
5092     return true;
5093   n += 2;
5094   if (!c_parser_check_balanced_raw_token_sequence (parser, &n))
5095     return false;
5096   c_token *token = c_parser_peek_nth_token_raw (parser, n);
5097   if (token->type != CPP_CLOSE_SQUARE)
5098     return false;
5099   token = c_parser_peek_nth_token_raw (parser, n + 1);
5100   return token->type == CPP_CLOSE_SQUARE;
5101 }
5102 
5103 static tree
c_parser_std_attribute_specifier_sequence(c_parser * parser)5104 c_parser_std_attribute_specifier_sequence (c_parser *parser)
5105 {
5106   tree attributes = NULL_TREE;
5107   do
5108     {
5109       tree attrs = c_parser_std_attribute_specifier (parser, false);
5110       attributes = chainon (attributes, attrs);
5111     }
5112   while (c_parser_nth_token_starts_std_attributes (parser, 1));
5113   return attributes;
5114 }
5115 
5116 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7).  ALIGNAS_OK
5117    says whether alignment specifiers are OK (only in cases that might
5118    be the type name of a compound literal).
5119 
5120    type-name:
5121      specifier-qualifier-list abstract-declarator[opt]
5122 */
5123 
5124 struct c_type_name *
c_parser_type_name(c_parser * parser,bool alignas_ok)5125 c_parser_type_name (c_parser *parser, bool alignas_ok)
5126 {
5127   struct c_declspecs *specs = build_null_declspecs ();
5128   struct c_declarator *declarator;
5129   struct c_type_name *ret;
5130   bool dummy = false;
5131   c_parser_declspecs (parser, specs, false, true, true, alignas_ok, false,
5132 		      false, true, cla_prefer_type);
5133   if (!specs->declspecs_seen_p)
5134     {
5135       c_parser_error (parser, "expected specifier-qualifier-list");
5136       return NULL;
5137     }
5138   if (specs->type != error_mark_node)
5139     {
5140       pending_xref_error ();
5141       finish_declspecs (specs);
5142     }
5143   declarator = c_parser_declarator (parser,
5144 				    specs->typespec_kind != ctsk_none,
5145 				    C_DTR_ABSTRACT, &dummy);
5146   if (declarator == NULL)
5147     return NULL;
5148   ret = XOBNEW (&parser_obstack, struct c_type_name);
5149   ret->specs = specs;
5150   ret->declarator = declarator;
5151   return ret;
5152 }
5153 
5154 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
5155 
5156    initializer:
5157      assignment-expression
5158      { initializer-list }
5159      { initializer-list , }
5160 
5161    initializer-list:
5162      designation[opt] initializer
5163      initializer-list , designation[opt] initializer
5164 
5165    designation:
5166      designator-list =
5167 
5168    designator-list:
5169      designator
5170      designator-list designator
5171 
5172    designator:
5173      array-designator
5174      . identifier
5175 
5176    array-designator:
5177      [ constant-expression ]
5178 
5179    GNU extensions:
5180 
5181    initializer:
5182      { }
5183 
5184    designation:
5185      array-designator
5186      identifier :
5187 
5188    array-designator:
5189      [ constant-expression ... constant-expression ]
5190 
5191    Any expression without commas is accepted in the syntax for the
5192    constant-expressions, with non-constant expressions rejected later.
5193 
5194    This function is only used for top-level initializers; for nested
5195    ones, see c_parser_initval.  */
5196 
5197 static struct c_expr
c_parser_initializer(c_parser * parser)5198 c_parser_initializer (c_parser *parser)
5199 {
5200   if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
5201     return c_parser_braced_init (parser, NULL_TREE, false, NULL);
5202   else
5203     {
5204       struct c_expr ret;
5205       location_t loc = c_parser_peek_token (parser)->location;
5206       ret = c_parser_expr_no_commas (parser, NULL);
5207       if (TREE_CODE (ret.value) != STRING_CST
5208 	  && TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR)
5209 	ret = convert_lvalue_to_rvalue (loc, ret, true, true);
5210       return ret;
5211     }
5212 }
5213 
5214 /* The location of the last comma within the current initializer list,
5215    or UNKNOWN_LOCATION if not within one.  */
5216 
5217 location_t last_init_list_comma;
5218 
5219 /* Parse a braced initializer list.  TYPE is the type specified for a
5220    compound literal, and NULL_TREE for other initializers and for
5221    nested braced lists.  NESTED_P is true for nested braced lists,
5222    false for the list of a compound literal or the list that is the
5223    top-level initializer in a declaration.  */
5224 
5225 static struct c_expr
c_parser_braced_init(c_parser * parser,tree type,bool nested_p,struct obstack * outer_obstack)5226 c_parser_braced_init (c_parser *parser, tree type, bool nested_p,
5227 		      struct obstack *outer_obstack)
5228 {
5229   struct c_expr ret;
5230   struct obstack braced_init_obstack;
5231   location_t brace_loc = c_parser_peek_token (parser)->location;
5232   gcc_obstack_init (&braced_init_obstack);
5233   gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
5234   matching_braces braces;
5235   braces.consume_open (parser);
5236   if (nested_p)
5237     {
5238       finish_implicit_inits (brace_loc, outer_obstack);
5239       push_init_level (brace_loc, 0, &braced_init_obstack);
5240     }
5241   else
5242     really_start_incremental_init (type);
5243   if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5244     {
5245       pedwarn (brace_loc, OPT_Wpedantic, "ISO C forbids empty initializer braces");
5246     }
5247   else
5248     {
5249       /* Parse a non-empty initializer list, possibly with a trailing
5250 	 comma.  */
5251       while (true)
5252 	{
5253 	  c_parser_initelt (parser, &braced_init_obstack);
5254 	  if (parser->error)
5255 	    break;
5256 	  if (c_parser_next_token_is (parser, CPP_COMMA))
5257 	    {
5258 	      last_init_list_comma = c_parser_peek_token (parser)->location;
5259 	      c_parser_consume_token (parser);
5260 	    }
5261 	  else
5262 	    break;
5263 	  if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5264 	    break;
5265 	}
5266     }
5267   c_token *next_tok = c_parser_peek_token (parser);
5268   if (next_tok->type != CPP_CLOSE_BRACE)
5269     {
5270       ret.set_error ();
5271       ret.original_code = ERROR_MARK;
5272       ret.original_type = NULL;
5273       braces.skip_until_found_close (parser);
5274       pop_init_level (brace_loc, 0, &braced_init_obstack, last_init_list_comma);
5275       obstack_free (&braced_init_obstack, NULL);
5276       return ret;
5277     }
5278   location_t close_loc = next_tok->location;
5279   c_parser_consume_token (parser);
5280   ret = pop_init_level (brace_loc, 0, &braced_init_obstack, close_loc);
5281   obstack_free (&braced_init_obstack, NULL);
5282   set_c_expr_source_range (&ret, brace_loc, close_loc);
5283   return ret;
5284 }
5285 
5286 /* Parse a nested initializer, including designators.  */
5287 
5288 static void
c_parser_initelt(c_parser * parser,struct obstack * braced_init_obstack)5289 c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
5290 {
5291   /* Parse any designator or designator list.  A single array
5292      designator may have the subsequent "=" omitted in GNU C, but a
5293      longer list or a structure member designator may not.  */
5294   if (c_parser_next_token_is (parser, CPP_NAME)
5295       && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
5296     {
5297       /* Old-style structure member designator.  */
5298       set_init_label (c_parser_peek_token (parser)->location,
5299 		      c_parser_peek_token (parser)->value,
5300 		      c_parser_peek_token (parser)->location,
5301 		      braced_init_obstack);
5302       /* Use the colon as the error location.  */
5303       pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_Wpedantic,
5304 	       "obsolete use of designated initializer with %<:%>");
5305       c_parser_consume_token (parser);
5306       c_parser_consume_token (parser);
5307     }
5308   else
5309     {
5310       /* des_seen is 0 if there have been no designators, 1 if there
5311 	 has been a single array designator and 2 otherwise.  */
5312       int des_seen = 0;
5313       /* Location of a designator.  */
5314       location_t des_loc = UNKNOWN_LOCATION;  /* Quiet warning.  */
5315       while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
5316 	     || c_parser_next_token_is (parser, CPP_DOT))
5317 	{
5318 	  int des_prev = des_seen;
5319 	  if (!des_seen)
5320 	    des_loc = c_parser_peek_token (parser)->location;
5321 	  if (des_seen < 2)
5322 	    des_seen++;
5323 	  if (c_parser_next_token_is (parser, CPP_DOT))
5324 	    {
5325 	      des_seen = 2;
5326 	      c_parser_consume_token (parser);
5327 	      if (c_parser_next_token_is (parser, CPP_NAME))
5328 		{
5329 		  set_init_label (des_loc, c_parser_peek_token (parser)->value,
5330 				  c_parser_peek_token (parser)->location,
5331 				  braced_init_obstack);
5332 		  c_parser_consume_token (parser);
5333 		}
5334 	      else
5335 		{
5336 		  struct c_expr init;
5337 		  init.set_error ();
5338 		  init.original_code = ERROR_MARK;
5339 		  init.original_type = NULL;
5340 		  c_parser_error (parser, "expected identifier");
5341 		  c_parser_skip_until_found (parser, CPP_COMMA, NULL);
5342 		  process_init_element (input_location, init, false,
5343 					braced_init_obstack);
5344 		  return;
5345 		}
5346 	    }
5347 	  else
5348 	    {
5349 	      tree first, second;
5350 	      location_t ellipsis_loc = UNKNOWN_LOCATION;  /* Quiet warning.  */
5351 	      location_t array_index_loc = UNKNOWN_LOCATION;
5352 	      /* ??? Following the old parser, [ objc-receiver
5353 		 objc-message-args ] is accepted as an initializer,
5354 		 being distinguished from a designator by what follows
5355 		 the first assignment expression inside the square
5356 		 brackets, but after a first array designator a
5357 		 subsequent square bracket is for Objective-C taken to
5358 		 start an expression, using the obsolete form of
5359 		 designated initializer without '=', rather than
5360 		 possibly being a second level of designation: in LALR
5361 		 terms, the '[' is shifted rather than reducing
5362 		 designator to designator-list.  */
5363 	      if (des_prev == 1 && c_dialect_objc ())
5364 		{
5365 		  des_seen = des_prev;
5366 		  break;
5367 		}
5368 	      if (des_prev == 0 && c_dialect_objc ())
5369 		{
5370 		  /* This might be an array designator or an
5371 		     Objective-C message expression.  If the former,
5372 		     continue parsing here; if the latter, parse the
5373 		     remainder of the initializer given the starting
5374 		     primary-expression.  ??? It might make sense to
5375 		     distinguish when des_prev == 1 as well; see
5376 		     previous comment.  */
5377 		  tree rec, args;
5378 		  struct c_expr mexpr;
5379 		  c_parser_consume_token (parser);
5380 		  if (c_parser_peek_token (parser)->type == CPP_NAME
5381 		      && ((c_parser_peek_token (parser)->id_kind
5382 			   == C_ID_TYPENAME)
5383 			  || (c_parser_peek_token (parser)->id_kind
5384 			      == C_ID_CLASSNAME)))
5385 		    {
5386 		      /* Type name receiver.  */
5387 		      tree id = c_parser_peek_token (parser)->value;
5388 		      c_parser_consume_token (parser);
5389 		      rec = objc_get_class_reference (id);
5390 		      goto parse_message_args;
5391 		    }
5392 		  first = c_parser_expr_no_commas (parser, NULL).value;
5393 		  mark_exp_read (first);
5394 		  if (c_parser_next_token_is (parser, CPP_ELLIPSIS)
5395 		      || c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
5396 		    goto array_desig_after_first;
5397 		  /* Expression receiver.  So far only one part
5398 		     without commas has been parsed; there might be
5399 		     more of the expression.  */
5400 		  rec = first;
5401 		  while (c_parser_next_token_is (parser, CPP_COMMA))
5402 		    {
5403 		      struct c_expr next;
5404 		      location_t comma_loc, exp_loc;
5405 		      comma_loc = c_parser_peek_token (parser)->location;
5406 		      c_parser_consume_token (parser);
5407 		      exp_loc = c_parser_peek_token (parser)->location;
5408 		      next = c_parser_expr_no_commas (parser, NULL);
5409 		      next = convert_lvalue_to_rvalue (exp_loc, next,
5410 						       true, true);
5411 		      rec = build_compound_expr (comma_loc, rec, next.value);
5412 		    }
5413 		parse_message_args:
5414 		  /* Now parse the objc-message-args.  */
5415 		  args = c_parser_objc_message_args (parser);
5416 		  c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5417 					     "expected %<]%>");
5418 		  mexpr.value
5419 		    = objc_build_message_expr (rec, args);
5420 		  mexpr.original_code = ERROR_MARK;
5421 		  mexpr.original_type = NULL;
5422 		  /* Now parse and process the remainder of the
5423 		     initializer, starting with this message
5424 		     expression as a primary-expression.  */
5425 		  c_parser_initval (parser, &mexpr, braced_init_obstack);
5426 		  return;
5427 		}
5428 	      c_parser_consume_token (parser);
5429 	      array_index_loc = c_parser_peek_token (parser)->location;
5430 	      first = c_parser_expr_no_commas (parser, NULL).value;
5431 	      mark_exp_read (first);
5432 	    array_desig_after_first:
5433 	      if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
5434 		{
5435 		  ellipsis_loc = c_parser_peek_token (parser)->location;
5436 		  c_parser_consume_token (parser);
5437 		  second = c_parser_expr_no_commas (parser, NULL).value;
5438 		  mark_exp_read (second);
5439 		}
5440 	      else
5441 		second = NULL_TREE;
5442 	      if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
5443 		{
5444 		  c_parser_consume_token (parser);
5445 		  set_init_index (array_index_loc, first, second,
5446 				  braced_init_obstack);
5447 		  if (second)
5448 		    pedwarn (ellipsis_loc, OPT_Wpedantic,
5449 			     "ISO C forbids specifying range of elements to initialize");
5450 		}
5451 	      else
5452 		c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5453 					   "expected %<]%>");
5454 	    }
5455 	}
5456       if (des_seen >= 1)
5457 	{
5458 	  if (c_parser_next_token_is (parser, CPP_EQ))
5459 	    {
5460 	      pedwarn_c90 (des_loc, OPT_Wpedantic,
5461 			   "ISO C90 forbids specifying subobject "
5462 			   "to initialize");
5463 	      c_parser_consume_token (parser);
5464 	    }
5465 	  else
5466 	    {
5467 	      if (des_seen == 1)
5468 		pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
5469 			 "obsolete use of designated initializer without %<=%>");
5470 	      else
5471 		{
5472 		  struct c_expr init;
5473 		  init.set_error ();
5474 		  init.original_code = ERROR_MARK;
5475 		  init.original_type = NULL;
5476 		  c_parser_error (parser, "expected %<=%>");
5477 		  c_parser_skip_until_found (parser, CPP_COMMA, NULL);
5478 		  process_init_element (input_location, init, false,
5479 					braced_init_obstack);
5480 		  return;
5481 		}
5482 	    }
5483 	}
5484     }
5485   c_parser_initval (parser, NULL, braced_init_obstack);
5486 }
5487 
5488 /* Parse a nested initializer; as c_parser_initializer but parses
5489    initializers within braced lists, after any designators have been
5490    applied.  If AFTER is not NULL then it is an Objective-C message
5491    expression which is the primary-expression starting the
5492    initializer.  */
5493 
5494 static void
c_parser_initval(c_parser * parser,struct c_expr * after,struct obstack * braced_init_obstack)5495 c_parser_initval (c_parser *parser, struct c_expr *after,
5496 		  struct obstack * braced_init_obstack)
5497 {
5498   struct c_expr init;
5499   gcc_assert (!after || c_dialect_objc ());
5500   location_t loc = c_parser_peek_token (parser)->location;
5501 
5502   if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after)
5503     init = c_parser_braced_init (parser, NULL_TREE, true,
5504 				 braced_init_obstack);
5505   else
5506     {
5507       init = c_parser_expr_no_commas (parser, after);
5508       if (init.value != NULL_TREE
5509 	  && TREE_CODE (init.value) != STRING_CST
5510 	  && TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR)
5511 	init = convert_lvalue_to_rvalue (loc, init, true, true);
5512     }
5513   process_init_element (loc, init, false, braced_init_obstack);
5514 }
5515 
5516 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
5517    C99 6.8.2, C11 6.8.2, C2X 6.8.2).
5518 
5519    compound-statement:
5520      { block-item-list[opt] }
5521      { label-declarations block-item-list }
5522 
5523    block-item-list:
5524      block-item
5525      block-item-list block-item
5526 
5527    block-item:
5528      label
5529      nested-declaration
5530      statement
5531 
5532    nested-declaration:
5533      declaration
5534 
5535    GNU extensions:
5536 
5537    compound-statement:
5538      { label-declarations block-item-list }
5539 
5540    nested-declaration:
5541      __extension__ nested-declaration
5542      nested-function-definition
5543 
5544    label-declarations:
5545      label-declaration
5546      label-declarations label-declaration
5547 
5548    label-declaration:
5549      __label__ identifier-list ;
5550 
5551    Allowing the mixing of declarations and code is new in C99.  The
5552    GNU syntax also permits (not shown above) labels at the end of
5553    compound statements, which yield an error.  We don't allow labels
5554    on declarations; this might seem like a natural extension, but
5555    there would be a conflict between gnu-attributes on the label and
5556    prefix gnu-attributes on the declaration.  ??? The syntax follows the
5557    old parser in requiring something after label declarations.
5558    Although they are erroneous if the labels declared aren't defined,
5559    is it useful for the syntax to be this way?
5560 
5561    OpenACC:
5562 
5563    block-item:
5564      openacc-directive
5565 
5566    openacc-directive:
5567      update-directive
5568 
5569    OpenMP:
5570 
5571    block-item:
5572      openmp-directive
5573 
5574    openmp-directive:
5575      barrier-directive
5576      flush-directive
5577      taskwait-directive
5578      taskyield-directive
5579      cancel-directive
5580      cancellation-point-directive  */
5581 
5582 static tree
c_parser_compound_statement(c_parser * parser,location_t * endlocp)5583 c_parser_compound_statement (c_parser *parser, location_t *endlocp)
5584 {
5585   tree stmt;
5586   location_t brace_loc;
5587   brace_loc = c_parser_peek_token (parser)->location;
5588   if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
5589     {
5590       /* Ensure a scope is entered and left anyway to avoid confusion
5591 	 if we have just prepared to enter a function body.  */
5592       stmt = c_begin_compound_stmt (true);
5593       c_end_compound_stmt (brace_loc, stmt, true);
5594       return error_mark_node;
5595     }
5596   stmt = c_begin_compound_stmt (true);
5597   location_t end_loc = c_parser_compound_statement_nostart (parser);
5598   if (endlocp)
5599     *endlocp = end_loc;
5600 
5601   return c_end_compound_stmt (brace_loc, stmt, true);
5602 }
5603 
5604 /* Parse a compound statement except for the opening brace.  This is
5605    used for parsing both compound statements and statement expressions
5606    (which follow different paths to handling the opening).  */
5607 
5608 static location_t
c_parser_compound_statement_nostart(c_parser * parser)5609 c_parser_compound_statement_nostart (c_parser *parser)
5610 {
5611   bool last_stmt = false;
5612   bool last_label = false;
5613   bool save_valid_for_pragma = valid_location_for_stdc_pragma_p ();
5614   location_t label_loc = UNKNOWN_LOCATION;  /* Quiet warning.  */
5615   if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5616     {
5617       location_t endloc = c_parser_peek_token (parser)->location;
5618       add_debug_begin_stmt (endloc);
5619       c_parser_consume_token (parser);
5620       return endloc;
5621     }
5622   mark_valid_location_for_stdc_pragma (true);
5623   if (c_parser_next_token_is_keyword (parser, RID_LABEL))
5624     {
5625       /* Read zero or more forward-declarations for labels that nested
5626 	 functions can jump to.  */
5627       mark_valid_location_for_stdc_pragma (false);
5628       while (c_parser_next_token_is_keyword (parser, RID_LABEL))
5629 	{
5630 	  label_loc = c_parser_peek_token (parser)->location;
5631 	  c_parser_consume_token (parser);
5632 	  /* Any identifiers, including those declared as type names,
5633 	     are OK here.  */
5634 	  while (true)
5635 	    {
5636 	      tree label;
5637 	      if (c_parser_next_token_is_not (parser, CPP_NAME))
5638 		{
5639 		  c_parser_error (parser, "expected identifier");
5640 		  break;
5641 		}
5642 	      label
5643 		= declare_label (c_parser_peek_token (parser)->value);
5644 	      C_DECLARED_LABEL_FLAG (label) = 1;
5645 	      add_stmt (build_stmt (label_loc, DECL_EXPR, label));
5646 	      c_parser_consume_token (parser);
5647 	      if (c_parser_next_token_is (parser, CPP_COMMA))
5648 		c_parser_consume_token (parser);
5649 	      else
5650 		break;
5651 	    }
5652 	  c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
5653 	}
5654       pedwarn (label_loc, OPT_Wpedantic, "ISO C forbids label declarations");
5655     }
5656   /* We must now have at least one statement, label or declaration.  */
5657   if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5658     {
5659       mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5660       c_parser_error (parser, "expected declaration or statement");
5661       location_t endloc = c_parser_peek_token (parser)->location;
5662       c_parser_consume_token (parser);
5663       return endloc;
5664     }
5665   while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
5666     {
5667       location_t loc = c_parser_peek_token (parser)->location;
5668       loc = expansion_point_location_if_in_system_header (loc);
5669       /* Standard attributes may start a label, statement or declaration.  */
5670       bool have_std_attrs
5671 	= c_parser_nth_token_starts_std_attributes (parser, 1);
5672       tree std_attrs = NULL_TREE;
5673       if (have_std_attrs)
5674 	std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5675       if (c_parser_next_token_is_keyword (parser, RID_CASE)
5676 	  || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
5677 	  || (c_parser_next_token_is (parser, CPP_NAME)
5678 	      && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5679 	{
5680 	  if (c_parser_next_token_is_keyword (parser, RID_CASE))
5681 	    label_loc = c_parser_peek_2nd_token (parser)->location;
5682 	  else
5683 	    label_loc = c_parser_peek_token (parser)->location;
5684 	  last_label = true;
5685 	  last_stmt = false;
5686 	  mark_valid_location_for_stdc_pragma (false);
5687 	  c_parser_label (parser, std_attrs);
5688 	}
5689       else if (c_parser_next_tokens_start_declaration (parser)
5690 	       || (have_std_attrs
5691 		   && c_parser_next_token_is (parser, CPP_SEMICOLON)))
5692 	{
5693 	  if (last_label)
5694 	    pedwarn_c11 (c_parser_peek_token (parser)->location, OPT_Wpedantic,
5695 			 "a label can only be part of a statement and "
5696 			 "a declaration is not a statement");
5697 
5698 	  mark_valid_location_for_stdc_pragma (false);
5699 	  bool fallthru_attr_p = false;
5700 	  c_parser_declaration_or_fndef (parser, true, !have_std_attrs,
5701 					 true, true, true, NULL,
5702 					 vNULL, have_std_attrs, std_attrs,
5703 					 NULL, &fallthru_attr_p);
5704 
5705 	  if (last_stmt && !fallthru_attr_p)
5706 	    pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
5707 			 "ISO C90 forbids mixed declarations and code");
5708 	  last_stmt = fallthru_attr_p;
5709 	  last_label = false;
5710 	}
5711       else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
5712 	{
5713 	  /* __extension__ can start a declaration, but is also an
5714 	     unary operator that can start an expression.  Consume all
5715 	     but the last of a possible series of __extension__ to
5716 	     determine which.  If standard attributes have already
5717 	     been seen, it must start a statement, not a declaration,
5718 	     but standard attributes starting a declaration may appear
5719 	     after __extension__.  */
5720 	  while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
5721 		 && (c_parser_peek_2nd_token (parser)->keyword
5722 		     == RID_EXTENSION))
5723 	    c_parser_consume_token (parser);
5724 	  if (!have_std_attrs
5725 	      && (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
5726 		  || c_parser_nth_token_starts_std_attributes (parser, 2)))
5727 	    {
5728 	      int ext;
5729 	      ext = disable_extension_diagnostics ();
5730 	      c_parser_consume_token (parser);
5731 	      last_label = false;
5732 	      mark_valid_location_for_stdc_pragma (false);
5733 	      c_parser_declaration_or_fndef (parser, true, true, true, true,
5734 					     true, NULL, vNULL);
5735 	      /* Following the old parser, __extension__ does not
5736 		 disable this diagnostic.  */
5737 	      restore_extension_diagnostics (ext);
5738 	      if (last_stmt)
5739 		pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
5740 			     "ISO C90 forbids mixed declarations and code");
5741 	      last_stmt = false;
5742 	    }
5743 	  else
5744 	    goto statement;
5745 	}
5746       else if (c_parser_next_token_is (parser, CPP_PRAGMA))
5747 	{
5748 	  if (have_std_attrs)
5749 	    c_parser_error (parser, "expected declaration or statement");
5750 	  /* External pragmas, and some omp pragmas, are not associated
5751 	     with regular c code, and so are not to be considered statements
5752 	     syntactically.  This ensures that the user doesn't put them
5753 	     places that would turn into syntax errors if the directive
5754 	     were ignored.  */
5755 	  if (c_parser_pragma (parser,
5756 			       last_label ? pragma_stmt : pragma_compound,
5757 			       NULL))
5758 	    last_label = false, last_stmt = true;
5759 	}
5760       else if (c_parser_next_token_is (parser, CPP_EOF))
5761 	{
5762 	  mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5763 	  c_parser_error (parser, "expected declaration or statement");
5764 	  return c_parser_peek_token (parser)->location;
5765 	}
5766       else if (c_parser_next_token_is_keyword (parser, RID_ELSE))
5767         {
5768           if (parser->in_if_block)
5769             {
5770 	      mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5771 	      error_at (loc, "expected %<}%> before %<else%>");
5772 	      return c_parser_peek_token (parser)->location;
5773             }
5774           else
5775             {
5776               error_at (loc, "%<else%> without a previous %<if%>");
5777               c_parser_consume_token (parser);
5778               continue;
5779             }
5780         }
5781       else
5782 	{
5783 	statement:
5784 	  c_warn_unused_attributes (std_attrs);
5785 	  last_label = false;
5786 	  last_stmt = true;
5787 	  mark_valid_location_for_stdc_pragma (false);
5788 	  c_parser_statement_after_labels (parser, NULL);
5789 	}
5790 
5791       parser->error = false;
5792     }
5793   if (last_label)
5794     pedwarn_c11 (label_loc, OPT_Wpedantic, "label at end of compound statement");
5795   location_t endloc = c_parser_peek_token (parser)->location;
5796   c_parser_consume_token (parser);
5797   /* Restore the value we started with.  */
5798   mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5799   return endloc;
5800 }
5801 
5802 /* Parse all consecutive labels, possibly preceded by standard
5803    attributes.  In this context, a statement is required, not a
5804    declaration, so attributes must be followed by a statement that is
5805    not just a semicolon.  */
5806 
5807 static void
c_parser_all_labels(c_parser * parser)5808 c_parser_all_labels (c_parser *parser)
5809 {
5810   tree std_attrs = NULL;
5811   if (c_parser_nth_token_starts_std_attributes (parser, 1))
5812     {
5813       std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5814       if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5815 	c_parser_error (parser, "expected statement");
5816     }
5817   while (c_parser_next_token_is_keyword (parser, RID_CASE)
5818 	 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
5819 	 || (c_parser_next_token_is (parser, CPP_NAME)
5820 	     && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5821     {
5822       c_parser_label (parser, std_attrs);
5823       std_attrs = NULL;
5824       if (c_parser_nth_token_starts_std_attributes (parser, 1))
5825 	{
5826 	  std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5827 	  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5828 	    c_parser_error (parser, "expected statement");
5829 	}
5830     }
5831    if (std_attrs)
5832      c_warn_unused_attributes (std_attrs);
5833 }
5834 
5835 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
5836 
5837    label:
5838      identifier : gnu-attributes[opt]
5839      case constant-expression :
5840      default :
5841 
5842    GNU extensions:
5843 
5844    label:
5845      case constant-expression ... constant-expression :
5846 
5847    The use of gnu-attributes on labels is a GNU extension.  The syntax in
5848    GNU C accepts any expressions without commas, non-constant
5849    expressions being rejected later.  Any standard
5850    attribute-specifier-sequence before the first label has been parsed
5851    in the caller, to distinguish statements from declarations.  Any
5852    attribute-specifier-sequence after the label is parsed in this
5853    function.  */
5854 static void
c_parser_label(c_parser * parser,tree std_attrs)5855 c_parser_label (c_parser *parser, tree std_attrs)
5856 {
5857   location_t loc1 = c_parser_peek_token (parser)->location;
5858   tree label = NULL_TREE;
5859 
5860   /* Remember whether this case or a user-defined label is allowed to fall
5861      through to.  */
5862   bool fallthrough_p = c_parser_peek_token (parser)->flags & PREV_FALLTHROUGH;
5863 
5864   if (c_parser_next_token_is_keyword (parser, RID_CASE))
5865     {
5866       tree exp1, exp2;
5867       c_parser_consume_token (parser);
5868       exp1 = c_parser_expr_no_commas (parser, NULL).value;
5869       if (c_parser_next_token_is (parser, CPP_COLON))
5870 	{
5871 	  c_parser_consume_token (parser);
5872 	  label = do_case (loc1, exp1, NULL_TREE);
5873 	}
5874       else if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
5875 	{
5876 	  c_parser_consume_token (parser);
5877 	  exp2 = c_parser_expr_no_commas (parser, NULL).value;
5878 	  if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
5879 	    label = do_case (loc1, exp1, exp2);
5880 	}
5881       else
5882 	c_parser_error (parser, "expected %<:%> or %<...%>");
5883     }
5884   else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
5885     {
5886       c_parser_consume_token (parser);
5887       if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
5888 	label = do_case (loc1, NULL_TREE, NULL_TREE);
5889     }
5890   else
5891     {
5892       tree name = c_parser_peek_token (parser)->value;
5893       tree tlab;
5894       tree attrs;
5895       location_t loc2 = c_parser_peek_token (parser)->location;
5896       gcc_assert (c_parser_next_token_is (parser, CPP_NAME));
5897       c_parser_consume_token (parser);
5898       gcc_assert (c_parser_next_token_is (parser, CPP_COLON));
5899       c_parser_consume_token (parser);
5900       attrs = c_parser_gnu_attributes (parser);
5901       tlab = define_label (loc2, name);
5902       if (tlab)
5903 	{
5904 	  decl_attributes (&tlab, attrs, 0);
5905 	  decl_attributes (&tlab, std_attrs, 0);
5906 	  label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab));
5907 	}
5908       if (attrs
5909 	  && c_parser_next_tokens_start_declaration (parser))
5910 	  warning_at (loc2, OPT_Wattributes, "GNU-style attribute between"
5911 		      " label and declaration appertains to the label");
5912     }
5913   if (label)
5914     {
5915       if (TREE_CODE (label) == LABEL_EXPR)
5916 	FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label)) = fallthrough_p;
5917       else
5918 	FALLTHROUGH_LABEL_P (CASE_LABEL (label)) = fallthrough_p;
5919     }
5920 }
5921 
5922 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
5923 
5924    statement:
5925      labeled-statement
5926      attribute-specifier-sequence[opt] compound-statement
5927      expression-statement
5928      attribute-specifier-sequence[opt] selection-statement
5929      attribute-specifier-sequence[opt] iteration-statement
5930      attribute-specifier-sequence[opt] jump-statement
5931 
5932    labeled-statement:
5933      attribute-specifier-sequence[opt] label statement
5934 
5935    expression-statement:
5936      expression[opt] ;
5937      attribute-specifier-sequence expression ;
5938 
5939    selection-statement:
5940      if-statement
5941      switch-statement
5942 
5943    iteration-statement:
5944      while-statement
5945      do-statement
5946      for-statement
5947 
5948    jump-statement:
5949      goto identifier ;
5950      continue ;
5951      break ;
5952      return expression[opt] ;
5953 
5954    GNU extensions:
5955 
5956    statement:
5957      attribute-specifier-sequence[opt] asm-statement
5958 
5959    jump-statement:
5960      goto * expression ;
5961 
5962    expression-statement:
5963      gnu-attributes ;
5964 
5965    Objective-C:
5966 
5967    statement:
5968      attribute-specifier-sequence[opt] objc-throw-statement
5969      attribute-specifier-sequence[opt] objc-try-catch-statement
5970      attribute-specifier-sequence[opt] objc-synchronized-statement
5971 
5972    objc-throw-statement:
5973      @throw expression ;
5974      @throw ;
5975 
5976    OpenACC:
5977 
5978    statement:
5979      attribute-specifier-sequence[opt] openacc-construct
5980 
5981    openacc-construct:
5982      parallel-construct
5983      kernels-construct
5984      data-construct
5985      loop-construct
5986 
5987    parallel-construct:
5988      parallel-directive structured-block
5989 
5990    kernels-construct:
5991      kernels-directive structured-block
5992 
5993    data-construct:
5994      data-directive structured-block
5995 
5996    loop-construct:
5997      loop-directive structured-block
5998 
5999    OpenMP:
6000 
6001    statement:
6002      attribute-specifier-sequence[opt] openmp-construct
6003 
6004    openmp-construct:
6005      parallel-construct
6006      for-construct
6007      simd-construct
6008      for-simd-construct
6009      sections-construct
6010      single-construct
6011      parallel-for-construct
6012      parallel-for-simd-construct
6013      parallel-sections-construct
6014      master-construct
6015      critical-construct
6016      atomic-construct
6017      ordered-construct
6018 
6019    parallel-construct:
6020      parallel-directive structured-block
6021 
6022    for-construct:
6023      for-directive iteration-statement
6024 
6025    simd-construct:
6026      simd-directive iteration-statements
6027 
6028    for-simd-construct:
6029      for-simd-directive iteration-statements
6030 
6031    sections-construct:
6032      sections-directive section-scope
6033 
6034    single-construct:
6035      single-directive structured-block
6036 
6037    parallel-for-construct:
6038      parallel-for-directive iteration-statement
6039 
6040    parallel-for-simd-construct:
6041      parallel-for-simd-directive iteration-statement
6042 
6043    parallel-sections-construct:
6044      parallel-sections-directive section-scope
6045 
6046    master-construct:
6047      master-directive structured-block
6048 
6049    critical-construct:
6050      critical-directive structured-block
6051 
6052    atomic-construct:
6053      atomic-directive expression-statement
6054 
6055    ordered-construct:
6056      ordered-directive structured-block
6057 
6058    Transactional Memory:
6059 
6060    statement:
6061      attribute-specifier-sequence[opt] transaction-statement
6062      attribute-specifier-sequence[opt] transaction-cancel-statement
6063 
6064    IF_P is used to track whether there's a (possibly labeled) if statement
6065    which is not enclosed in braces and has an else clause.  This is used to
6066    implement -Wparentheses.  */
6067 
6068 static void
c_parser_statement(c_parser * parser,bool * if_p,location_t * loc_after_labels)6069 c_parser_statement (c_parser *parser, bool *if_p, location_t *loc_after_labels)
6070 {
6071   c_parser_all_labels (parser);
6072   if (loc_after_labels)
6073     *loc_after_labels = c_parser_peek_token (parser)->location;
6074   c_parser_statement_after_labels (parser, if_p, NULL);
6075 }
6076 
6077 /* Parse a statement, other than a labeled statement.  CHAIN is a vector
6078    of if-else-if conditions.  All labels and standard attributes have
6079    been parsed in the caller.
6080 
6081    IF_P is used to track whether there's a (possibly labeled) if statement
6082    which is not enclosed in braces and has an else clause.  This is used to
6083    implement -Wparentheses.  */
6084 
6085 static void
c_parser_statement_after_labels(c_parser * parser,bool * if_p,vec<tree> * chain)6086 c_parser_statement_after_labels (c_parser *parser, bool *if_p,
6087 				 vec<tree> *chain)
6088 {
6089   location_t loc = c_parser_peek_token (parser)->location;
6090   tree stmt = NULL_TREE;
6091   bool in_if_block = parser->in_if_block;
6092   parser->in_if_block = false;
6093   if (if_p != NULL)
6094     *if_p = false;
6095 
6096   if (c_parser_peek_token (parser)->type != CPP_OPEN_BRACE)
6097     add_debug_begin_stmt (loc);
6098 
6099   switch (c_parser_peek_token (parser)->type)
6100     {
6101     case CPP_OPEN_BRACE:
6102       add_stmt (c_parser_compound_statement (parser));
6103       break;
6104     case CPP_KEYWORD:
6105       switch (c_parser_peek_token (parser)->keyword)
6106 	{
6107 	case RID_IF:
6108 	  c_parser_if_statement (parser, if_p, chain);
6109 	  break;
6110 	case RID_SWITCH:
6111 	  c_parser_switch_statement (parser, if_p);
6112 	  break;
6113 	case RID_WHILE:
6114 	  c_parser_while_statement (parser, false, 0, if_p);
6115 	  break;
6116 	case RID_DO:
6117 	  c_parser_do_statement (parser, false, 0);
6118 	  break;
6119 	case RID_FOR:
6120 	  c_parser_for_statement (parser, false, 0, if_p);
6121 	  break;
6122 	case RID_GOTO:
6123 	  c_parser_consume_token (parser);
6124 	  if (c_parser_next_token_is (parser, CPP_NAME))
6125 	    {
6126 	      stmt = c_finish_goto_label (loc,
6127 					  c_parser_peek_token (parser)->value);
6128 	      c_parser_consume_token (parser);
6129 	    }
6130 	  else if (c_parser_next_token_is (parser, CPP_MULT))
6131 	    {
6132 	      struct c_expr val;
6133 
6134 	      c_parser_consume_token (parser);
6135 	      val = c_parser_expression (parser);
6136 	      val = convert_lvalue_to_rvalue (loc, val, false, true);
6137 	      stmt = c_finish_goto_ptr (loc, val.value);
6138 	    }
6139 	  else
6140 	    c_parser_error (parser, "expected identifier or %<*%>");
6141 	  goto expect_semicolon;
6142 	case RID_CONTINUE:
6143 	  c_parser_consume_token (parser);
6144 	  stmt = c_finish_bc_stmt (loc, objc_foreach_continue_label, false);
6145 	  goto expect_semicolon;
6146 	case RID_BREAK:
6147 	  c_parser_consume_token (parser);
6148 	  stmt = c_finish_bc_stmt (loc, objc_foreach_break_label, true);
6149 	  goto expect_semicolon;
6150 	case RID_RETURN:
6151 	  c_parser_consume_token (parser);
6152 	  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6153 	    {
6154 	      stmt = c_finish_return (loc, NULL_TREE, NULL_TREE);
6155 	      c_parser_consume_token (parser);
6156 	    }
6157 	  else
6158 	    {
6159 	      location_t xloc = c_parser_peek_token (parser)->location;
6160 	      struct c_expr expr = c_parser_expression_conv (parser);
6161 	      mark_exp_read (expr.value);
6162 	      stmt = c_finish_return (EXPR_LOC_OR_LOC (expr.value, xloc),
6163 				      expr.value, expr.original_type);
6164 	      goto expect_semicolon;
6165 	    }
6166 	  break;
6167 	case RID_ASM:
6168 	  stmt = c_parser_asm_statement (parser);
6169 	  break;
6170 	case RID_TRANSACTION_ATOMIC:
6171 	case RID_TRANSACTION_RELAXED:
6172 	  stmt = c_parser_transaction (parser,
6173 	      c_parser_peek_token (parser)->keyword);
6174 	  break;
6175 	case RID_TRANSACTION_CANCEL:
6176 	  stmt = c_parser_transaction_cancel (parser);
6177 	  goto expect_semicolon;
6178 	case RID_AT_THROW:
6179 	  gcc_assert (c_dialect_objc ());
6180 	  c_parser_consume_token (parser);
6181 	  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6182 	    {
6183 	      stmt = objc_build_throw_stmt (loc, NULL_TREE);
6184 	      c_parser_consume_token (parser);
6185 	    }
6186 	  else
6187 	    {
6188 	      struct c_expr expr = c_parser_expression (parser);
6189 	      expr = convert_lvalue_to_rvalue (loc, expr, false, false);
6190 	      expr.value = c_fully_fold (expr.value, false, NULL);
6191 	      stmt = objc_build_throw_stmt (loc, expr.value);
6192 	      goto expect_semicolon;
6193 	    }
6194 	  break;
6195 	case RID_AT_TRY:
6196 	  gcc_assert (c_dialect_objc ());
6197 	  c_parser_objc_try_catch_finally_statement (parser);
6198 	  break;
6199 	case RID_AT_SYNCHRONIZED:
6200 	  gcc_assert (c_dialect_objc ());
6201 	  c_parser_objc_synchronized_statement (parser);
6202 	  break;
6203 	case RID_ATTRIBUTE:
6204 	  {
6205 	    /* Allow '__attribute__((fallthrough));'.  */
6206 	    tree attrs = c_parser_gnu_attributes (parser);
6207 	    if (attribute_fallthrough_p (attrs))
6208 	      {
6209 		if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6210 		  {
6211 		    tree fn = build_call_expr_internal_loc (loc,
6212 							    IFN_FALLTHROUGH,
6213 							    void_type_node, 0);
6214 		    add_stmt (fn);
6215 		    /* Eat the ';'.  */
6216 		    c_parser_consume_token (parser);
6217 		  }
6218 		else
6219 		  warning_at (loc, OPT_Wattributes,
6220 			      "%<fallthrough%> attribute not followed "
6221 			      "by %<;%>");
6222 	      }
6223 	    else if (attrs != NULL_TREE)
6224 	      warning_at (loc, OPT_Wattributes, "only attribute %<fallthrough%>"
6225 			  " can be applied to a null statement");
6226 	    break;
6227 	  }
6228 	default:
6229 	  goto expr_stmt;
6230 	}
6231       break;
6232     case CPP_SEMICOLON:
6233       c_parser_consume_token (parser);
6234       break;
6235     case CPP_CLOSE_PAREN:
6236     case CPP_CLOSE_SQUARE:
6237       /* Avoid infinite loop in error recovery:
6238 	 c_parser_skip_until_found stops at a closing nesting
6239 	 delimiter without consuming it, but here we need to consume
6240 	 it to proceed further.  */
6241       c_parser_error (parser, "expected statement");
6242       c_parser_consume_token (parser);
6243       break;
6244     case CPP_PRAGMA:
6245       c_parser_pragma (parser, pragma_stmt, if_p);
6246       break;
6247     default:
6248     expr_stmt:
6249       stmt = c_finish_expr_stmt (loc, c_parser_expression_conv (parser).value);
6250     expect_semicolon:
6251       c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
6252       break;
6253     }
6254   /* Two cases cannot and do not have line numbers associated: If stmt
6255      is degenerate, such as "2;", then stmt is an INTEGER_CST, which
6256      cannot hold line numbers.  But that's OK because the statement
6257      will either be changed to a MODIFY_EXPR during gimplification of
6258      the statement expr, or discarded.  If stmt was compound, but
6259      without new variables, we will have skipped the creation of a
6260      BIND and will have a bare STATEMENT_LIST.  But that's OK because
6261      (recursively) all of the component statements should already have
6262      line numbers assigned.  ??? Can we discard no-op statements
6263      earlier?  */
6264   if (EXPR_LOCATION (stmt) == UNKNOWN_LOCATION)
6265     protected_set_expr_location (stmt, loc);
6266 
6267   parser->in_if_block = in_if_block;
6268 }
6269 
6270 /* Parse the condition from an if, do, while or for statements.  */
6271 
6272 static tree
c_parser_condition(c_parser * parser)6273 c_parser_condition (c_parser *parser)
6274 {
6275   location_t loc = c_parser_peek_token (parser)->location;
6276   tree cond;
6277   cond = c_parser_expression_conv (parser).value;
6278   cond = c_objc_common_truthvalue_conversion (loc, cond);
6279   cond = c_fully_fold (cond, false, NULL);
6280   if (warn_sequence_point)
6281     verify_sequence_points (cond);
6282   return cond;
6283 }
6284 
6285 /* Parse a parenthesized condition from an if, do or while statement.
6286 
6287    condition:
6288      ( expression )
6289 */
6290 static tree
c_parser_paren_condition(c_parser * parser)6291 c_parser_paren_condition (c_parser *parser)
6292 {
6293   tree cond;
6294   matching_parens parens;
6295   if (!parens.require_open (parser))
6296     return error_mark_node;
6297   cond = c_parser_condition (parser);
6298   parens.skip_until_found_close (parser);
6299   return cond;
6300 }
6301 
6302 /* Parse a statement which is a block in C99.
6303 
6304    IF_P is used to track whether there's a (possibly labeled) if statement
6305    which is not enclosed in braces and has an else clause.  This is used to
6306    implement -Wparentheses.  */
6307 
6308 static tree
c_parser_c99_block_statement(c_parser * parser,bool * if_p,location_t * loc_after_labels)6309 c_parser_c99_block_statement (c_parser *parser, bool *if_p,
6310 			      location_t *loc_after_labels)
6311 {
6312   tree block = c_begin_compound_stmt (flag_isoc99);
6313   location_t loc = c_parser_peek_token (parser)->location;
6314   c_parser_statement (parser, if_p, loc_after_labels);
6315   return c_end_compound_stmt (loc, block, flag_isoc99);
6316 }
6317 
6318 /* Parse the body of an if statement.  This is just parsing a
6319    statement but (a) it is a block in C99, (b) we track whether the
6320    body is an if statement for the sake of -Wparentheses warnings, (c)
6321    we handle an empty body specially for the sake of -Wempty-body
6322    warnings, and (d) we call parser_compound_statement directly
6323    because c_parser_statement_after_labels resets
6324    parser->in_if_block.
6325 
6326    IF_P is used to track whether there's a (possibly labeled) if statement
6327    which is not enclosed in braces and has an else clause.  This is used to
6328    implement -Wparentheses.  */
6329 
6330 static tree
c_parser_if_body(c_parser * parser,bool * if_p,const token_indent_info & if_tinfo)6331 c_parser_if_body (c_parser *parser, bool *if_p,
6332 		  const token_indent_info &if_tinfo)
6333 {
6334   tree block = c_begin_compound_stmt (flag_isoc99);
6335   location_t body_loc = c_parser_peek_token (parser)->location;
6336   location_t body_loc_after_labels = UNKNOWN_LOCATION;
6337   token_indent_info body_tinfo
6338     = get_token_indent_info (c_parser_peek_token (parser));
6339 
6340   c_parser_all_labels (parser);
6341   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6342     {
6343       location_t loc = c_parser_peek_token (parser)->location;
6344       add_stmt (build_empty_stmt (loc));
6345       c_parser_consume_token (parser);
6346       if (!c_parser_next_token_is_keyword (parser, RID_ELSE))
6347 	warning_at (loc, OPT_Wempty_body,
6348 		    "suggest braces around empty body in an %<if%> statement");
6349     }
6350   else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6351     add_stmt (c_parser_compound_statement (parser));
6352   else
6353     {
6354       body_loc_after_labels = c_parser_peek_token (parser)->location;
6355       c_parser_statement_after_labels (parser, if_p);
6356     }
6357 
6358   token_indent_info next_tinfo
6359     = get_token_indent_info (c_parser_peek_token (parser));
6360   warn_for_misleading_indentation (if_tinfo, body_tinfo, next_tinfo);
6361   if (body_loc_after_labels != UNKNOWN_LOCATION
6362       && next_tinfo.type != CPP_SEMICOLON)
6363     warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
6364 				    if_tinfo.location, RID_IF);
6365 
6366   return c_end_compound_stmt (body_loc, block, flag_isoc99);
6367 }
6368 
6369 /* Parse the else body of an if statement.  This is just parsing a
6370    statement but (a) it is a block in C99, (b) we handle an empty body
6371    specially for the sake of -Wempty-body warnings.  CHAIN is a vector
6372    of if-else-if conditions.  */
6373 
6374 static tree
c_parser_else_body(c_parser * parser,const token_indent_info & else_tinfo,vec<tree> * chain)6375 c_parser_else_body (c_parser *parser, const token_indent_info &else_tinfo,
6376 		    vec<tree> *chain)
6377 {
6378   location_t body_loc = c_parser_peek_token (parser)->location;
6379   tree block = c_begin_compound_stmt (flag_isoc99);
6380   token_indent_info body_tinfo
6381     = get_token_indent_info (c_parser_peek_token (parser));
6382   location_t body_loc_after_labels = UNKNOWN_LOCATION;
6383 
6384   c_parser_all_labels (parser);
6385   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6386     {
6387       location_t loc = c_parser_peek_token (parser)->location;
6388       warning_at (loc,
6389 		  OPT_Wempty_body,
6390 	         "suggest braces around empty body in an %<else%> statement");
6391       add_stmt (build_empty_stmt (loc));
6392       c_parser_consume_token (parser);
6393     }
6394   else
6395     {
6396       if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6397 	body_loc_after_labels = c_parser_peek_token (parser)->location;
6398       c_parser_statement_after_labels (parser, NULL, chain);
6399     }
6400 
6401   token_indent_info next_tinfo
6402     = get_token_indent_info (c_parser_peek_token (parser));
6403   warn_for_misleading_indentation (else_tinfo, body_tinfo, next_tinfo);
6404   if (body_loc_after_labels != UNKNOWN_LOCATION
6405       && next_tinfo.type != CPP_SEMICOLON)
6406     warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
6407 				    else_tinfo.location, RID_ELSE);
6408 
6409   return c_end_compound_stmt (body_loc, block, flag_isoc99);
6410 }
6411 
6412 /* We might need to reclassify any previously-lexed identifier, e.g.
6413    when we've left a for loop with an if-statement without else in the
6414    body - we might have used a wrong scope for the token.  See PR67784.  */
6415 
6416 static void
c_parser_maybe_reclassify_token(c_parser * parser)6417 c_parser_maybe_reclassify_token (c_parser *parser)
6418 {
6419   if (c_parser_next_token_is (parser, CPP_NAME))
6420     {
6421       c_token *token = c_parser_peek_token (parser);
6422 
6423       if (token->id_kind != C_ID_CLASSNAME)
6424 	{
6425 	  tree decl = lookup_name (token->value);
6426 
6427 	  token->id_kind = C_ID_ID;
6428 	  if (decl)
6429 	    {
6430 	      if (TREE_CODE (decl) == TYPE_DECL)
6431 		token->id_kind = C_ID_TYPENAME;
6432 	    }
6433 	  else if (c_dialect_objc ())
6434 	    {
6435 	      tree objc_interface_decl = objc_is_class_name (token->value);
6436 	      /* Objective-C class names are in the same namespace as
6437 		 variables and typedefs, and hence are shadowed by local
6438 		 declarations.  */
6439 	      if (objc_interface_decl)
6440 		{
6441 		  token->value = objc_interface_decl;
6442 		  token->id_kind = C_ID_CLASSNAME;
6443 		}
6444 	    }
6445 	}
6446     }
6447 }
6448 
6449 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6450 
6451    if-statement:
6452      if ( expression ) statement
6453      if ( expression ) statement else statement
6454 
6455    CHAIN is a vector of if-else-if conditions.
6456    IF_P is used to track whether there's a (possibly labeled) if statement
6457    which is not enclosed in braces and has an else clause.  This is used to
6458    implement -Wparentheses.  */
6459 
6460 static void
c_parser_if_statement(c_parser * parser,bool * if_p,vec<tree> * chain)6461 c_parser_if_statement (c_parser *parser, bool *if_p, vec<tree> *chain)
6462 {
6463   tree block;
6464   location_t loc;
6465   tree cond;
6466   bool nested_if = false;
6467   tree first_body, second_body;
6468   bool in_if_block;
6469 
6470   gcc_assert (c_parser_next_token_is_keyword (parser, RID_IF));
6471   token_indent_info if_tinfo
6472     = get_token_indent_info (c_parser_peek_token (parser));
6473   c_parser_consume_token (parser);
6474   block = c_begin_compound_stmt (flag_isoc99);
6475   loc = c_parser_peek_token (parser)->location;
6476   cond = c_parser_paren_condition (parser);
6477   in_if_block = parser->in_if_block;
6478   parser->in_if_block = true;
6479   first_body = c_parser_if_body (parser, &nested_if, if_tinfo);
6480   parser->in_if_block = in_if_block;
6481 
6482   if (warn_duplicated_cond)
6483     warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond), cond, &chain);
6484 
6485   if (c_parser_next_token_is_keyword (parser, RID_ELSE))
6486     {
6487       token_indent_info else_tinfo
6488 	= get_token_indent_info (c_parser_peek_token (parser));
6489       c_parser_consume_token (parser);
6490       if (warn_duplicated_cond)
6491 	{
6492 	  if (c_parser_next_token_is_keyword (parser, RID_IF)
6493 	      && chain == NULL)
6494 	    {
6495 	      /* We've got "if (COND) else if (COND2)".  Start the
6496 		 condition chain and add COND as the first element.  */
6497 	      chain = new vec<tree> ();
6498 	      if (!CONSTANT_CLASS_P (cond) && !TREE_SIDE_EFFECTS (cond))
6499 		chain->safe_push (cond);
6500 	    }
6501 	  else if (!c_parser_next_token_is_keyword (parser, RID_IF))
6502 	    /* This is if-else without subsequent if.  Zap the condition
6503 	       chain; we would have already warned at this point.  */
6504 	    vec_free (chain);
6505 	}
6506       second_body = c_parser_else_body (parser, else_tinfo, chain);
6507       /* Set IF_P to true to indicate that this if statement has an
6508 	 else clause.  This may trigger the Wparentheses warning
6509 	 below when we get back up to the parent if statement.  */
6510       if (if_p != NULL)
6511 	*if_p = true;
6512     }
6513   else
6514     {
6515       second_body = NULL_TREE;
6516 
6517       /* Diagnose an ambiguous else if if-then-else is nested inside
6518 	 if-then.  */
6519       if (nested_if)
6520 	warning_at (loc, OPT_Wdangling_else,
6521 		    "suggest explicit braces to avoid ambiguous %<else%>");
6522 
6523       if (warn_duplicated_cond)
6524 	/* This if statement does not have an else clause.  We don't
6525 	   need the condition chain anymore.  */
6526 	vec_free (chain);
6527     }
6528   c_finish_if_stmt (loc, cond, first_body, second_body);
6529   add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6530 
6531   c_parser_maybe_reclassify_token (parser);
6532 }
6533 
6534 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6535 
6536    switch-statement:
6537      switch (expression) statement
6538 */
6539 
6540 static void
c_parser_switch_statement(c_parser * parser,bool * if_p)6541 c_parser_switch_statement (c_parser *parser, bool *if_p)
6542 {
6543   struct c_expr ce;
6544   tree block, expr, body;
6545   unsigned char save_in_statement;
6546   location_t switch_loc = c_parser_peek_token (parser)->location;
6547   location_t switch_cond_loc;
6548   gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH));
6549   c_parser_consume_token (parser);
6550   block = c_begin_compound_stmt (flag_isoc99);
6551   bool explicit_cast_p = false;
6552   matching_parens parens;
6553   if (parens.require_open (parser))
6554     {
6555       switch_cond_loc = c_parser_peek_token (parser)->location;
6556       if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
6557 	  && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
6558 	explicit_cast_p = true;
6559       ce = c_parser_expression (parser);
6560       ce = convert_lvalue_to_rvalue (switch_cond_loc, ce, true, true);
6561       expr = ce.value;
6562       /* ??? expr has no valid location?  */
6563       parens.skip_until_found_close (parser);
6564     }
6565   else
6566     {
6567       switch_cond_loc = UNKNOWN_LOCATION;
6568       expr = error_mark_node;
6569       ce.original_type = error_mark_node;
6570     }
6571   c_start_switch (switch_loc, switch_cond_loc, expr, explicit_cast_p);
6572   save_in_statement = in_statement;
6573   in_statement |= IN_SWITCH_STMT;
6574   location_t loc_after_labels;
6575   bool open_brace_p = c_parser_peek_token (parser)->type == CPP_OPEN_BRACE;
6576   body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6577   location_t next_loc = c_parser_peek_token (parser)->location;
6578   if (!open_brace_p && c_parser_peek_token (parser)->type != CPP_SEMICOLON)
6579     warn_for_multistatement_macros (loc_after_labels, next_loc, switch_loc,
6580 				    RID_SWITCH);
6581   c_finish_switch (body, ce.original_type);
6582   in_statement = save_in_statement;
6583   add_stmt (c_end_compound_stmt (switch_loc, block, flag_isoc99));
6584   c_parser_maybe_reclassify_token (parser);
6585 }
6586 
6587 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6588 
6589    while-statement:
6590       while (expression) statement
6591 
6592    IF_P is used to track whether there's a (possibly labeled) if statement
6593    which is not enclosed in braces and has an else clause.  This is used to
6594    implement -Wparentheses.  */
6595 
6596 static void
c_parser_while_statement(c_parser * parser,bool ivdep,unsigned short unroll,bool * if_p)6597 c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6598 			  bool *if_p)
6599 {
6600   tree block, cond, body;
6601   unsigned char save_in_statement;
6602   location_t loc;
6603   gcc_assert (c_parser_next_token_is_keyword (parser, RID_WHILE));
6604   token_indent_info while_tinfo
6605     = get_token_indent_info (c_parser_peek_token (parser));
6606   c_parser_consume_token (parser);
6607   block = c_begin_compound_stmt (flag_isoc99);
6608   loc = c_parser_peek_token (parser)->location;
6609   cond = c_parser_paren_condition (parser);
6610   if (ivdep && cond != error_mark_node)
6611     cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6612 		   build_int_cst (integer_type_node,
6613 				  annot_expr_ivdep_kind),
6614 		   integer_zero_node);
6615   if (unroll && cond != error_mark_node)
6616     cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6617 		   build_int_cst (integer_type_node,
6618 				  annot_expr_unroll_kind),
6619 		   build_int_cst (integer_type_node, unroll));
6620   save_in_statement = in_statement;
6621   in_statement = IN_ITERATION_STMT;
6622 
6623   token_indent_info body_tinfo
6624     = get_token_indent_info (c_parser_peek_token (parser));
6625 
6626   location_t loc_after_labels;
6627   bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
6628   body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6629   add_stmt (build_stmt (loc, WHILE_STMT, cond, body));
6630   add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6631   c_parser_maybe_reclassify_token (parser);
6632 
6633   token_indent_info next_tinfo
6634     = get_token_indent_info (c_parser_peek_token (parser));
6635   warn_for_misleading_indentation (while_tinfo, body_tinfo, next_tinfo);
6636 
6637   if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
6638     warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
6639 				    while_tinfo.location, RID_WHILE);
6640 
6641   in_statement = save_in_statement;
6642 }
6643 
6644 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6645 
6646    do-statement:
6647      do statement while ( expression ) ;
6648 */
6649 
6650 static void
c_parser_do_statement(c_parser * parser,bool ivdep,unsigned short unroll)6651 c_parser_do_statement (c_parser *parser, bool ivdep, unsigned short unroll)
6652 {
6653   tree block, cond, body;
6654   unsigned char save_in_statement;
6655   location_t loc;
6656   gcc_assert (c_parser_next_token_is_keyword (parser, RID_DO));
6657   c_parser_consume_token (parser);
6658   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6659     warning_at (c_parser_peek_token (parser)->location,
6660 		OPT_Wempty_body,
6661 		"suggest braces around empty body in %<do%> statement");
6662   block = c_begin_compound_stmt (flag_isoc99);
6663   loc = c_parser_peek_token (parser)->location;
6664   save_in_statement = in_statement;
6665   in_statement = IN_ITERATION_STMT;
6666   body = c_parser_c99_block_statement (parser, NULL);
6667   c_parser_require_keyword (parser, RID_WHILE, "expected %<while%>");
6668   in_statement = save_in_statement;
6669   cond = c_parser_paren_condition (parser);
6670   if (ivdep && cond != error_mark_node)
6671     cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6672 		   build_int_cst (integer_type_node,
6673 				  annot_expr_ivdep_kind),
6674 		   integer_zero_node);
6675   if (unroll && cond != error_mark_node)
6676     cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6677 		   build_int_cst (integer_type_node,
6678 				  annot_expr_unroll_kind),
6679  		   build_int_cst (integer_type_node, unroll));
6680   if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
6681     c_parser_skip_to_end_of_block_or_statement (parser);
6682 
6683   add_stmt (build_stmt (loc, DO_STMT, cond, body));
6684   add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6685 }
6686 
6687 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6688 
6689    for-statement:
6690      for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
6691      for ( nested-declaration expression[opt] ; expression[opt] ) statement
6692 
6693    The form with a declaration is new in C99.
6694 
6695    ??? In accordance with the old parser, the declaration may be a
6696    nested function, which is then rejected in check_for_loop_decls,
6697    but does it make any sense for this to be included in the grammar?
6698    Note in particular that the nested function does not include a
6699    trailing ';', whereas the "declaration" production includes one.
6700    Also, can we reject bad declarations earlier and cheaper than
6701    check_for_loop_decls?
6702 
6703    In Objective-C, there are two additional variants:
6704 
6705    foreach-statement:
6706      for ( expression in expresssion ) statement
6707      for ( declaration in expression ) statement
6708 
6709    This is inconsistent with C, because the second variant is allowed
6710    even if c99 is not enabled.
6711 
6712    The rest of the comment documents these Objective-C foreach-statement.
6713 
6714    Here is the canonical example of the first variant:
6715     for (object in array)    { do something with object }
6716    we call the first expression ("object") the "object_expression" and
6717    the second expression ("array") the "collection_expression".
6718    object_expression must be an lvalue of type "id" (a generic Objective-C
6719    object) because the loop works by assigning to object_expression the
6720    various objects from the collection_expression.  collection_expression
6721    must evaluate to something of type "id" which responds to the method
6722    countByEnumeratingWithState:objects:count:.
6723 
6724    The canonical example of the second variant is:
6725     for (id object in array)    { do something with object }
6726    which is completely equivalent to
6727     {
6728       id object;
6729       for (object in array) { do something with object }
6730     }
6731    Note that initizializing 'object' in some way (eg, "for ((object =
6732    xxx) in array) { do something with object }") is possibly
6733    technically valid, but completely pointless as 'object' will be
6734    assigned to something else as soon as the loop starts.  We should
6735    most likely reject it (TODO).
6736 
6737    The beginning of the Objective-C foreach-statement looks exactly
6738    like the beginning of the for-statement, and we can tell it is a
6739    foreach-statement only because the initial declaration or
6740    expression is terminated by 'in' instead of ';'.
6741 
6742    IF_P is used to track whether there's a (possibly labeled) if statement
6743    which is not enclosed in braces and has an else clause.  This is used to
6744    implement -Wparentheses.  */
6745 
6746 static void
c_parser_for_statement(c_parser * parser,bool ivdep,unsigned short unroll,bool * if_p)6747 c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6748 			bool *if_p)
6749 {
6750   tree block, cond, incr, body;
6751   unsigned char save_in_statement;
6752   tree save_objc_foreach_break_label, save_objc_foreach_continue_label;
6753   /* The following are only used when parsing an ObjC foreach statement.  */
6754   tree object_expression;
6755   /* Silence the bogus uninitialized warning.  */
6756   tree collection_expression = NULL;
6757   location_t loc = c_parser_peek_token (parser)->location;
6758   location_t for_loc = loc;
6759   bool is_foreach_statement = false;
6760   gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
6761   token_indent_info for_tinfo
6762     = get_token_indent_info (c_parser_peek_token (parser));
6763   c_parser_consume_token (parser);
6764   /* Open a compound statement in Objective-C as well, just in case this is
6765      as foreach expression.  */
6766   block = c_begin_compound_stmt (flag_isoc99 || c_dialect_objc ());
6767   cond = error_mark_node;
6768   incr = error_mark_node;
6769   matching_parens parens;
6770   if (parens.require_open (parser))
6771     {
6772       /* Parse the initialization declaration or expression.  */
6773       object_expression = error_mark_node;
6774       parser->objc_could_be_foreach_context = c_dialect_objc ();
6775       if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6776 	{
6777 	  parser->objc_could_be_foreach_context = false;
6778 	  c_parser_consume_token (parser);
6779 	  c_finish_expr_stmt (loc, NULL_TREE);
6780 	}
6781       else if (c_parser_next_tokens_start_declaration (parser)
6782 	       || c_parser_nth_token_starts_std_attributes (parser, 1))
6783 	{
6784 	  c_parser_declaration_or_fndef (parser, true, true, true, true, true,
6785 					 &object_expression, vNULL);
6786 	  parser->objc_could_be_foreach_context = false;
6787 
6788 	  if (c_parser_next_token_is_keyword (parser, RID_IN))
6789 	    {
6790 	      c_parser_consume_token (parser);
6791 	      is_foreach_statement = true;
6792 	      if (check_for_loop_decls (for_loc, true) == NULL_TREE)
6793 		c_parser_error (parser, "multiple iterating variables in "
6794 					"fast enumeration");
6795 	    }
6796 	  else
6797 	    check_for_loop_decls (for_loc, flag_isoc99);
6798 	}
6799       else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
6800 	{
6801 	  /* __extension__ can start a declaration, but is also an
6802 	     unary operator that can start an expression.  Consume all
6803 	     but the last of a possible series of __extension__ to
6804 	     determine which.  */
6805 	  while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
6806 		 && (c_parser_peek_2nd_token (parser)->keyword
6807 		     == RID_EXTENSION))
6808 	    c_parser_consume_token (parser);
6809 	  if (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
6810 	      || c_parser_nth_token_starts_std_attributes (parser, 2))
6811 	    {
6812 	      int ext;
6813 	      ext = disable_extension_diagnostics ();
6814 	      c_parser_consume_token (parser);
6815 	      c_parser_declaration_or_fndef (parser, true, true, true, true,
6816 					     true, &object_expression, vNULL);
6817 	      parser->objc_could_be_foreach_context = false;
6818 
6819 	      restore_extension_diagnostics (ext);
6820 	      if (c_parser_next_token_is_keyword (parser, RID_IN))
6821 		{
6822 		  c_parser_consume_token (parser);
6823 		  is_foreach_statement = true;
6824 		  if (check_for_loop_decls (for_loc, true) == NULL_TREE)
6825 		    c_parser_error (parser, "multiple iterating variables in "
6826 					    "fast enumeration");
6827 		}
6828 	      else
6829 		check_for_loop_decls (for_loc, flag_isoc99);
6830 	    }
6831 	  else
6832 	    goto init_expr;
6833 	}
6834       else
6835 	{
6836 	init_expr:
6837 	  {
6838 	    struct c_expr ce;
6839 	    tree init_expression;
6840 	    ce = c_parser_expression (parser);
6841 	    init_expression = ce.value;
6842 	    parser->objc_could_be_foreach_context = false;
6843 	    if (c_parser_next_token_is_keyword (parser, RID_IN))
6844 	      {
6845 		c_parser_consume_token (parser);
6846 		is_foreach_statement = true;
6847 		if (! lvalue_p (init_expression))
6848 		  c_parser_error (parser, "invalid iterating variable in "
6849 					  "fast enumeration");
6850 		object_expression
6851 		  = c_fully_fold (init_expression, false, NULL);
6852 	      }
6853 	    else
6854 	      {
6855 		ce = convert_lvalue_to_rvalue (loc, ce, true, false);
6856 		init_expression = ce.value;
6857 		c_finish_expr_stmt (loc, init_expression);
6858 		c_parser_skip_until_found (parser, CPP_SEMICOLON,
6859 					   "expected %<;%>");
6860 	      }
6861 	  }
6862 	}
6863       /* Parse the loop condition.  In the case of a foreach
6864 	 statement, there is no loop condition.  */
6865       gcc_assert (!parser->objc_could_be_foreach_context);
6866       if (!is_foreach_statement)
6867 	{
6868 	  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6869 	    {
6870 	      if (ivdep)
6871 		{
6872 		  c_parser_error (parser, "missing loop condition in loop "
6873 					  "with %<GCC ivdep%> pragma");
6874 		  cond = error_mark_node;
6875 		}
6876 	      else if (unroll)
6877 		{
6878 		  c_parser_error (parser, "missing loop condition in loop "
6879 					  "with %<GCC unroll%> pragma");
6880 		  cond = error_mark_node;
6881 		}
6882 	      else
6883 		{
6884 		  c_parser_consume_token (parser);
6885 		  cond = NULL_TREE;
6886 		}
6887 	    }
6888 	  else
6889 	    {
6890 	      cond = c_parser_condition (parser);
6891 	      c_parser_skip_until_found (parser, CPP_SEMICOLON,
6892 					 "expected %<;%>");
6893 	    }
6894 	  if (ivdep && cond != error_mark_node)
6895 	    cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6896 			   build_int_cst (integer_type_node,
6897 					  annot_expr_ivdep_kind),
6898 			   integer_zero_node);
6899 	  if (unroll && cond != error_mark_node)
6900 	    cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6901  			   build_int_cst (integer_type_node,
6902 					  annot_expr_unroll_kind),
6903 			   build_int_cst (integer_type_node, unroll));
6904 	}
6905       /* Parse the increment expression (the third expression in a
6906 	 for-statement).  In the case of a foreach-statement, this is
6907 	 the expression that follows the 'in'.  */
6908       loc = c_parser_peek_token (parser)->location;
6909       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
6910 	{
6911 	  if (is_foreach_statement)
6912 	    {
6913 	      c_parser_error (parser,
6914 			      "missing collection in fast enumeration");
6915 	      collection_expression = error_mark_node;
6916 	    }
6917 	  else
6918 	    incr = c_process_expr_stmt (loc, NULL_TREE);
6919 	}
6920       else
6921 	{
6922 	  if (is_foreach_statement)
6923 	    collection_expression
6924 	      = c_fully_fold (c_parser_expression (parser).value, false, NULL);
6925 	  else
6926 	    {
6927 	      struct c_expr ce = c_parser_expression (parser);
6928 	      ce = convert_lvalue_to_rvalue (loc, ce, true, false);
6929 	      incr = c_process_expr_stmt (loc, ce.value);
6930 	    }
6931 	}
6932       parens.skip_until_found_close (parser);
6933     }
6934   save_in_statement = in_statement;
6935   if (is_foreach_statement)
6936     {
6937       in_statement = IN_OBJC_FOREACH;
6938       save_objc_foreach_break_label = objc_foreach_break_label;
6939       save_objc_foreach_continue_label = objc_foreach_continue_label;
6940       objc_foreach_break_label = create_artificial_label (loc);
6941       objc_foreach_continue_label = create_artificial_label (loc);
6942     }
6943   else
6944     in_statement = IN_ITERATION_STMT;
6945 
6946   token_indent_info body_tinfo
6947     = get_token_indent_info (c_parser_peek_token (parser));
6948 
6949   location_t loc_after_labels;
6950   bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
6951   body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6952 
6953   if (is_foreach_statement)
6954     objc_finish_foreach_loop (for_loc, object_expression,
6955 			      collection_expression, body,
6956 			      objc_foreach_break_label,
6957 			      objc_foreach_continue_label);
6958   else
6959     add_stmt (build_stmt (for_loc, FOR_STMT, NULL_TREE, cond, incr,
6960 			  body, NULL_TREE));
6961   add_stmt (c_end_compound_stmt (for_loc, block,
6962 				 flag_isoc99 || c_dialect_objc ()));
6963   c_parser_maybe_reclassify_token (parser);
6964 
6965   token_indent_info next_tinfo
6966     = get_token_indent_info (c_parser_peek_token (parser));
6967   warn_for_misleading_indentation (for_tinfo, body_tinfo, next_tinfo);
6968 
6969   if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
6970     warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
6971 				    for_tinfo.location, RID_FOR);
6972 
6973   in_statement = save_in_statement;
6974   if (is_foreach_statement)
6975     {
6976       objc_foreach_break_label = save_objc_foreach_break_label;
6977       objc_foreach_continue_label = save_objc_foreach_continue_label;
6978     }
6979 }
6980 
6981 /* Parse an asm statement, a GNU extension.  This is a full-blown asm
6982    statement with inputs, outputs, clobbers, and volatile, inline, and goto
6983    tags allowed.
6984 
6985    asm-qualifier:
6986      volatile
6987      inline
6988      goto
6989 
6990    asm-qualifier-list:
6991      asm-qualifier-list asm-qualifier
6992      asm-qualifier
6993 
6994    asm-statement:
6995      asm asm-qualifier-list[opt] ( asm-argument ) ;
6996 
6997    asm-argument:
6998      asm-string-literal
6999      asm-string-literal : asm-operands[opt]
7000      asm-string-literal : asm-operands[opt] : asm-operands[opt]
7001      asm-string-literal : asm-operands[opt] : asm-operands[opt] \
7002        : asm-clobbers[opt]
7003      asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
7004        : asm-goto-operands
7005 
7006    The form with asm-goto-operands is valid if and only if the
7007    asm-qualifier-list contains goto, and is the only allowed form in that case.
7008    Duplicate asm-qualifiers are not allowed.
7009 
7010    The :: token is considered equivalent to two consecutive : tokens.  */
7011 
7012 static tree
c_parser_asm_statement(c_parser * parser)7013 c_parser_asm_statement (c_parser *parser)
7014 {
7015   tree str, outputs, inputs, clobbers, labels, ret;
7016   bool simple;
7017   location_t asm_loc = c_parser_peek_token (parser)->location;
7018   int section, nsections;
7019 
7020   gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
7021   c_parser_consume_token (parser);
7022 
7023   /* Handle the asm-qualifier-list.  */
7024   location_t volatile_loc = UNKNOWN_LOCATION;
7025   location_t inline_loc = UNKNOWN_LOCATION;
7026   location_t goto_loc = UNKNOWN_LOCATION;
7027   for (;;)
7028     {
7029       c_token *token = c_parser_peek_token (parser);
7030       location_t loc = token->location;
7031       switch (token->keyword)
7032 	{
7033 	case RID_VOLATILE:
7034 	  if (volatile_loc)
7035 	    {
7036 	      error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7037 	      inform (volatile_loc, "first seen here");
7038 	    }
7039 	  else
7040 	    volatile_loc = loc;
7041 	  c_parser_consume_token (parser);
7042 	  continue;
7043 
7044 	case RID_INLINE:
7045 	  if (inline_loc)
7046 	    {
7047 	      error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7048 	      inform (inline_loc, "first seen here");
7049 	    }
7050 	  else
7051 	    inline_loc = loc;
7052 	  c_parser_consume_token (parser);
7053 	  continue;
7054 
7055 	case RID_GOTO:
7056 	  if (goto_loc)
7057 	    {
7058 	      error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7059 	      inform (goto_loc, "first seen here");
7060 	    }
7061 	  else
7062 	    goto_loc = loc;
7063 	  c_parser_consume_token (parser);
7064 	  continue;
7065 
7066 	case RID_CONST:
7067 	case RID_RESTRICT:
7068 	  error_at (loc, "%qE is not a valid %<asm%> qualifier", token->value);
7069 	  c_parser_consume_token (parser);
7070 	  continue;
7071 
7072 	default:
7073 	  break;
7074 	}
7075       break;
7076     }
7077 
7078   bool is_volatile = (volatile_loc != UNKNOWN_LOCATION);
7079   bool is_inline = (inline_loc != UNKNOWN_LOCATION);
7080   bool is_goto = (goto_loc != UNKNOWN_LOCATION);
7081 
7082   ret = NULL;
7083 
7084   matching_parens parens;
7085   if (!parens.require_open (parser))
7086     goto error;
7087 
7088   str = c_parser_asm_string_literal (parser);
7089   if (str == NULL_TREE)
7090     goto error_close_paren;
7091 
7092   simple = true;
7093   outputs = NULL_TREE;
7094   inputs = NULL_TREE;
7095   clobbers = NULL_TREE;
7096   labels = NULL_TREE;
7097 
7098   if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
7099     goto done_asm;
7100 
7101   /* Parse each colon-delimited section of operands.  */
7102   nsections = 3 + is_goto;
7103   for (section = 0; section < nsections; ++section)
7104     {
7105       if (c_parser_next_token_is (parser, CPP_SCOPE))
7106 	{
7107 	  ++section;
7108 	  if (section == nsections)
7109 	    {
7110 	      c_parser_error (parser, "expected %<)%>");
7111 	      goto error_close_paren;
7112 	    }
7113 	  c_parser_consume_token (parser);
7114 	}
7115       else if (!c_parser_require (parser, CPP_COLON,
7116 				  is_goto
7117 				  ? G_("expected %<:%>")
7118 				  : G_("expected %<:%> or %<)%>"),
7119 				  UNKNOWN_LOCATION, is_goto))
7120 	goto error_close_paren;
7121 
7122       /* Once past any colon, we're no longer a simple asm.  */
7123       simple = false;
7124 
7125       if ((!c_parser_next_token_is (parser, CPP_COLON)
7126 	   && !c_parser_next_token_is (parser, CPP_SCOPE)
7127 	   && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
7128 	  || section == 3)
7129 	switch (section)
7130 	  {
7131 	  case 0:
7132 	    outputs = c_parser_asm_operands (parser);
7133 	    break;
7134 	  case 1:
7135 	    inputs = c_parser_asm_operands (parser);
7136 	    break;
7137 	  case 2:
7138 	    clobbers = c_parser_asm_clobbers (parser);
7139 	    break;
7140 	  case 3:
7141 	    labels = c_parser_asm_goto_operands (parser);
7142 	    break;
7143 	  default:
7144 	    gcc_unreachable ();
7145 	  }
7146 
7147       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
7148 	goto done_asm;
7149     }
7150 
7151  done_asm:
7152   if (!parens.require_close (parser))
7153     {
7154       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7155       goto error;
7156     }
7157 
7158   if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
7159     c_parser_skip_to_end_of_block_or_statement (parser);
7160 
7161   ret = build_asm_stmt (is_volatile,
7162 			build_asm_expr (asm_loc, str, outputs, inputs,
7163 					clobbers, labels, simple, is_inline));
7164 
7165  error:
7166   return ret;
7167 
7168  error_close_paren:
7169   c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7170   goto error;
7171 }
7172 
7173 /* Parse asm operands, a GNU extension.
7174 
7175    asm-operands:
7176      asm-operand
7177      asm-operands , asm-operand
7178 
7179    asm-operand:
7180      asm-string-literal ( expression )
7181      [ identifier ] asm-string-literal ( expression )
7182 */
7183 
7184 static tree
c_parser_asm_operands(c_parser * parser)7185 c_parser_asm_operands (c_parser *parser)
7186 {
7187   tree list = NULL_TREE;
7188   while (true)
7189     {
7190       tree name, str;
7191       struct c_expr expr;
7192       if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
7193 	{
7194 	  c_parser_consume_token (parser);
7195 	  if (c_parser_next_token_is (parser, CPP_NAME))
7196 	    {
7197 	      tree id = c_parser_peek_token (parser)->value;
7198 	      c_parser_consume_token (parser);
7199 	      name = build_string (IDENTIFIER_LENGTH (id),
7200 				   IDENTIFIER_POINTER (id));
7201 	    }
7202 	  else
7203 	    {
7204 	      c_parser_error (parser, "expected identifier");
7205 	      c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
7206 	      return NULL_TREE;
7207 	    }
7208 	  c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
7209 				     "expected %<]%>");
7210 	}
7211       else
7212 	name = NULL_TREE;
7213       str = c_parser_asm_string_literal (parser);
7214       if (str == NULL_TREE)
7215 	return NULL_TREE;
7216       matching_parens parens;
7217       if (!parens.require_open (parser))
7218 	return NULL_TREE;
7219       expr = c_parser_expression (parser);
7220       mark_exp_read (expr.value);
7221       if (!parens.require_close (parser))
7222 	{
7223 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7224 	  return NULL_TREE;
7225 	}
7226       list = chainon (list, build_tree_list (build_tree_list (name, str),
7227 					     expr.value));
7228       if (c_parser_next_token_is (parser, CPP_COMMA))
7229 	c_parser_consume_token (parser);
7230       else
7231 	break;
7232     }
7233   return list;
7234 }
7235 
7236 /* Parse asm clobbers, a GNU extension.
7237 
7238    asm-clobbers:
7239      asm-string-literal
7240      asm-clobbers , asm-string-literal
7241 */
7242 
7243 static tree
c_parser_asm_clobbers(c_parser * parser)7244 c_parser_asm_clobbers (c_parser *parser)
7245 {
7246   tree list = NULL_TREE;
7247   while (true)
7248     {
7249       tree str = c_parser_asm_string_literal (parser);
7250       if (str)
7251 	list = tree_cons (NULL_TREE, str, list);
7252       else
7253 	return NULL_TREE;
7254       if (c_parser_next_token_is (parser, CPP_COMMA))
7255 	c_parser_consume_token (parser);
7256       else
7257 	break;
7258     }
7259   return list;
7260 }
7261 
7262 /* Parse asm goto labels, a GNU extension.
7263 
7264    asm-goto-operands:
7265      identifier
7266      asm-goto-operands , identifier
7267 */
7268 
7269 static tree
c_parser_asm_goto_operands(c_parser * parser)7270 c_parser_asm_goto_operands (c_parser *parser)
7271 {
7272   tree list = NULL_TREE;
7273   while (true)
7274     {
7275       tree name, label;
7276 
7277       if (c_parser_next_token_is (parser, CPP_NAME))
7278 	{
7279 	  c_token *tok = c_parser_peek_token (parser);
7280 	  name = tok->value;
7281 	  label = lookup_label_for_goto (tok->location, name);
7282 	  c_parser_consume_token (parser);
7283 	  TREE_USED (label) = 1;
7284 	}
7285       else
7286 	{
7287 	  c_parser_error (parser, "expected identifier");
7288 	  return NULL_TREE;
7289 	}
7290 
7291       name = build_string (IDENTIFIER_LENGTH (name),
7292 			   IDENTIFIER_POINTER (name));
7293       list = tree_cons (name, label, list);
7294       if (c_parser_next_token_is (parser, CPP_COMMA))
7295 	c_parser_consume_token (parser);
7296       else
7297 	return nreverse (list);
7298     }
7299 }
7300 
7301 /* Parse a possibly concatenated sequence of string literals.
7302    TRANSLATE says whether to translate them to the execution character
7303    set; WIDE_OK says whether any kind of prefixed string literal is
7304    permitted in this context.  This code is based on that in
7305    lex_string.  */
7306 
7307 struct c_expr
c_parser_string_literal(c_parser * parser,bool translate,bool wide_ok)7308 c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok)
7309 {
7310   struct c_expr ret;
7311   size_t count;
7312   struct obstack str_ob;
7313   struct obstack loc_ob;
7314   cpp_string str, istr, *strs;
7315   c_token *tok;
7316   location_t loc, last_tok_loc;
7317   enum cpp_ttype type;
7318   tree value, string_tree;
7319 
7320   tok = c_parser_peek_token (parser);
7321   loc = tok->location;
7322   last_tok_loc = linemap_resolve_location (line_table, loc,
7323 					   LRK_MACRO_DEFINITION_LOCATION,
7324 					   NULL);
7325   type = tok->type;
7326   switch (type)
7327     {
7328     case CPP_STRING:
7329     case CPP_WSTRING:
7330     case CPP_STRING16:
7331     case CPP_STRING32:
7332     case CPP_UTF8STRING:
7333       string_tree = tok->value;
7334       break;
7335 
7336     default:
7337       c_parser_error (parser, "expected string literal");
7338       ret.set_error ();
7339       ret.value = NULL_TREE;
7340       ret.original_code = ERROR_MARK;
7341       ret.original_type = NULL_TREE;
7342       return ret;
7343     }
7344 
7345   /* Try to avoid the overhead of creating and destroying an obstack
7346      for the common case of just one string.  */
7347   switch (c_parser_peek_2nd_token (parser)->type)
7348     {
7349     default:
7350       c_parser_consume_token (parser);
7351       str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
7352       str.len = TREE_STRING_LENGTH (string_tree);
7353       count = 1;
7354       strs = &str;
7355       break;
7356 
7357     case CPP_STRING:
7358     case CPP_WSTRING:
7359     case CPP_STRING16:
7360     case CPP_STRING32:
7361     case CPP_UTF8STRING:
7362       gcc_obstack_init (&str_ob);
7363       gcc_obstack_init (&loc_ob);
7364       count = 0;
7365       do
7366 	{
7367 	  c_parser_consume_token (parser);
7368 	  count++;
7369 	  str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
7370 	  str.len = TREE_STRING_LENGTH (string_tree);
7371 	  if (type != tok->type)
7372 	    {
7373 	      if (type == CPP_STRING)
7374 		type = tok->type;
7375 	      else if (tok->type != CPP_STRING)
7376 		error ("unsupported non-standard concatenation "
7377 		       "of string literals");
7378 	    }
7379 	  obstack_grow (&str_ob, &str, sizeof (cpp_string));
7380 	  obstack_grow (&loc_ob, &last_tok_loc, sizeof (location_t));
7381 	  tok = c_parser_peek_token (parser);
7382 	  string_tree = tok->value;
7383 	  last_tok_loc
7384 	    = linemap_resolve_location (line_table, tok->location,
7385 					LRK_MACRO_DEFINITION_LOCATION, NULL);
7386 	}
7387       while (tok->type == CPP_STRING
7388 	     || tok->type == CPP_WSTRING
7389 	     || tok->type == CPP_STRING16
7390 	     || tok->type == CPP_STRING32
7391 	     || tok->type == CPP_UTF8STRING);
7392       strs = (cpp_string *) obstack_finish (&str_ob);
7393     }
7394 
7395   if (count > 1 && !in_system_header_at (input_location))
7396     warning (OPT_Wtraditional,
7397 	     "traditional C rejects string constant concatenation");
7398 
7399   if ((type == CPP_STRING || wide_ok)
7400       && ((translate
7401 	  ? cpp_interpret_string : cpp_interpret_string_notranslate)
7402 	  (parse_in, strs, count, &istr, type)))
7403     {
7404       value = build_string (istr.len, (const char *) istr.text);
7405       free (CONST_CAST (unsigned char *, istr.text));
7406       if (count > 1)
7407 	{
7408 	  location_t *locs = (location_t *) obstack_finish (&loc_ob);
7409 	  gcc_assert (g_string_concat_db);
7410 	  g_string_concat_db->record_string_concatenation (count, locs);
7411 	}
7412     }
7413   else
7414     {
7415       if (type != CPP_STRING && !wide_ok)
7416 	{
7417 	  error_at (loc, "a wide string is invalid in this context");
7418 	  type = CPP_STRING;
7419 	}
7420       /* Callers cannot generally handle error_mark_node in this
7421 	 context, so return the empty string instead.  An error has
7422 	 been issued, either above or from cpp_interpret_string.  */
7423       switch (type)
7424 	{
7425 	default:
7426 	case CPP_STRING:
7427 	case CPP_UTF8STRING:
7428 	  value = build_string (1, "");
7429 	  break;
7430 	case CPP_STRING16:
7431 	  value = build_string (TYPE_PRECISION (char16_type_node)
7432 				/ TYPE_PRECISION (char_type_node),
7433 				"\0");  /* char16_t is 16 bits */
7434 	  break;
7435 	case CPP_STRING32:
7436 	  value = build_string (TYPE_PRECISION (char32_type_node)
7437 				/ TYPE_PRECISION (char_type_node),
7438 				"\0\0\0");  /* char32_t is 32 bits */
7439 	  break;
7440 	case CPP_WSTRING:
7441 	  value = build_string (TYPE_PRECISION (wchar_type_node)
7442 				/ TYPE_PRECISION (char_type_node),
7443 				"\0\0\0");  /* widest supported wchar_t
7444 					       is 32 bits */
7445 	  break;
7446         }
7447     }
7448 
7449   switch (type)
7450     {
7451     default:
7452     case CPP_STRING:
7453     case CPP_UTF8STRING:
7454       TREE_TYPE (value) = char_array_type_node;
7455       break;
7456     case CPP_STRING16:
7457       TREE_TYPE (value) = char16_array_type_node;
7458       break;
7459     case CPP_STRING32:
7460       TREE_TYPE (value) = char32_array_type_node;
7461       break;
7462     case CPP_WSTRING:
7463       TREE_TYPE (value) = wchar_array_type_node;
7464     }
7465   value = fix_string_type (value);
7466 
7467   if (count > 1)
7468     {
7469       obstack_free (&str_ob, 0);
7470       obstack_free (&loc_ob, 0);
7471     }
7472 
7473   ret.value = value;
7474   ret.original_code = STRING_CST;
7475   ret.original_type = NULL_TREE;
7476   set_c_expr_source_range (&ret, get_range_from_loc (line_table, loc));
7477   parser->seen_string_literal = true;
7478   return ret;
7479 }
7480 
7481 /* Parse an expression other than a compound expression; that is, an
7482    assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16).  If
7483    AFTER is not NULL then it is an Objective-C message expression which
7484    is the primary-expression starting the expression as an initializer.
7485 
7486    assignment-expression:
7487      conditional-expression
7488      unary-expression assignment-operator assignment-expression
7489 
7490    assignment-operator: one of
7491      = *= /= %= += -= <<= >>= &= ^= |=
7492 
7493    In GNU C we accept any conditional expression on the LHS and
7494    diagnose the invalid lvalue rather than producing a syntax
7495    error.  */
7496 
7497 static struct c_expr
c_parser_expr_no_commas(c_parser * parser,struct c_expr * after,tree omp_atomic_lhs)7498 c_parser_expr_no_commas (c_parser *parser, struct c_expr *after,
7499 			 tree omp_atomic_lhs)
7500 {
7501   struct c_expr lhs, rhs, ret;
7502   enum tree_code code;
7503   location_t op_location, exp_location;
7504   bool save_in_omp_for = c_in_omp_for;
7505   c_in_omp_for = false;
7506   gcc_assert (!after || c_dialect_objc ());
7507   lhs = c_parser_conditional_expression (parser, after, omp_atomic_lhs);
7508   op_location = c_parser_peek_token (parser)->location;
7509   switch (c_parser_peek_token (parser)->type)
7510     {
7511     case CPP_EQ:
7512       code = NOP_EXPR;
7513       break;
7514     case CPP_MULT_EQ:
7515       code = MULT_EXPR;
7516       break;
7517     case CPP_DIV_EQ:
7518       code = TRUNC_DIV_EXPR;
7519       break;
7520     case CPP_MOD_EQ:
7521       code = TRUNC_MOD_EXPR;
7522       break;
7523     case CPP_PLUS_EQ:
7524       code = PLUS_EXPR;
7525       break;
7526     case CPP_MINUS_EQ:
7527       code = MINUS_EXPR;
7528       break;
7529     case CPP_LSHIFT_EQ:
7530       code = LSHIFT_EXPR;
7531       break;
7532     case CPP_RSHIFT_EQ:
7533       code = RSHIFT_EXPR;
7534       break;
7535     case CPP_AND_EQ:
7536       code = BIT_AND_EXPR;
7537       break;
7538     case CPP_XOR_EQ:
7539       code = BIT_XOR_EXPR;
7540       break;
7541     case CPP_OR_EQ:
7542       code = BIT_IOR_EXPR;
7543       break;
7544     default:
7545       c_in_omp_for = save_in_omp_for;
7546       return lhs;
7547     }
7548   c_parser_consume_token (parser);
7549   exp_location = c_parser_peek_token (parser)->location;
7550   rhs = c_parser_expr_no_commas (parser, NULL);
7551   rhs = convert_lvalue_to_rvalue (exp_location, rhs, true, true);
7552 
7553   ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
7554 				 code, exp_location, rhs.value,
7555 				 rhs.original_type);
7556   set_c_expr_source_range (&ret, lhs.get_start (), rhs.get_finish ());
7557   if (code == NOP_EXPR)
7558     ret.original_code = MODIFY_EXPR;
7559   else
7560     {
7561       TREE_NO_WARNING (ret.value) = 1;
7562       ret.original_code = ERROR_MARK;
7563     }
7564   ret.original_type = NULL;
7565   c_in_omp_for = save_in_omp_for;
7566   return ret;
7567 }
7568 
7569 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15).  If
7570    AFTER is not NULL then it is an Objective-C message expression which is
7571    the primary-expression starting the expression as an initializer.
7572 
7573    conditional-expression:
7574      logical-OR-expression
7575      logical-OR-expression ? expression : conditional-expression
7576 
7577    GNU extensions:
7578 
7579    conditional-expression:
7580      logical-OR-expression ? : conditional-expression
7581 */
7582 
7583 static struct c_expr
c_parser_conditional_expression(c_parser * parser,struct c_expr * after,tree omp_atomic_lhs)7584 c_parser_conditional_expression (c_parser *parser, struct c_expr *after,
7585 				 tree omp_atomic_lhs)
7586 {
7587   struct c_expr cond, exp1, exp2, ret;
7588   location_t start, cond_loc, colon_loc;
7589 
7590   gcc_assert (!after || c_dialect_objc ());
7591 
7592   cond = c_parser_binary_expression (parser, after, omp_atomic_lhs);
7593 
7594   if (c_parser_next_token_is_not (parser, CPP_QUERY))
7595     return cond;
7596   if (cond.value != error_mark_node)
7597     start = cond.get_start ();
7598   else
7599     start = UNKNOWN_LOCATION;
7600   cond_loc = c_parser_peek_token (parser)->location;
7601   cond = convert_lvalue_to_rvalue (cond_loc, cond, true, true);
7602   c_parser_consume_token (parser);
7603   if (c_parser_next_token_is (parser, CPP_COLON))
7604     {
7605       tree eptype = NULL_TREE;
7606 
7607       location_t middle_loc = c_parser_peek_token (parser)->location;
7608       pedwarn (middle_loc, OPT_Wpedantic,
7609 	       "ISO C forbids omitting the middle term of a %<?:%> expression");
7610       if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR)
7611 	{
7612 	  eptype = TREE_TYPE (cond.value);
7613 	  cond.value = TREE_OPERAND (cond.value, 0);
7614 	}
7615       tree e = cond.value;
7616       while (TREE_CODE (e) == COMPOUND_EXPR)
7617 	e = TREE_OPERAND (e, 1);
7618       warn_for_omitted_condop (middle_loc, e);
7619       /* Make sure first operand is calculated only once.  */
7620       exp1.value = save_expr (default_conversion (cond.value));
7621       if (eptype)
7622 	exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value);
7623       exp1.original_type = NULL;
7624       exp1.src_range = cond.src_range;
7625       cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value);
7626       c_inhibit_evaluation_warnings += cond.value == truthvalue_true_node;
7627     }
7628   else
7629     {
7630       cond.value
7631 	= c_objc_common_truthvalue_conversion
7632 	(cond_loc, default_conversion (cond.value));
7633       c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node;
7634       exp1 = c_parser_expression_conv (parser);
7635       mark_exp_read (exp1.value);
7636       c_inhibit_evaluation_warnings +=
7637 	((cond.value == truthvalue_true_node)
7638 	 - (cond.value == truthvalue_false_node));
7639     }
7640 
7641   colon_loc = c_parser_peek_token (parser)->location;
7642   if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
7643     {
7644       c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
7645       ret.set_error ();
7646       ret.original_code = ERROR_MARK;
7647       ret.original_type = NULL;
7648       return ret;
7649     }
7650   {
7651     location_t exp2_loc = c_parser_peek_token (parser)->location;
7652     exp2 = c_parser_conditional_expression (parser, NULL, NULL_TREE);
7653     exp2 = convert_lvalue_to_rvalue (exp2_loc, exp2, true, true);
7654   }
7655   c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
7656   location_t loc1 = make_location (exp1.get_start (), exp1.src_range);
7657   location_t loc2 = make_location (exp2.get_start (), exp2.src_range);
7658   ret.value = build_conditional_expr (colon_loc, cond.value,
7659 				      cond.original_code == C_MAYBE_CONST_EXPR,
7660 				      exp1.value, exp1.original_type, loc1,
7661 				      exp2.value, exp2.original_type, loc2);
7662   ret.original_code = ERROR_MARK;
7663   if (exp1.value == error_mark_node || exp2.value == error_mark_node)
7664     ret.original_type = NULL;
7665   else
7666     {
7667       tree t1, t2;
7668 
7669       /* If both sides are enum type, the default conversion will have
7670 	 made the type of the result be an integer type.  We want to
7671 	 remember the enum types we started with.  */
7672       t1 = exp1.original_type ? exp1.original_type : TREE_TYPE (exp1.value);
7673       t2 = exp2.original_type ? exp2.original_type : TREE_TYPE (exp2.value);
7674       ret.original_type = ((t1 != error_mark_node
7675 			    && t2 != error_mark_node
7676 			    && (TYPE_MAIN_VARIANT (t1)
7677 				== TYPE_MAIN_VARIANT (t2)))
7678 			   ? t1
7679 			   : NULL);
7680     }
7681   set_c_expr_source_range (&ret, start, exp2.get_finish ());
7682   return ret;
7683 }
7684 
7685 /* Parse a binary expression; that is, a logical-OR-expression (C90
7686    6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14).  If AFTER is not
7687    NULL then it is an Objective-C message expression which is the
7688    primary-expression starting the expression as an initializer.
7689 
7690    OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
7691    when it should be the unfolded lhs.  In a valid OpenMP source,
7692    one of the operands of the toplevel binary expression must be equal
7693    to it.  In that case, just return a build2 created binary operation
7694    rather than result of parser_build_binary_op.
7695 
7696    multiplicative-expression:
7697      cast-expression
7698      multiplicative-expression * cast-expression
7699      multiplicative-expression / cast-expression
7700      multiplicative-expression % cast-expression
7701 
7702    additive-expression:
7703      multiplicative-expression
7704      additive-expression + multiplicative-expression
7705      additive-expression - multiplicative-expression
7706 
7707    shift-expression:
7708      additive-expression
7709      shift-expression << additive-expression
7710      shift-expression >> additive-expression
7711 
7712    relational-expression:
7713      shift-expression
7714      relational-expression < shift-expression
7715      relational-expression > shift-expression
7716      relational-expression <= shift-expression
7717      relational-expression >= shift-expression
7718 
7719    equality-expression:
7720      relational-expression
7721      equality-expression == relational-expression
7722      equality-expression != relational-expression
7723 
7724    AND-expression:
7725      equality-expression
7726      AND-expression & equality-expression
7727 
7728    exclusive-OR-expression:
7729      AND-expression
7730      exclusive-OR-expression ^ AND-expression
7731 
7732    inclusive-OR-expression:
7733      exclusive-OR-expression
7734      inclusive-OR-expression | exclusive-OR-expression
7735 
7736    logical-AND-expression:
7737      inclusive-OR-expression
7738      logical-AND-expression && inclusive-OR-expression
7739 
7740    logical-OR-expression:
7741      logical-AND-expression
7742      logical-OR-expression || logical-AND-expression
7743 */
7744 
7745 static struct c_expr
c_parser_binary_expression(c_parser * parser,struct c_expr * after,tree omp_atomic_lhs)7746 c_parser_binary_expression (c_parser *parser, struct c_expr *after,
7747 			    tree omp_atomic_lhs)
7748 {
7749   /* A binary expression is parsed using operator-precedence parsing,
7750      with the operands being cast expressions.  All the binary
7751      operators are left-associative.  Thus a binary expression is of
7752      form:
7753 
7754      E0 op1 E1 op2 E2 ...
7755 
7756      which we represent on a stack.  On the stack, the precedence
7757      levels are strictly increasing.  When a new operator is
7758      encountered of higher precedence than that at the top of the
7759      stack, it is pushed; its LHS is the top expression, and its RHS
7760      is everything parsed until it is popped.  When a new operator is
7761      encountered with precedence less than or equal to that at the top
7762      of the stack, triples E[i-1] op[i] E[i] are popped and replaced
7763      by the result of the operation until the operator at the top of
7764      the stack has lower precedence than the new operator or there is
7765      only one element on the stack; then the top expression is the LHS
7766      of the new operator.  In the case of logical AND and OR
7767      expressions, we also need to adjust c_inhibit_evaluation_warnings
7768      as appropriate when the operators are pushed and popped.  */
7769 
7770   struct {
7771     /* The expression at this stack level.  */
7772     struct c_expr expr;
7773     /* The precedence of the operator on its left, PREC_NONE at the
7774        bottom of the stack.  */
7775     enum c_parser_prec prec;
7776     /* The operation on its left.  */
7777     enum tree_code op;
7778     /* The source location of this operation.  */
7779     location_t loc;
7780     /* The sizeof argument if expr.original_code == {PAREN_,}SIZEOF_EXPR.  */
7781     tree sizeof_arg;
7782   } stack[NUM_PRECS];
7783   int sp;
7784   /* Location of the binary operator.  */
7785   location_t binary_loc = UNKNOWN_LOCATION;  /* Quiet warning.  */
7786 #define POP								      \
7787   do {									      \
7788     switch (stack[sp].op)						      \
7789       {									      \
7790       case TRUTH_ANDIF_EXPR:						      \
7791 	c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value	      \
7792 					  == truthvalue_false_node);	      \
7793 	break;								      \
7794       case TRUTH_ORIF_EXPR:						      \
7795 	c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value	      \
7796 					  == truthvalue_true_node);	      \
7797 	break;								      \
7798       case TRUNC_DIV_EXPR:						      \
7799 	if ((stack[sp - 1].expr.original_code == SIZEOF_EXPR		      \
7800 	     || stack[sp - 1].expr.original_code == PAREN_SIZEOF_EXPR)	      \
7801 	    && (stack[sp].expr.original_code == SIZEOF_EXPR		      \
7802 		|| stack[sp].expr.original_code == PAREN_SIZEOF_EXPR))	      \
7803 	  {								      \
7804 	    tree type0 = stack[sp - 1].sizeof_arg;			      \
7805 	    tree type1 = stack[sp].sizeof_arg;				      \
7806 	    tree first_arg = type0;					      \
7807 	    if (!TYPE_P (type0))					      \
7808 	      type0 = TREE_TYPE (type0);				      \
7809 	    if (!TYPE_P (type1))					      \
7810 	      type1 = TREE_TYPE (type1);				      \
7811 	    if (POINTER_TYPE_P (type0)					      \
7812 		&& comptypes (TREE_TYPE (type0), type1)			      \
7813 		&& !(TREE_CODE (first_arg) == PARM_DECL			      \
7814 		     && C_ARRAY_PARAMETER (first_arg)			      \
7815 		     && warn_sizeof_array_argument))			      \
7816 	      {								      \
7817 		auto_diagnostic_group d;				      \
7818 		if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div,	      \
7819 				  "division %<sizeof (%T) / sizeof (%T)%> "   \
7820 				  "does not compute the number of array "     \
7821 				  "elements",				      \
7822 				  type0, type1))			      \
7823 		  if (DECL_P (first_arg))				      \
7824 		    inform (DECL_SOURCE_LOCATION (first_arg),		      \
7825 			      "first %<sizeof%> operand was declared here");  \
7826 	      }								      \
7827 	    else if (TREE_CODE (type0) == ARRAY_TYPE			      \
7828 		     && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0)))  \
7829 		     && stack[sp].expr.original_code != PAREN_SIZEOF_EXPR)    \
7830 	      maybe_warn_sizeof_array_div (stack[sp].loc, first_arg, type0,   \
7831 					   stack[sp].sizeof_arg, type1);      \
7832 	  }								      \
7833 	break;								      \
7834       default:								      \
7835 	break;								      \
7836       }									      \
7837     stack[sp - 1].expr							      \
7838       = convert_lvalue_to_rvalue (stack[sp - 1].loc,			      \
7839 				  stack[sp - 1].expr, true, true);	      \
7840     stack[sp].expr							      \
7841       = convert_lvalue_to_rvalue (stack[sp].loc,			      \
7842 				  stack[sp].expr, true, true);		      \
7843     if (__builtin_expect (omp_atomic_lhs != NULL_TREE, 0) && sp == 1	      \
7844 	&& c_parser_peek_token (parser)->type == CPP_SEMICOLON		      \
7845 	&& ((1 << stack[sp].prec)					      \
7846 	    & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) | (1 << PREC_BITAND)    \
7847 	       | (1 << PREC_SHIFT) | (1 << PREC_ADD) | (1 << PREC_MULT)))     \
7848 	&& stack[sp].op != TRUNC_MOD_EXPR				      \
7849 	&& stack[0].expr.value != error_mark_node			      \
7850 	&& stack[1].expr.value != error_mark_node			      \
7851 	&& (c_tree_equal (stack[0].expr.value, omp_atomic_lhs)		      \
7852 	    || c_tree_equal (stack[1].expr.value, omp_atomic_lhs)))	      \
7853       {									      \
7854 	tree t = make_node (stack[1].op);				      \
7855 	TREE_TYPE (t) = TREE_TYPE (stack[0].expr.value);		      \
7856 	TREE_OPERAND (t, 0) = stack[0].expr.value;			      \
7857 	TREE_OPERAND (t, 1) = stack[1].expr.value;			      \
7858 	stack[0].expr.value = t;					      \
7859       }									      \
7860     else								      \
7861       stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc,	      \
7862 						   stack[sp].op,	      \
7863 						   stack[sp - 1].expr,	      \
7864 						   stack[sp].expr);	      \
7865     sp--;								      \
7866   } while (0)
7867   gcc_assert (!after || c_dialect_objc ());
7868   stack[0].loc = c_parser_peek_token (parser)->location;
7869   stack[0].expr = c_parser_cast_expression (parser, after);
7870   stack[0].prec = PREC_NONE;
7871   stack[0].sizeof_arg = c_last_sizeof_arg;
7872   sp = 0;
7873   while (true)
7874     {
7875       enum c_parser_prec oprec;
7876       enum tree_code ocode;
7877       source_range src_range;
7878       if (parser->error)
7879 	goto out;
7880       switch (c_parser_peek_token (parser)->type)
7881 	{
7882 	case CPP_MULT:
7883 	  oprec = PREC_MULT;
7884 	  ocode = MULT_EXPR;
7885 	  break;
7886 	case CPP_DIV:
7887 	  oprec = PREC_MULT;
7888 	  ocode = TRUNC_DIV_EXPR;
7889 	  break;
7890 	case CPP_MOD:
7891 	  oprec = PREC_MULT;
7892 	  ocode = TRUNC_MOD_EXPR;
7893 	  break;
7894 	case CPP_PLUS:
7895 	  oprec = PREC_ADD;
7896 	  ocode = PLUS_EXPR;
7897 	  break;
7898 	case CPP_MINUS:
7899 	  oprec = PREC_ADD;
7900 	  ocode = MINUS_EXPR;
7901 	  break;
7902 	case CPP_LSHIFT:
7903 	  oprec = PREC_SHIFT;
7904 	  ocode = LSHIFT_EXPR;
7905 	  break;
7906 	case CPP_RSHIFT:
7907 	  oprec = PREC_SHIFT;
7908 	  ocode = RSHIFT_EXPR;
7909 	  break;
7910 	case CPP_LESS:
7911 	  oprec = PREC_REL;
7912 	  ocode = LT_EXPR;
7913 	  break;
7914 	case CPP_GREATER:
7915 	  oprec = PREC_REL;
7916 	  ocode = GT_EXPR;
7917 	  break;
7918 	case CPP_LESS_EQ:
7919 	  oprec = PREC_REL;
7920 	  ocode = LE_EXPR;
7921 	  break;
7922 	case CPP_GREATER_EQ:
7923 	  oprec = PREC_REL;
7924 	  ocode = GE_EXPR;
7925 	  break;
7926 	case CPP_EQ_EQ:
7927 	  oprec = PREC_EQ;
7928 	  ocode = EQ_EXPR;
7929 	  break;
7930 	case CPP_NOT_EQ:
7931 	  oprec = PREC_EQ;
7932 	  ocode = NE_EXPR;
7933 	  break;
7934 	case CPP_AND:
7935 	  oprec = PREC_BITAND;
7936 	  ocode = BIT_AND_EXPR;
7937 	  break;
7938 	case CPP_XOR:
7939 	  oprec = PREC_BITXOR;
7940 	  ocode = BIT_XOR_EXPR;
7941 	  break;
7942 	case CPP_OR:
7943 	  oprec = PREC_BITOR;
7944 	  ocode = BIT_IOR_EXPR;
7945 	  break;
7946 	case CPP_AND_AND:
7947 	  oprec = PREC_LOGAND;
7948 	  ocode = TRUTH_ANDIF_EXPR;
7949 	  break;
7950 	case CPP_OR_OR:
7951 	  oprec = PREC_LOGOR;
7952 	  ocode = TRUTH_ORIF_EXPR;
7953 	  break;
7954 	default:
7955 	  /* Not a binary operator, so end of the binary
7956 	     expression.  */
7957 	  goto out;
7958 	}
7959       binary_loc = c_parser_peek_token (parser)->location;
7960       while (oprec <= stack[sp].prec)
7961 	POP;
7962       c_parser_consume_token (parser);
7963       switch (ocode)
7964 	{
7965 	case TRUTH_ANDIF_EXPR:
7966 	  src_range = stack[sp].expr.src_range;
7967 	  stack[sp].expr
7968 	    = convert_lvalue_to_rvalue (stack[sp].loc,
7969 					stack[sp].expr, true, true);
7970 	  stack[sp].expr.value = c_objc_common_truthvalue_conversion
7971 	    (stack[sp].loc, default_conversion (stack[sp].expr.value));
7972 	  c_inhibit_evaluation_warnings += (stack[sp].expr.value
7973 					    == truthvalue_false_node);
7974 	  set_c_expr_source_range (&stack[sp].expr, src_range);
7975 	  break;
7976 	case TRUTH_ORIF_EXPR:
7977 	  src_range = stack[sp].expr.src_range;
7978 	  stack[sp].expr
7979 	    = convert_lvalue_to_rvalue (stack[sp].loc,
7980 					stack[sp].expr, true, true);
7981 	  stack[sp].expr.value = c_objc_common_truthvalue_conversion
7982 	    (stack[sp].loc, default_conversion (stack[sp].expr.value));
7983 	  c_inhibit_evaluation_warnings += (stack[sp].expr.value
7984 					    == truthvalue_true_node);
7985 	  set_c_expr_source_range (&stack[sp].expr, src_range);
7986 	  break;
7987 	default:
7988 	  break;
7989 	}
7990       sp++;
7991       stack[sp].loc = binary_loc;
7992       stack[sp].expr = c_parser_cast_expression (parser, NULL);
7993       stack[sp].prec = oprec;
7994       stack[sp].op = ocode;
7995       stack[sp].sizeof_arg = c_last_sizeof_arg;
7996     }
7997  out:
7998   while (sp > 0)
7999     POP;
8000   return stack[0].expr;
8001 #undef POP
8002 }
8003 
8004 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4).  If AFTER
8005    is not NULL then it is an Objective-C message expression which is the
8006    primary-expression starting the expression as an initializer.
8007 
8008    cast-expression:
8009      unary-expression
8010      ( type-name ) unary-expression
8011 */
8012 
8013 static struct c_expr
c_parser_cast_expression(c_parser * parser,struct c_expr * after)8014 c_parser_cast_expression (c_parser *parser, struct c_expr *after)
8015 {
8016   location_t cast_loc = c_parser_peek_token (parser)->location;
8017   gcc_assert (!after || c_dialect_objc ());
8018   if (after)
8019     return c_parser_postfix_expression_after_primary (parser,
8020 						      cast_loc, *after);
8021   /* If the expression begins with a parenthesized type name, it may
8022      be either a cast or a compound literal; we need to see whether
8023      the next character is '{' to tell the difference.  If not, it is
8024      an unary expression.  Full detection of unknown typenames here
8025      would require a 3-token lookahead.  */
8026   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8027       && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8028     {
8029       struct c_type_name *type_name;
8030       struct c_expr ret;
8031       struct c_expr expr;
8032       matching_parens parens;
8033       parens.consume_open (parser);
8034       type_name = c_parser_type_name (parser, true);
8035       parens.skip_until_found_close (parser);
8036       if (type_name == NULL)
8037 	{
8038 	  ret.set_error ();
8039 	  ret.original_code = ERROR_MARK;
8040 	  ret.original_type = NULL;
8041 	  return ret;
8042 	}
8043 
8044       /* Save casted types in the function's used types hash table.  */
8045       used_types_insert (type_name->specs->type);
8046 
8047       if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8048 	return c_parser_postfix_expression_after_paren_type (parser, type_name,
8049 							     cast_loc);
8050       if (type_name->specs->alignas_p)
8051 	error_at (type_name->specs->locations[cdw_alignas],
8052 		  "alignment specified for type name in cast");
8053       {
8054 	location_t expr_loc = c_parser_peek_token (parser)->location;
8055 	expr = c_parser_cast_expression (parser, NULL);
8056 	expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
8057       }
8058       ret.value = c_cast_expr (cast_loc, type_name, expr.value);
8059       if (ret.value && expr.value)
8060 	set_c_expr_source_range (&ret, cast_loc, expr.get_finish ());
8061       ret.original_code = ERROR_MARK;
8062       ret.original_type = NULL;
8063       return ret;
8064     }
8065   else
8066     return c_parser_unary_expression (parser);
8067 }
8068 
8069 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
8070 
8071    unary-expression:
8072      postfix-expression
8073      ++ unary-expression
8074      -- unary-expression
8075      unary-operator cast-expression
8076      sizeof unary-expression
8077      sizeof ( type-name )
8078 
8079    unary-operator: one of
8080      & * + - ~ !
8081 
8082    GNU extensions:
8083 
8084    unary-expression:
8085      __alignof__ unary-expression
8086      __alignof__ ( type-name )
8087      && identifier
8088 
8089    (C11 permits _Alignof with type names only.)
8090 
8091    unary-operator: one of
8092      __extension__ __real__ __imag__
8093 
8094    Transactional Memory:
8095 
8096    unary-expression:
8097      transaction-expression
8098 
8099    In addition, the GNU syntax treats ++ and -- as unary operators, so
8100    they may be applied to cast expressions with errors for non-lvalues
8101    given later.  */
8102 
8103 static struct c_expr
c_parser_unary_expression(c_parser * parser)8104 c_parser_unary_expression (c_parser *parser)
8105 {
8106   int ext;
8107   struct c_expr ret, op;
8108   location_t op_loc = c_parser_peek_token (parser)->location;
8109   location_t exp_loc;
8110   location_t finish;
8111   ret.original_code = ERROR_MARK;
8112   ret.original_type = NULL;
8113   switch (c_parser_peek_token (parser)->type)
8114     {
8115     case CPP_PLUS_PLUS:
8116       c_parser_consume_token (parser);
8117       exp_loc = c_parser_peek_token (parser)->location;
8118       op = c_parser_cast_expression (parser, NULL);
8119 
8120       op = default_function_array_read_conversion (exp_loc, op);
8121       return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
8122     case CPP_MINUS_MINUS:
8123       c_parser_consume_token (parser);
8124       exp_loc = c_parser_peek_token (parser)->location;
8125       op = c_parser_cast_expression (parser, NULL);
8126 
8127       op = default_function_array_read_conversion (exp_loc, op);
8128       return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
8129     case CPP_AND:
8130       c_parser_consume_token (parser);
8131       op = c_parser_cast_expression (parser, NULL);
8132       mark_exp_read (op.value);
8133       return parser_build_unary_op (op_loc, ADDR_EXPR, op);
8134     case CPP_MULT:
8135       {
8136 	c_parser_consume_token (parser);
8137 	exp_loc = c_parser_peek_token (parser)->location;
8138 	op = c_parser_cast_expression (parser, NULL);
8139 	finish = op.get_finish ();
8140 	op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8141 	location_t combined_loc = make_location (op_loc, op_loc, finish);
8142 	ret.value = build_indirect_ref (combined_loc, op.value, RO_UNARY_STAR);
8143 	ret.src_range.m_start = op_loc;
8144 	ret.src_range.m_finish = finish;
8145 	return ret;
8146       }
8147     case CPP_PLUS:
8148       if (!c_dialect_objc () && !in_system_header_at (input_location))
8149 	warning_at (op_loc,
8150 		    OPT_Wtraditional,
8151 		    "traditional C rejects the unary plus operator");
8152       c_parser_consume_token (parser);
8153       exp_loc = c_parser_peek_token (parser)->location;
8154       op = c_parser_cast_expression (parser, NULL);
8155       op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8156       return parser_build_unary_op (op_loc, CONVERT_EXPR, op);
8157     case CPP_MINUS:
8158       c_parser_consume_token (parser);
8159       exp_loc = c_parser_peek_token (parser)->location;
8160       op = c_parser_cast_expression (parser, NULL);
8161       op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8162       return parser_build_unary_op (op_loc, NEGATE_EXPR, op);
8163     case CPP_COMPL:
8164       c_parser_consume_token (parser);
8165       exp_loc = c_parser_peek_token (parser)->location;
8166       op = c_parser_cast_expression (parser, NULL);
8167       op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8168       return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
8169     case CPP_NOT:
8170       c_parser_consume_token (parser);
8171       exp_loc = c_parser_peek_token (parser)->location;
8172       op = c_parser_cast_expression (parser, NULL);
8173       op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8174       return parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op);
8175     case CPP_AND_AND:
8176       /* Refer to the address of a label as a pointer.  */
8177       c_parser_consume_token (parser);
8178       if (c_parser_next_token_is (parser, CPP_NAME))
8179 	{
8180 	  ret.value = finish_label_address_expr
8181 	    (c_parser_peek_token (parser)->value, op_loc);
8182 	  set_c_expr_source_range (&ret, op_loc,
8183 				   c_parser_peek_token (parser)->get_finish ());
8184 	  c_parser_consume_token (parser);
8185 	}
8186       else
8187 	{
8188 	  c_parser_error (parser, "expected identifier");
8189 	  ret.set_error ();
8190 	}
8191       return ret;
8192     case CPP_KEYWORD:
8193       switch (c_parser_peek_token (parser)->keyword)
8194 	{
8195 	case RID_SIZEOF:
8196 	  return c_parser_sizeof_expression (parser);
8197 	case RID_ALIGNOF:
8198 	  return c_parser_alignof_expression (parser);
8199 	case RID_BUILTIN_HAS_ATTRIBUTE:
8200 	  return c_parser_has_attribute_expression (parser);
8201 	case RID_EXTENSION:
8202 	  c_parser_consume_token (parser);
8203 	  ext = disable_extension_diagnostics ();
8204 	  ret = c_parser_cast_expression (parser, NULL);
8205 	  restore_extension_diagnostics (ext);
8206 	  return ret;
8207 	case RID_REALPART:
8208 	  c_parser_consume_token (parser);
8209 	  exp_loc = c_parser_peek_token (parser)->location;
8210 	  op = c_parser_cast_expression (parser, NULL);
8211 	  op = default_function_array_conversion (exp_loc, op);
8212 	  return parser_build_unary_op (op_loc, REALPART_EXPR, op);
8213 	case RID_IMAGPART:
8214 	  c_parser_consume_token (parser);
8215 	  exp_loc = c_parser_peek_token (parser)->location;
8216 	  op = c_parser_cast_expression (parser, NULL);
8217 	  op = default_function_array_conversion (exp_loc, op);
8218 	  return parser_build_unary_op (op_loc, IMAGPART_EXPR, op);
8219 	case RID_TRANSACTION_ATOMIC:
8220 	case RID_TRANSACTION_RELAXED:
8221 	  return c_parser_transaction_expression (parser,
8222 	      c_parser_peek_token (parser)->keyword);
8223 	default:
8224 	  return c_parser_postfix_expression (parser);
8225 	}
8226     default:
8227       return c_parser_postfix_expression (parser);
8228     }
8229 }
8230 
8231 /* Parse a sizeof expression.  */
8232 
8233 static struct c_expr
c_parser_sizeof_expression(c_parser * parser)8234 c_parser_sizeof_expression (c_parser *parser)
8235 {
8236   struct c_expr expr;
8237   struct c_expr result;
8238   location_t expr_loc;
8239   gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF));
8240 
8241   location_t start;
8242   location_t finish = UNKNOWN_LOCATION;
8243 
8244   start = c_parser_peek_token (parser)->location;
8245 
8246   c_parser_consume_token (parser);
8247   c_inhibit_evaluation_warnings++;
8248   in_sizeof++;
8249   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8250       && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8251     {
8252       /* Either sizeof ( type-name ) or sizeof unary-expression
8253 	 starting with a compound literal.  */
8254       struct c_type_name *type_name;
8255       matching_parens parens;
8256       parens.consume_open (parser);
8257       expr_loc = c_parser_peek_token (parser)->location;
8258       type_name = c_parser_type_name (parser, true);
8259       parens.skip_until_found_close (parser);
8260       finish = parser->tokens_buf[0].location;
8261       if (type_name == NULL)
8262 	{
8263 	  struct c_expr ret;
8264 	  c_inhibit_evaluation_warnings--;
8265 	  in_sizeof--;
8266 	  ret.set_error ();
8267 	  ret.original_code = ERROR_MARK;
8268 	  ret.original_type = NULL;
8269 	  return ret;
8270 	}
8271       if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8272 	{
8273 	  expr = c_parser_postfix_expression_after_paren_type (parser,
8274 							       type_name,
8275 							       expr_loc);
8276 	  finish = expr.get_finish ();
8277 	  goto sizeof_expr;
8278 	}
8279       /* sizeof ( type-name ).  */
8280       if (type_name->specs->alignas_p)
8281 	error_at (type_name->specs->locations[cdw_alignas],
8282 		  "alignment specified for type name in %<sizeof%>");
8283       c_inhibit_evaluation_warnings--;
8284       in_sizeof--;
8285       result = c_expr_sizeof_type (expr_loc, type_name);
8286     }
8287   else
8288     {
8289       expr_loc = c_parser_peek_token (parser)->location;
8290       expr = c_parser_unary_expression (parser);
8291       finish = expr.get_finish ();
8292     sizeof_expr:
8293       c_inhibit_evaluation_warnings--;
8294       in_sizeof--;
8295       mark_exp_read (expr.value);
8296       if (TREE_CODE (expr.value) == COMPONENT_REF
8297 	  && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
8298 	error_at (expr_loc, "%<sizeof%> applied to a bit-field");
8299       result = c_expr_sizeof_expr (expr_loc, expr);
8300     }
8301   if (finish == UNKNOWN_LOCATION)
8302     finish = start;
8303   set_c_expr_source_range (&result, start, finish);
8304   return result;
8305 }
8306 
8307 /* Parse an alignof expression.  */
8308 
8309 static struct c_expr
c_parser_alignof_expression(c_parser * parser)8310 c_parser_alignof_expression (c_parser *parser)
8311 {
8312   struct c_expr expr;
8313   location_t start_loc = c_parser_peek_token (parser)->location;
8314   location_t end_loc;
8315   tree alignof_spelling = c_parser_peek_token (parser)->value;
8316   gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF));
8317   bool is_c11_alignof = strcmp (IDENTIFIER_POINTER (alignof_spelling),
8318 				"_Alignof") == 0;
8319   /* A diagnostic is not required for the use of this identifier in
8320      the implementation namespace; only diagnose it for the C11
8321      spelling because of existing code using the other spellings.  */
8322   if (is_c11_alignof)
8323     {
8324       if (flag_isoc99)
8325 	pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C99 does not support %qE",
8326 		     alignof_spelling);
8327       else
8328 	pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C90 does not support %qE",
8329 		     alignof_spelling);
8330     }
8331   c_parser_consume_token (parser);
8332   c_inhibit_evaluation_warnings++;
8333   in_alignof++;
8334   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8335       && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8336     {
8337       /* Either __alignof__ ( type-name ) or __alignof__
8338 	 unary-expression starting with a compound literal.  */
8339       location_t loc;
8340       struct c_type_name *type_name;
8341       struct c_expr ret;
8342       matching_parens parens;
8343       parens.consume_open (parser);
8344       loc = c_parser_peek_token (parser)->location;
8345       type_name = c_parser_type_name (parser, true);
8346       end_loc = c_parser_peek_token (parser)->location;
8347       parens.skip_until_found_close (parser);
8348       if (type_name == NULL)
8349 	{
8350 	  struct c_expr ret;
8351 	  c_inhibit_evaluation_warnings--;
8352 	  in_alignof--;
8353 	  ret.set_error ();
8354 	  ret.original_code = ERROR_MARK;
8355 	  ret.original_type = NULL;
8356 	  return ret;
8357 	}
8358       if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8359 	{
8360 	  expr = c_parser_postfix_expression_after_paren_type (parser,
8361 							       type_name,
8362 							       loc);
8363 	  goto alignof_expr;
8364 	}
8365       /* alignof ( type-name ).  */
8366       if (type_name->specs->alignas_p)
8367 	error_at (type_name->specs->locations[cdw_alignas],
8368 		  "alignment specified for type name in %qE",
8369 		  alignof_spelling);
8370       c_inhibit_evaluation_warnings--;
8371       in_alignof--;
8372       ret.value = c_sizeof_or_alignof_type (loc, groktypename (type_name,
8373 							       NULL, NULL),
8374 					    false, is_c11_alignof, 1);
8375       ret.original_code = ERROR_MARK;
8376       ret.original_type = NULL;
8377       set_c_expr_source_range (&ret, start_loc, end_loc);
8378       return ret;
8379     }
8380   else
8381     {
8382       struct c_expr ret;
8383       expr = c_parser_unary_expression (parser);
8384       end_loc = expr.src_range.m_finish;
8385     alignof_expr:
8386       mark_exp_read (expr.value);
8387       c_inhibit_evaluation_warnings--;
8388       in_alignof--;
8389       if (is_c11_alignof)
8390 	pedwarn (start_loc,
8391 		 OPT_Wpedantic, "ISO C does not allow %<%E (expression)%>",
8392 		 alignof_spelling);
8393       ret.value = c_alignof_expr (start_loc, expr.value);
8394       ret.original_code = ERROR_MARK;
8395       ret.original_type = NULL;
8396       set_c_expr_source_range (&ret, start_loc, end_loc);
8397       return ret;
8398     }
8399 }
8400 
8401 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
8402    expression.  */
8403 
8404 static struct c_expr
c_parser_has_attribute_expression(c_parser * parser)8405 c_parser_has_attribute_expression (c_parser *parser)
8406 {
8407   gcc_assert (c_parser_next_token_is_keyword (parser,
8408 					      RID_BUILTIN_HAS_ATTRIBUTE));
8409   location_t start = c_parser_peek_token (parser)->location;
8410   c_parser_consume_token (parser);
8411 
8412   c_inhibit_evaluation_warnings++;
8413 
8414   matching_parens parens;
8415   if (!parens.require_open (parser))
8416     {
8417       c_inhibit_evaluation_warnings--;
8418       in_typeof--;
8419 
8420       struct c_expr result;
8421       result.set_error ();
8422       result.original_code = ERROR_MARK;
8423       result.original_type = NULL;
8424       return result;
8425     }
8426 
8427   /* Treat the type argument the same way as in typeof for the purposes
8428      of warnings.  FIXME: Generalize this so the warning refers to
8429      __builtin_has_attribute rather than typeof.  */
8430   in_typeof++;
8431 
8432   /* The first operand: one of DECL, EXPR, or TYPE.  */
8433   tree oper = NULL_TREE;
8434   if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
8435     {
8436       struct c_type_name *tname = c_parser_type_name (parser);
8437       in_typeof--;
8438       if (tname)
8439 	{
8440 	  oper = groktypename (tname, NULL, NULL);
8441 	  pop_maybe_used (variably_modified_type_p (oper, NULL_TREE));
8442 	}
8443     }
8444   else
8445     {
8446       struct c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
8447       c_inhibit_evaluation_warnings--;
8448       in_typeof--;
8449       if (cexpr.value != error_mark_node)
8450 	{
8451 	  mark_exp_read (cexpr.value);
8452 	  oper = cexpr.value;
8453 	  tree etype = TREE_TYPE (oper);
8454 	  bool was_vm = variably_modified_type_p (etype, NULL_TREE);
8455 	  /* This is returned with the type so that when the type is
8456 	     evaluated, this can be evaluated.  */
8457 	  if (was_vm)
8458 	    oper = c_fully_fold (oper, false, NULL);
8459 	  pop_maybe_used (was_vm);
8460 	}
8461     }
8462 
8463   struct c_expr result;
8464   result.original_code = ERROR_MARK;
8465   result.original_type = NULL;
8466 
8467   if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8468     {
8469       /* Consume the closing parenthesis if that's the next token
8470 	 in the likely case the built-in was invoked with fewer
8471 	 than two arguments.  */
8472       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8473 	c_parser_consume_token (parser);
8474       c_inhibit_evaluation_warnings--;
8475       result.set_error ();
8476       return result;
8477     }
8478 
8479   bool save_translate_strings_p = parser->translate_strings_p;
8480 
8481   location_t atloc = c_parser_peek_token (parser)->location;
8482   /* Parse a single attribute.  Require no leading comma and do not
8483      allow empty attributes.  */
8484   tree attr = c_parser_gnu_attribute (parser, NULL_TREE, false, false);
8485 
8486   parser->translate_strings_p = save_translate_strings_p;
8487 
8488   location_t finish = c_parser_peek_token (parser)->location;
8489   if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8490     c_parser_consume_token (parser);
8491   else
8492     {
8493       c_parser_error (parser, "expected identifier");
8494       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8495 
8496       result.set_error ();
8497       return result;
8498     }
8499 
8500   if (!attr)
8501     {
8502       error_at (atloc, "expected identifier");
8503       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
8504 				 "expected %<)%>");
8505       result.set_error ();
8506       return result;
8507     }
8508 
8509   result.original_code = INTEGER_CST;
8510   result.original_type = boolean_type_node;
8511 
8512   if (has_attribute (atloc, oper, attr, default_conversion))
8513     result.value = boolean_true_node;
8514   else
8515     result.value =  boolean_false_node;
8516 
8517   set_c_expr_source_range (&result, start, finish);
8518   return result;
8519 }
8520 
8521 /* Helper function to read arguments of builtins which are interfaces
8522    for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
8523    others.  The name of the builtin is passed using BNAME parameter.
8524    Function returns true if there were no errors while parsing and
8525    stores the arguments in CEXPR_LIST.  If it returns true,
8526    *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
8527    parenthesis.  */
8528 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)8529 c_parser_get_builtin_args (c_parser *parser, const char *bname,
8530 			   vec<c_expr_t, va_gc> **ret_cexpr_list,
8531 			   bool choose_expr_p,
8532 			   location_t *out_close_paren_loc)
8533 {
8534   location_t loc = c_parser_peek_token (parser)->location;
8535   vec<c_expr_t, va_gc> *cexpr_list;
8536   c_expr_t expr;
8537   bool saved_force_folding_builtin_constant_p;
8538 
8539   *ret_cexpr_list = NULL;
8540   if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
8541     {
8542       error_at (loc, "cannot take address of %qs", bname);
8543       return false;
8544     }
8545 
8546   c_parser_consume_token (parser);
8547 
8548   if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8549     {
8550       *out_close_paren_loc = c_parser_peek_token (parser)->location;
8551       c_parser_consume_token (parser);
8552       return true;
8553     }
8554 
8555   saved_force_folding_builtin_constant_p
8556     = force_folding_builtin_constant_p;
8557   force_folding_builtin_constant_p |= choose_expr_p;
8558   expr = c_parser_expr_no_commas (parser, NULL);
8559   force_folding_builtin_constant_p
8560     = saved_force_folding_builtin_constant_p;
8561   vec_alloc (cexpr_list, 1);
8562   vec_safe_push (cexpr_list, expr);
8563   while (c_parser_next_token_is (parser, CPP_COMMA))
8564     {
8565       c_parser_consume_token (parser);
8566       expr = c_parser_expr_no_commas (parser, NULL);
8567       vec_safe_push (cexpr_list, expr);
8568     }
8569 
8570   *out_close_paren_loc = c_parser_peek_token (parser)->location;
8571   if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
8572     return false;
8573 
8574   *ret_cexpr_list = cexpr_list;
8575   return true;
8576 }
8577 
8578 /* This represents a single generic-association.  */
8579 
8580 struct c_generic_association
8581 {
8582   /* The location of the starting token of the type.  */
8583   location_t type_location;
8584   /* The association's type, or NULL_TREE for 'default'.  */
8585   tree type;
8586   /* The association's expression.  */
8587   struct c_expr expression;
8588 };
8589 
8590 /* Parse a generic-selection.  (C11 6.5.1.1).
8591 
8592    generic-selection:
8593      _Generic ( assignment-expression , generic-assoc-list )
8594 
8595    generic-assoc-list:
8596      generic-association
8597      generic-assoc-list , generic-association
8598 
8599    generic-association:
8600      type-name : assignment-expression
8601      default : assignment-expression
8602 */
8603 
8604 static struct c_expr
c_parser_generic_selection(c_parser * parser)8605 c_parser_generic_selection (c_parser *parser)
8606 {
8607   struct c_expr selector, error_expr;
8608   tree selector_type;
8609   struct c_generic_association matched_assoc;
8610   int match_found = -1;
8611   location_t generic_loc, selector_loc;
8612 
8613   error_expr.original_code = ERROR_MARK;
8614   error_expr.original_type = NULL;
8615   error_expr.set_error ();
8616   matched_assoc.type_location = UNKNOWN_LOCATION;
8617   matched_assoc.type = NULL_TREE;
8618   matched_assoc.expression = error_expr;
8619 
8620   gcc_assert (c_parser_next_token_is_keyword (parser, RID_GENERIC));
8621   generic_loc = c_parser_peek_token (parser)->location;
8622   c_parser_consume_token (parser);
8623   if (flag_isoc99)
8624     pedwarn_c99 (generic_loc, OPT_Wpedantic,
8625 		 "ISO C99 does not support %<_Generic%>");
8626   else
8627     pedwarn_c99 (generic_loc, OPT_Wpedantic,
8628 		 "ISO C90 does not support %<_Generic%>");
8629 
8630   matching_parens parens;
8631   if (!parens.require_open (parser))
8632     return error_expr;
8633 
8634   c_inhibit_evaluation_warnings++;
8635   selector_loc = c_parser_peek_token (parser)->location;
8636   selector = c_parser_expr_no_commas (parser, NULL);
8637   selector = default_function_array_conversion (selector_loc, selector);
8638   c_inhibit_evaluation_warnings--;
8639 
8640   if (selector.value == error_mark_node)
8641     {
8642       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8643       return selector;
8644     }
8645   mark_exp_read (selector.value);
8646   selector_type = TREE_TYPE (selector.value);
8647   /* In ISO C terms, rvalues (including the controlling expression of
8648      _Generic) do not have qualified types.  */
8649   if (TREE_CODE (selector_type) != ARRAY_TYPE)
8650     selector_type = TYPE_MAIN_VARIANT (selector_type);
8651   /* In ISO C terms, _Noreturn is not part of the type of expressions
8652      such as &abort, but in GCC it is represented internally as a type
8653      qualifier.  */
8654   if (FUNCTION_POINTER_TYPE_P (selector_type)
8655       && TYPE_QUALS (TREE_TYPE (selector_type)) != TYPE_UNQUALIFIED)
8656     selector_type
8657       = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type)));
8658 
8659   if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8660     {
8661       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8662       return error_expr;
8663     }
8664 
8665   auto_vec<c_generic_association> associations;
8666   while (1)
8667     {
8668       struct c_generic_association assoc, *iter;
8669       unsigned int ix;
8670       c_token *token = c_parser_peek_token (parser);
8671 
8672       assoc.type_location = token->location;
8673       if (token->type == CPP_KEYWORD && token->keyword == RID_DEFAULT)
8674 	{
8675 	  c_parser_consume_token (parser);
8676 	  assoc.type = NULL_TREE;
8677 	}
8678       else
8679 	{
8680 	  struct c_type_name *type_name;
8681 
8682 	  type_name = c_parser_type_name (parser);
8683 	  if (type_name == NULL)
8684 	    {
8685 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8686 	      return error_expr;
8687 	    }
8688 	  assoc.type = groktypename (type_name, NULL, NULL);
8689 	  if (assoc.type == error_mark_node)
8690 	    {
8691 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8692 	      return error_expr;
8693 	    }
8694 
8695 	  if (TREE_CODE (assoc.type) == FUNCTION_TYPE)
8696 	    error_at (assoc.type_location,
8697 		      "%<_Generic%> association has function type");
8698 	  else if (!COMPLETE_TYPE_P (assoc.type))
8699 	    error_at (assoc.type_location,
8700 		      "%<_Generic%> association has incomplete type");
8701 
8702 	  if (variably_modified_type_p (assoc.type, NULL_TREE))
8703 	    error_at (assoc.type_location,
8704 		      "%<_Generic%> association has "
8705 		      "variable length type");
8706 	}
8707 
8708       if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
8709 	{
8710 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8711 	  return error_expr;
8712 	}
8713 
8714       assoc.expression = c_parser_expr_no_commas (parser, NULL);
8715       if (assoc.expression.value == error_mark_node)
8716 	{
8717 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8718 	  return error_expr;
8719 	}
8720 
8721       for (ix = 0; associations.iterate (ix, &iter); ++ix)
8722 	{
8723 	  if (assoc.type == NULL_TREE)
8724 	    {
8725 	      if (iter->type == NULL_TREE)
8726 		{
8727 		  error_at (assoc.type_location,
8728 			    "duplicate %<default%> case in %<_Generic%>");
8729 		  inform (iter->type_location, "original %<default%> is here");
8730 		}
8731 	    }
8732 	  else if (iter->type != NULL_TREE)
8733 	    {
8734 	      if (comptypes (assoc.type, iter->type))
8735 		{
8736 		  error_at (assoc.type_location,
8737 			    "%<_Generic%> specifies two compatible types");
8738 		  inform (iter->type_location, "compatible type is here");
8739 		}
8740 	    }
8741 	}
8742 
8743       if (assoc.type == NULL_TREE)
8744 	{
8745 	  if (match_found < 0)
8746 	    {
8747 	      matched_assoc = assoc;
8748 	      match_found = associations.length ();
8749 	    }
8750 	}
8751       else if (comptypes (assoc.type, selector_type))
8752 	{
8753 	  if (match_found < 0 || matched_assoc.type == NULL_TREE)
8754 	    {
8755 	      matched_assoc = assoc;
8756 	      match_found = associations.length ();
8757 	    }
8758 	  else
8759 	    {
8760 	      error_at (assoc.type_location,
8761 			"%<_Generic%> selector matches multiple associations");
8762 	      inform (matched_assoc.type_location,
8763 		      "other match is here");
8764 	    }
8765 	}
8766 
8767       associations.safe_push (assoc);
8768 
8769       if (c_parser_peek_token (parser)->type != CPP_COMMA)
8770 	break;
8771       c_parser_consume_token (parser);
8772     }
8773 
8774   unsigned int ix;
8775   struct c_generic_association *iter;
8776   FOR_EACH_VEC_ELT (associations, ix, iter)
8777     if (ix != (unsigned) match_found)
8778       mark_exp_read (iter->expression.value);
8779 
8780   if (!parens.require_close (parser))
8781     {
8782       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8783       return error_expr;
8784     }
8785 
8786   if (match_found < 0)
8787     {
8788       error_at (selector_loc, "%<_Generic%> selector of type %qT is not "
8789 		"compatible with any association",
8790 		selector_type);
8791       return error_expr;
8792     }
8793 
8794   return matched_assoc.expression;
8795 }
8796 
8797 /* Check the validity of a function pointer argument *EXPR (argument
8798    position POS) to __builtin_tgmath.  Return the number of function
8799    arguments if possibly valid; return 0 having reported an error if
8800    not valid.  */
8801 
8802 static unsigned int
check_tgmath_function(c_expr * expr,unsigned int pos)8803 check_tgmath_function (c_expr *expr, unsigned int pos)
8804 {
8805   tree type = TREE_TYPE (expr->value);
8806   if (!FUNCTION_POINTER_TYPE_P (type))
8807     {
8808       error_at (expr->get_location (),
8809 		"argument %u of %<__builtin_tgmath%> is not a function pointer",
8810 		pos);
8811       return 0;
8812     }
8813   type = TREE_TYPE (type);
8814   if (!prototype_p (type))
8815     {
8816       error_at (expr->get_location (),
8817 		"argument %u of %<__builtin_tgmath%> is unprototyped", pos);
8818       return 0;
8819     }
8820   if (stdarg_p (type))
8821     {
8822       error_at (expr->get_location (),
8823 		"argument %u of %<__builtin_tgmath%> has variable arguments",
8824 		pos);
8825       return 0;
8826     }
8827   unsigned int nargs = 0;
8828   function_args_iterator iter;
8829   tree t;
8830   FOREACH_FUNCTION_ARGS (type, t, iter)
8831     {
8832       if (t == void_type_node)
8833 	break;
8834       nargs++;
8835     }
8836   if (nargs == 0)
8837     {
8838       error_at (expr->get_location (),
8839 		"argument %u of %<__builtin_tgmath%> has no arguments", pos);
8840       return 0;
8841     }
8842   return nargs;
8843 }
8844 
8845 /* Ways in which a parameter or return value of a type-generic macro
8846    may vary between the different functions the macro may call.  */
8847 enum tgmath_parm_kind
8848   {
8849     tgmath_fixed, tgmath_real, tgmath_complex
8850   };
8851 
8852 /* Helper function for c_parser_postfix_expression.  Parse predefined
8853    identifiers.  */
8854 
8855 static struct c_expr
c_parser_predefined_identifier(c_parser * parser)8856 c_parser_predefined_identifier (c_parser *parser)
8857 {
8858   location_t loc = c_parser_peek_token (parser)->location;
8859   switch (c_parser_peek_token (parser)->keyword)
8860     {
8861     case RID_FUNCTION_NAME:
8862       pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
8863 	       "identifier", "__FUNCTION__");
8864       break;
8865     case RID_PRETTY_FUNCTION_NAME:
8866       pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
8867 	       "identifier", "__PRETTY_FUNCTION__");
8868       break;
8869     case RID_C99_FUNCTION_NAME:
8870       pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not support "
8871 		   "%<__func__%> predefined identifier");
8872       break;
8873     default:
8874       gcc_unreachable ();
8875     }
8876 
8877   struct c_expr expr;
8878   expr.original_code = ERROR_MARK;
8879   expr.original_type = NULL;
8880   expr.value = fname_decl (loc, c_parser_peek_token (parser)->keyword,
8881 			   c_parser_peek_token (parser)->value);
8882   set_c_expr_source_range (&expr, loc, loc);
8883   c_parser_consume_token (parser);
8884   return expr;
8885 }
8886 
8887 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
8888    C11 6.5.1-6.5.2).  Compound literals aren't handled here; callers have to
8889    call c_parser_postfix_expression_after_paren_type on encountering them.
8890 
8891    postfix-expression:
8892      primary-expression
8893      postfix-expression [ expression ]
8894      postfix-expression ( argument-expression-list[opt] )
8895      postfix-expression . identifier
8896      postfix-expression -> identifier
8897      postfix-expression ++
8898      postfix-expression --
8899      ( type-name ) { initializer-list }
8900      ( type-name ) { initializer-list , }
8901 
8902    argument-expression-list:
8903      argument-expression
8904      argument-expression-list , argument-expression
8905 
8906    primary-expression:
8907      identifier
8908      constant
8909      string-literal
8910      ( expression )
8911      generic-selection
8912 
8913    GNU extensions:
8914 
8915    primary-expression:
8916      __func__
8917        (treated as a keyword in GNU C)
8918      __FUNCTION__
8919      __PRETTY_FUNCTION__
8920      ( compound-statement )
8921      __builtin_va_arg ( assignment-expression , type-name )
8922      __builtin_offsetof ( type-name , offsetof-member-designator )
8923      __builtin_choose_expr ( assignment-expression ,
8924 			     assignment-expression ,
8925 			     assignment-expression )
8926      __builtin_types_compatible_p ( type-name , type-name )
8927      __builtin_tgmath ( expr-list )
8928      __builtin_complex ( assignment-expression , assignment-expression )
8929      __builtin_shuffle ( assignment-expression , assignment-expression )
8930      __builtin_shuffle ( assignment-expression ,
8931 			 assignment-expression ,
8932 			 assignment-expression, )
8933      __builtin_convertvector ( assignment-expression , type-name )
8934 
8935    offsetof-member-designator:
8936      identifier
8937      offsetof-member-designator . identifier
8938      offsetof-member-designator [ expression ]
8939 
8940    Objective-C:
8941 
8942    primary-expression:
8943      [ objc-receiver objc-message-args ]
8944      @selector ( objc-selector-arg )
8945      @protocol ( identifier )
8946      @encode ( type-name )
8947      objc-string-literal
8948      Classname . identifier
8949 */
8950 
8951 static struct c_expr
c_parser_postfix_expression(c_parser * parser)8952 c_parser_postfix_expression (c_parser *parser)
8953 {
8954   struct c_expr expr, e1;
8955   struct c_type_name *t1, *t2;
8956   location_t loc = c_parser_peek_token (parser)->location;
8957   source_range tok_range = c_parser_peek_token (parser)->get_range ();
8958   expr.original_code = ERROR_MARK;
8959   expr.original_type = NULL;
8960   switch (c_parser_peek_token (parser)->type)
8961     {
8962     case CPP_NUMBER:
8963       expr.value = c_parser_peek_token (parser)->value;
8964       set_c_expr_source_range (&expr, tok_range);
8965       loc = c_parser_peek_token (parser)->location;
8966       c_parser_consume_token (parser);
8967       if (TREE_CODE (expr.value) == FIXED_CST
8968 	  && !targetm.fixed_point_supported_p ())
8969 	{
8970 	  error_at (loc, "fixed-point types not supported for this target");
8971 	  expr.set_error ();
8972 	}
8973       break;
8974     case CPP_CHAR:
8975     case CPP_CHAR16:
8976     case CPP_CHAR32:
8977     case CPP_UTF8CHAR:
8978     case CPP_WCHAR:
8979       expr.value = c_parser_peek_token (parser)->value;
8980       /* For the purpose of warning when a pointer is compared with
8981 	 a zero character constant.  */
8982       expr.original_type = char_type_node;
8983       set_c_expr_source_range (&expr, tok_range);
8984       c_parser_consume_token (parser);
8985       break;
8986     case CPP_STRING:
8987     case CPP_STRING16:
8988     case CPP_STRING32:
8989     case CPP_WSTRING:
8990     case CPP_UTF8STRING:
8991       expr = c_parser_string_literal (parser, parser->translate_strings_p,
8992 				      true);
8993       break;
8994     case CPP_OBJC_STRING:
8995       gcc_assert (c_dialect_objc ());
8996       expr.value
8997 	= objc_build_string_object (c_parser_peek_token (parser)->value);
8998       set_c_expr_source_range (&expr, tok_range);
8999       c_parser_consume_token (parser);
9000       break;
9001     case CPP_NAME:
9002       switch (c_parser_peek_token (parser)->id_kind)
9003 	{
9004 	case C_ID_ID:
9005 	  {
9006 	    tree id = c_parser_peek_token (parser)->value;
9007 	    c_parser_consume_token (parser);
9008 	    expr.value = build_external_ref (loc, id,
9009 					     (c_parser_peek_token (parser)->type
9010 					      == CPP_OPEN_PAREN),
9011 					     &expr.original_type);
9012 	    set_c_expr_source_range (&expr, tok_range);
9013 	    break;
9014 	  }
9015 	case C_ID_CLASSNAME:
9016 	  {
9017 	    /* Here we parse the Objective-C 2.0 Class.name dot
9018 	       syntax.  */
9019 	    tree class_name = c_parser_peek_token (parser)->value;
9020 	    tree component;
9021 	    c_parser_consume_token (parser);
9022 	    gcc_assert (c_dialect_objc ());
9023 	    if (!c_parser_require (parser, CPP_DOT, "expected %<.%>"))
9024 	      {
9025 		expr.set_error ();
9026 		break;
9027 	      }
9028 	    if (c_parser_next_token_is_not (parser, CPP_NAME))
9029 	      {
9030 		c_parser_error (parser, "expected identifier");
9031 		expr.set_error ();
9032 		break;
9033 	      }
9034 	    c_token *component_tok = c_parser_peek_token (parser);
9035 	    component = component_tok->value;
9036 	    location_t end_loc = component_tok->get_finish ();
9037 	    c_parser_consume_token (parser);
9038 	    expr.value = objc_build_class_component_ref (class_name,
9039 							 component);
9040 	    set_c_expr_source_range (&expr, loc, end_loc);
9041 	    break;
9042 	  }
9043 	default:
9044 	  c_parser_error (parser, "expected expression");
9045 	  expr.set_error ();
9046 	  break;
9047 	}
9048       break;
9049     case CPP_OPEN_PAREN:
9050       /* A parenthesized expression, statement expression or compound
9051 	 literal.  */
9052       if (c_parser_peek_2nd_token (parser)->type == CPP_OPEN_BRACE)
9053 	{
9054 	  /* A statement expression.  */
9055 	  tree stmt;
9056 	  location_t brace_loc;
9057 	  c_parser_consume_token (parser);
9058 	  brace_loc = c_parser_peek_token (parser)->location;
9059 	  c_parser_consume_token (parser);
9060 	  /* If we've not yet started the current function's statement list,
9061 	     or we're in the parameter scope of an old-style function
9062 	     declaration, statement expressions are not allowed.  */
9063 	  if (!building_stmt_list_p () || old_style_parameter_scope ())
9064 	    {
9065 	      error_at (loc, "braced-group within expression allowed "
9066 			"only inside a function");
9067 	      parser->error = true;
9068 	      c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
9069 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9070 	      expr.set_error ();
9071 	      break;
9072 	    }
9073 	  stmt = c_begin_stmt_expr ();
9074 	  c_parser_compound_statement_nostart (parser);
9075 	  location_t close_loc = c_parser_peek_token (parser)->location;
9076 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9077 				     "expected %<)%>");
9078 	  pedwarn (loc, OPT_Wpedantic,
9079 		   "ISO C forbids braced-groups within expressions");
9080 	  expr.value = c_finish_stmt_expr (brace_loc, stmt);
9081 	  set_c_expr_source_range (&expr, loc, close_loc);
9082 	  mark_exp_read (expr.value);
9083 	}
9084       else
9085 	{
9086 	  /* A parenthesized expression.  */
9087 	  location_t loc_open_paren = c_parser_peek_token (parser)->location;
9088 	  c_parser_consume_token (parser);
9089 	  expr = c_parser_expression (parser);
9090 	  if (TREE_CODE (expr.value) == MODIFY_EXPR)
9091 	    TREE_NO_WARNING (expr.value) = 1;
9092 	  if (expr.original_code != C_MAYBE_CONST_EXPR
9093 	      && expr.original_code != SIZEOF_EXPR)
9094 	    expr.original_code = ERROR_MARK;
9095 	  /* Remember that we saw ( ) around the sizeof.  */
9096 	  if (expr.original_code == SIZEOF_EXPR)
9097 	    expr.original_code = PAREN_SIZEOF_EXPR;
9098 	  /* Don't change EXPR.ORIGINAL_TYPE.  */
9099 	  location_t loc_close_paren = c_parser_peek_token (parser)->location;
9100 	  set_c_expr_source_range (&expr, loc_open_paren, loc_close_paren);
9101 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9102 				     "expected %<)%>", loc_open_paren);
9103 	}
9104       break;
9105     case CPP_KEYWORD:
9106       switch (c_parser_peek_token (parser)->keyword)
9107 	{
9108 	case RID_FUNCTION_NAME:
9109 	case RID_PRETTY_FUNCTION_NAME:
9110 	case RID_C99_FUNCTION_NAME:
9111 	  expr = c_parser_predefined_identifier (parser);
9112 	  break;
9113 	case RID_VA_ARG:
9114 	  {
9115 	    location_t start_loc = loc;
9116 	    c_parser_consume_token (parser);
9117 	    matching_parens parens;
9118 	    if (!parens.require_open (parser))
9119 	      {
9120 		expr.set_error ();
9121 		break;
9122 	      }
9123 	    e1 = c_parser_expr_no_commas (parser, NULL);
9124 	    mark_exp_read (e1.value);
9125 	    e1.value = c_fully_fold (e1.value, false, NULL);
9126 	    if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9127 	      {
9128 		c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9129 		expr.set_error ();
9130 		break;
9131 	      }
9132 	    loc = c_parser_peek_token (parser)->location;
9133 	    t1 = c_parser_type_name (parser);
9134 	    location_t end_loc = c_parser_peek_token (parser)->get_finish ();
9135 	    c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9136 				       "expected %<)%>");
9137 	    if (t1 == NULL)
9138 	      {
9139 		expr.set_error ();
9140 	      }
9141 	    else
9142 	      {
9143 		tree type_expr = NULL_TREE;
9144 		expr.value = c_build_va_arg (start_loc, e1.value, loc,
9145 					     groktypename (t1, &type_expr, NULL));
9146 		if (type_expr)
9147 		  {
9148 		    expr.value = build2 (C_MAYBE_CONST_EXPR,
9149 					 TREE_TYPE (expr.value), type_expr,
9150 					 expr.value);
9151 		    C_MAYBE_CONST_EXPR_NON_CONST (expr.value) = true;
9152 		  }
9153 		set_c_expr_source_range (&expr, start_loc, end_loc);
9154 	      }
9155 	  }
9156 	  break;
9157 	case RID_OFFSETOF:
9158 	  {
9159 	    c_parser_consume_token (parser);
9160 	    matching_parens parens;
9161 	    if (!parens.require_open (parser))
9162 	      {
9163 		expr.set_error ();
9164 		break;
9165 	      }
9166 	    t1 = c_parser_type_name (parser);
9167 	    if (t1 == NULL)
9168 	      parser->error = true;
9169 	    if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9170 	      gcc_assert (parser->error);
9171 	    if (parser->error)
9172 	      {
9173 		c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9174 		expr.set_error ();
9175 		break;
9176 	      }
9177 	    tree type = groktypename (t1, NULL, NULL);
9178 	    tree offsetof_ref;
9179 	    if (type == error_mark_node)
9180 	      offsetof_ref = error_mark_node;
9181 	    else
9182 	      {
9183 		offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
9184 		SET_EXPR_LOCATION (offsetof_ref, loc);
9185 	      }
9186 	    /* Parse the second argument to __builtin_offsetof.  We
9187 	       must have one identifier, and beyond that we want to
9188 	       accept sub structure and sub array references.  */
9189 	    if (c_parser_next_token_is (parser, CPP_NAME))
9190 	      {
9191 		c_token *comp_tok = c_parser_peek_token (parser);
9192 		offsetof_ref = build_component_ref
9193 		  (loc, offsetof_ref, comp_tok->value, comp_tok->location);
9194 		c_parser_consume_token (parser);
9195 		while (c_parser_next_token_is (parser, CPP_DOT)
9196 		       || c_parser_next_token_is (parser,
9197 						  CPP_OPEN_SQUARE)
9198 		       || c_parser_next_token_is (parser,
9199 						  CPP_DEREF))
9200 		  {
9201 		    if (c_parser_next_token_is (parser, CPP_DEREF))
9202 		      {
9203 			loc = c_parser_peek_token (parser)->location;
9204 			offsetof_ref = build_array_ref (loc,
9205 							offsetof_ref,
9206 							integer_zero_node);
9207 			goto do_dot;
9208 		      }
9209 		    else if (c_parser_next_token_is (parser, CPP_DOT))
9210 		      {
9211 		      do_dot:
9212 			c_parser_consume_token (parser);
9213 			if (c_parser_next_token_is_not (parser,
9214 							CPP_NAME))
9215 			  {
9216 			    c_parser_error (parser, "expected identifier");
9217 			    break;
9218 			  }
9219 			c_token *comp_tok = c_parser_peek_token (parser);
9220 			offsetof_ref = build_component_ref
9221 			  (loc, offsetof_ref, comp_tok->value,
9222 			   comp_tok->location);
9223 			c_parser_consume_token (parser);
9224 		      }
9225 		    else
9226 		      {
9227 			struct c_expr ce;
9228 			tree idx;
9229 			loc = c_parser_peek_token (parser)->location;
9230 			c_parser_consume_token (parser);
9231 			ce = c_parser_expression (parser);
9232 			ce = convert_lvalue_to_rvalue (loc, ce, false, false);
9233 			idx = ce.value;
9234 			idx = c_fully_fold (idx, false, NULL);
9235 			c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
9236 						   "expected %<]%>");
9237 			offsetof_ref = build_array_ref (loc, offsetof_ref, idx);
9238 		      }
9239 		  }
9240 	      }
9241 	    else
9242 	      c_parser_error (parser, "expected identifier");
9243 	    location_t end_loc = c_parser_peek_token (parser)->get_finish ();
9244 	    c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9245 				       "expected %<)%>");
9246 	    expr.value = fold_offsetof (offsetof_ref);
9247 	    set_c_expr_source_range (&expr, loc, end_loc);
9248 	  }
9249 	  break;
9250 	case RID_CHOOSE_EXPR:
9251 	  {
9252 	    vec<c_expr_t, va_gc> *cexpr_list;
9253 	    c_expr_t *e1_p, *e2_p, *e3_p;
9254 	    tree c;
9255 	    location_t close_paren_loc;
9256 
9257 	    c_parser_consume_token (parser);
9258 	    if (!c_parser_get_builtin_args (parser,
9259 					    "__builtin_choose_expr",
9260 					    &cexpr_list, true,
9261 					    &close_paren_loc))
9262 	      {
9263 		expr.set_error ();
9264 		break;
9265 	      }
9266 
9267 	    if (vec_safe_length (cexpr_list) != 3)
9268 	      {
9269 		error_at (loc, "wrong number of arguments to "
9270 			       "%<__builtin_choose_expr%>");
9271 		expr.set_error ();
9272 		break;
9273 	      }
9274 
9275 	    e1_p = &(*cexpr_list)[0];
9276 	    e2_p = &(*cexpr_list)[1];
9277 	    e3_p = &(*cexpr_list)[2];
9278 
9279 	    c = e1_p->value;
9280 	    mark_exp_read (e2_p->value);
9281 	    mark_exp_read (e3_p->value);
9282 	    if (TREE_CODE (c) != INTEGER_CST
9283 		|| !INTEGRAL_TYPE_P (TREE_TYPE (c)))
9284 	      error_at (loc,
9285 			"first argument to %<__builtin_choose_expr%> not"
9286 			" a constant");
9287 	    constant_expression_warning (c);
9288 	    expr = integer_zerop (c) ? *e3_p : *e2_p;
9289 	    set_c_expr_source_range (&expr, loc, close_paren_loc);
9290 	    break;
9291 	  }
9292 	case RID_TYPES_COMPATIBLE_P:
9293 	  {
9294 	    c_parser_consume_token (parser);
9295 	    matching_parens parens;
9296 	    if (!parens.require_open (parser))
9297 	      {
9298 		expr.set_error ();
9299 		break;
9300 	      }
9301 	    t1 = c_parser_type_name (parser);
9302 	    if (t1 == NULL)
9303 	      {
9304 		expr.set_error ();
9305 		break;
9306 	      }
9307 	    if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9308 	      {
9309 		c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9310 		expr.set_error ();
9311 		break;
9312 	      }
9313 	    t2 = c_parser_type_name (parser);
9314 	    if (t2 == NULL)
9315 	      {
9316 		expr.set_error ();
9317 		break;
9318 	      }
9319 	    location_t close_paren_loc = c_parser_peek_token (parser)->location;
9320 	    parens.skip_until_found_close (parser);
9321 	    tree e1, e2;
9322 	    e1 = groktypename (t1, NULL, NULL);
9323 	    e2 = groktypename (t2, NULL, NULL);
9324 	    if (e1 == error_mark_node || e2 == error_mark_node)
9325 	      {
9326 		expr.set_error ();
9327 		break;
9328 	      }
9329 
9330 	    e1 = TYPE_MAIN_VARIANT (e1);
9331 	    e2 = TYPE_MAIN_VARIANT (e2);
9332 
9333 	    expr.value
9334 	      = comptypes (e1, e2) ? integer_one_node : integer_zero_node;
9335 	    set_c_expr_source_range (&expr, loc, close_paren_loc);
9336 	  }
9337 	  break;
9338 	case RID_BUILTIN_TGMATH:
9339 	  {
9340 	    vec<c_expr_t, va_gc> *cexpr_list;
9341 	    location_t close_paren_loc;
9342 
9343 	    c_parser_consume_token (parser);
9344 	    if (!c_parser_get_builtin_args (parser,
9345 					    "__builtin_tgmath",
9346 					    &cexpr_list, false,
9347 					    &close_paren_loc))
9348 	      {
9349 		expr.set_error ();
9350 		break;
9351 	      }
9352 
9353 	    if (vec_safe_length (cexpr_list) < 3)
9354 	      {
9355 		error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9356 		expr.set_error ();
9357 		break;
9358 	      }
9359 
9360 	    unsigned int i;
9361 	    c_expr_t *p;
9362 	    FOR_EACH_VEC_ELT (*cexpr_list, i, p)
9363 	      *p = convert_lvalue_to_rvalue (loc, *p, true, true);
9364 	    unsigned int nargs = check_tgmath_function (&(*cexpr_list)[0], 1);
9365 	    if (nargs == 0)
9366 	      {
9367 		expr.set_error ();
9368 		break;
9369 	      }
9370 	    if (vec_safe_length (cexpr_list) < nargs)
9371 	      {
9372 		error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9373 		expr.set_error ();
9374 		break;
9375 	      }
9376 	    unsigned int num_functions = vec_safe_length (cexpr_list) - nargs;
9377 	    if (num_functions < 2)
9378 	      {
9379 		error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9380 		expr.set_error ();
9381 		break;
9382 	      }
9383 
9384 	    /* The first NUM_FUNCTIONS expressions are the function
9385 	       pointers.  The remaining NARGS expressions are the
9386 	       arguments that are to be passed to one of those
9387 	       functions, chosen following <tgmath.h> rules.  */
9388 	    for (unsigned int j = 1; j < num_functions; j++)
9389 	      {
9390 		unsigned int this_nargs
9391 		  = check_tgmath_function (&(*cexpr_list)[j], j + 1);
9392 		if (this_nargs == 0)
9393 		  {
9394 		    expr.set_error ();
9395 		    goto out;
9396 		  }
9397 		if (this_nargs != nargs)
9398 		  {
9399 		    error_at ((*cexpr_list)[j].get_location (),
9400 			      "argument %u of %<__builtin_tgmath%> has "
9401 			      "wrong number of arguments", j + 1);
9402 		    expr.set_error ();
9403 		    goto out;
9404 		  }
9405 	      }
9406 
9407 	    /* The functions all have the same number of arguments.
9408 	       Determine whether arguments and return types vary in
9409 	       ways permitted for <tgmath.h> functions.  */
9410 	    /* The first entry in each of these vectors is for the
9411 	       return type, subsequent entries for parameter
9412 	       types.  */
9413 	    auto_vec<enum tgmath_parm_kind> parm_kind (nargs + 1);
9414 	    auto_vec<tree> parm_first (nargs + 1);
9415 	    auto_vec<bool> parm_complex (nargs + 1);
9416 	    auto_vec<bool> parm_varies (nargs + 1);
9417 	    tree first_type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[0].value));
9418 	    tree first_ret = TYPE_MAIN_VARIANT (TREE_TYPE (first_type));
9419 	    parm_first.quick_push (first_ret);
9420 	    parm_complex.quick_push (TREE_CODE (first_ret) == COMPLEX_TYPE);
9421 	    parm_varies.quick_push (false);
9422 	    function_args_iterator iter;
9423 	    tree t;
9424 	    unsigned int argpos;
9425 	    FOREACH_FUNCTION_ARGS (first_type, t, iter)
9426 	      {
9427 		if (t == void_type_node)
9428 		  break;
9429 		parm_first.quick_push (TYPE_MAIN_VARIANT (t));
9430 		parm_complex.quick_push (TREE_CODE (t) == COMPLEX_TYPE);
9431 		parm_varies.quick_push (false);
9432 	      }
9433 	    for (unsigned int j = 1; j < num_functions; j++)
9434 	      {
9435 		tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9436 		tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
9437 		if (ret != parm_first[0])
9438 		  {
9439 		    parm_varies[0] = true;
9440 		    if (!SCALAR_FLOAT_TYPE_P (parm_first[0])
9441 			&& !COMPLEX_FLOAT_TYPE_P (parm_first[0]))
9442 		      {
9443 			error_at ((*cexpr_list)[0].get_location (),
9444 				  "invalid type-generic return type for "
9445 				  "argument %u of %<__builtin_tgmath%>",
9446 				  1);
9447 			expr.set_error ();
9448 			goto out;
9449 		      }
9450 		    if (!SCALAR_FLOAT_TYPE_P (ret)
9451 			&& !COMPLEX_FLOAT_TYPE_P (ret))
9452 		      {
9453 			error_at ((*cexpr_list)[j].get_location (),
9454 				  "invalid type-generic return type for "
9455 				  "argument %u of %<__builtin_tgmath%>",
9456 				  j + 1);
9457 			expr.set_error ();
9458 			goto out;
9459 		      }
9460 		  }
9461 		if (TREE_CODE (ret) == COMPLEX_TYPE)
9462 		  parm_complex[0] = true;
9463 		argpos = 1;
9464 		FOREACH_FUNCTION_ARGS (type, t, iter)
9465 		  {
9466 		    if (t == void_type_node)
9467 		      break;
9468 		    t = TYPE_MAIN_VARIANT (t);
9469 		    if (t != parm_first[argpos])
9470 		      {
9471 			parm_varies[argpos] = true;
9472 			if (!SCALAR_FLOAT_TYPE_P (parm_first[argpos])
9473 			    && !COMPLEX_FLOAT_TYPE_P (parm_first[argpos]))
9474 			  {
9475 			    error_at ((*cexpr_list)[0].get_location (),
9476 				      "invalid type-generic type for "
9477 				      "argument %u of argument %u of "
9478 				      "%<__builtin_tgmath%>", argpos, 1);
9479 			    expr.set_error ();
9480 			    goto out;
9481 			  }
9482 			if (!SCALAR_FLOAT_TYPE_P (t)
9483 			    && !COMPLEX_FLOAT_TYPE_P (t))
9484 			  {
9485 			    error_at ((*cexpr_list)[j].get_location (),
9486 				      "invalid type-generic type for "
9487 				      "argument %u of argument %u of "
9488 				      "%<__builtin_tgmath%>", argpos, j + 1);
9489 			    expr.set_error ();
9490 			    goto out;
9491 			  }
9492 		      }
9493 		    if (TREE_CODE (t) == COMPLEX_TYPE)
9494 		      parm_complex[argpos] = true;
9495 		    argpos++;
9496 		  }
9497 	      }
9498 	    enum tgmath_parm_kind max_variation = tgmath_fixed;
9499 	    for (unsigned int j = 0; j <= nargs; j++)
9500 	      {
9501 		enum tgmath_parm_kind this_kind;
9502 		if (parm_varies[j])
9503 		  {
9504 		    if (parm_complex[j])
9505 		      max_variation = this_kind = tgmath_complex;
9506 		    else
9507 		      {
9508 			this_kind = tgmath_real;
9509 			if (max_variation != tgmath_complex)
9510 			  max_variation = tgmath_real;
9511 		      }
9512 		  }
9513 		else
9514 		  this_kind = tgmath_fixed;
9515 		parm_kind.quick_push (this_kind);
9516 	      }
9517 	    if (max_variation == tgmath_fixed)
9518 	      {
9519 		error_at (loc, "function arguments of %<__builtin_tgmath%> "
9520 			  "all have the same type");
9521 		expr.set_error ();
9522 		break;
9523 	      }
9524 
9525 	    /* Identify a parameter (not the return type) that varies,
9526 	       including with complex types if any variation includes
9527 	       complex types; there must be at least one such
9528 	       parameter.  */
9529 	    unsigned int tgarg = 0;
9530 	    for (unsigned int j = 1; j <= nargs; j++)
9531 	      if (parm_kind[j] == max_variation)
9532 		{
9533 		  tgarg = j;
9534 		  break;
9535 		}
9536 	    if (tgarg == 0)
9537 	      {
9538 		error_at (loc, "function arguments of %<__builtin_tgmath%> "
9539 			  "lack type-generic parameter");
9540 		expr.set_error ();
9541 		break;
9542 	      }
9543 
9544 	    /* Determine the type of the relevant parameter for each
9545 	       function.  */
9546 	    auto_vec<tree> tg_type (num_functions);
9547 	    for (unsigned int j = 0; j < num_functions; j++)
9548 	      {
9549 		tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9550 		argpos = 1;
9551 		FOREACH_FUNCTION_ARGS (type, t, iter)
9552 		  {
9553 		    if (argpos == tgarg)
9554 		      {
9555 			tg_type.quick_push (TYPE_MAIN_VARIANT (t));
9556 			break;
9557 		      }
9558 		    argpos++;
9559 		  }
9560 	      }
9561 
9562 	    /* Verify that the corresponding types are different for
9563 	       all the listed functions.  Also determine whether all
9564 	       the types are complex, whether all the types are
9565 	       standard or binary, and whether all the types are
9566 	       decimal.  */
9567 	    bool all_complex = true;
9568 	    bool all_binary = true;
9569 	    bool all_decimal = true;
9570 	    hash_set<tree> tg_types;
9571 	    FOR_EACH_VEC_ELT (tg_type, i, t)
9572 	      {
9573 		if (TREE_CODE (t) == COMPLEX_TYPE)
9574 		  all_decimal = false;
9575 		else
9576 		  {
9577 		    all_complex = false;
9578 		    if (DECIMAL_FLOAT_TYPE_P (t))
9579 		      all_binary = false;
9580 		    else
9581 		      all_decimal = false;
9582 		  }
9583 		if (tg_types.add (t))
9584 		  {
9585 		    error_at ((*cexpr_list)[i].get_location (),
9586 			      "duplicate type-generic parameter type for "
9587 			      "function argument %u of %<__builtin_tgmath%>",
9588 			      i + 1);
9589 		    expr.set_error ();
9590 		    goto out;
9591 		  }
9592 	      }
9593 
9594 	    /* Verify that other parameters and the return type whose
9595 	       types vary have their types varying in the correct
9596 	       way.  */
9597 	    for (unsigned int j = 0; j < num_functions; j++)
9598 	      {
9599 		tree exp_type = tg_type[j];
9600 		tree exp_real_type = exp_type;
9601 		if (TREE_CODE (exp_type) == COMPLEX_TYPE)
9602 		  exp_real_type = TREE_TYPE (exp_type);
9603 		tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9604 		tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
9605 		if ((parm_kind[0] == tgmath_complex && ret != exp_type)
9606 		    || (parm_kind[0] == tgmath_real && ret != exp_real_type))
9607 		  {
9608 		    error_at ((*cexpr_list)[j].get_location (),
9609 			      "bad return type for function argument %u "
9610 			      "of %<__builtin_tgmath%>", j + 1);
9611 		    expr.set_error ();
9612 		    goto out;
9613 		  }
9614 		argpos = 1;
9615 		FOREACH_FUNCTION_ARGS (type, t, iter)
9616 		  {
9617 		    if (t == void_type_node)
9618 		      break;
9619 		    t = TYPE_MAIN_VARIANT (t);
9620 		    if ((parm_kind[argpos] == tgmath_complex
9621 			 && t != exp_type)
9622 			|| (parm_kind[argpos] == tgmath_real
9623 			    && t != exp_real_type))
9624 		      {
9625 			error_at ((*cexpr_list)[j].get_location (),
9626 				  "bad type for argument %u of "
9627 				  "function argument %u of "
9628 				  "%<__builtin_tgmath%>", argpos, j + 1);
9629 			expr.set_error ();
9630 			goto out;
9631 		      }
9632 		    argpos++;
9633 		  }
9634 	      }
9635 
9636 	    /* The functions listed are a valid set of functions for a
9637 	       <tgmath.h> macro to select between.  Identify the
9638 	       matching function, if any.  First, the argument types
9639 	       must be combined following <tgmath.h> rules.  Integer
9640 	       types are treated as _Decimal64 if any type-generic
9641 	       argument is decimal, or if the only alternatives for
9642 	       type-generic arguments are of decimal types, and are
9643 	       otherwise treated as double (or _Complex double for
9644 	       complex integer types, or _Float64 or _Complex _Float64
9645 	       if all the return types are the same _FloatN or
9646 	       _FloatNx type).  After that adjustment, types are
9647 	       combined following the usual arithmetic conversions.
9648 	       If the function only accepts complex arguments, a
9649 	       complex type is produced.  */
9650 	    bool arg_complex = all_complex;
9651 	    bool arg_binary = all_binary;
9652 	    bool arg_int_decimal = all_decimal;
9653 	    for (unsigned int j = 1; j <= nargs; j++)
9654 	      {
9655 		if (parm_kind[j] == tgmath_fixed)
9656 		  continue;
9657 		c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
9658 		tree type = TREE_TYPE (ce->value);
9659 		if (!INTEGRAL_TYPE_P (type)
9660 		    && !SCALAR_FLOAT_TYPE_P (type)
9661 		    && TREE_CODE (type) != COMPLEX_TYPE)
9662 		  {
9663 		    error_at (ce->get_location (),
9664 			      "invalid type of argument %u of type-generic "
9665 			      "function", j);
9666 		    expr.set_error ();
9667 		    goto out;
9668 		  }
9669 		if (DECIMAL_FLOAT_TYPE_P (type))
9670 		  {
9671 		    arg_int_decimal = true;
9672 		    if (all_complex)
9673 		      {
9674 			error_at (ce->get_location (),
9675 				  "decimal floating-point argument %u to "
9676 				  "complex-only type-generic function", j);
9677 			expr.set_error ();
9678 			goto out;
9679 		      }
9680 		    else if (all_binary)
9681 		      {
9682 			error_at (ce->get_location (),
9683 				  "decimal floating-point argument %u to "
9684 				  "binary-only type-generic function", j);
9685 			expr.set_error ();
9686 			goto out;
9687 		      }
9688 		    else if (arg_complex)
9689 		      {
9690 			error_at (ce->get_location (),
9691 				  "both complex and decimal floating-point "
9692 				  "arguments to type-generic function");
9693 			expr.set_error ();
9694 			goto out;
9695 		      }
9696 		    else if (arg_binary)
9697 		      {
9698 			error_at (ce->get_location (),
9699 				  "both binary and decimal floating-point "
9700 				  "arguments to type-generic function");
9701 			expr.set_error ();
9702 			goto out;
9703 		      }
9704 		  }
9705 		else if (TREE_CODE (type) == COMPLEX_TYPE)
9706 		  {
9707 		    arg_complex = true;
9708 		    if (COMPLEX_FLOAT_TYPE_P (type))
9709 		      arg_binary = true;
9710 		    if (all_decimal)
9711 		      {
9712 			error_at (ce->get_location (),
9713 				  "complex argument %u to "
9714 				  "decimal-only type-generic function", j);
9715 			expr.set_error ();
9716 			goto out;
9717 		      }
9718 		    else if (arg_int_decimal)
9719 		      {
9720 			error_at (ce->get_location (),
9721 				  "both complex and decimal floating-point "
9722 				  "arguments to type-generic function");
9723 			expr.set_error ();
9724 			goto out;
9725 		      }
9726 		  }
9727 		else if (SCALAR_FLOAT_TYPE_P (type))
9728 		  {
9729 		    arg_binary = true;
9730 		    if (all_decimal)
9731 		      {
9732 			error_at (ce->get_location (),
9733 				  "binary argument %u to "
9734 				  "decimal-only type-generic function", j);
9735 			expr.set_error ();
9736 			goto out;
9737 		      }
9738 		    else if (arg_int_decimal)
9739 		      {
9740 			error_at (ce->get_location (),
9741 				  "both binary and decimal floating-point "
9742 				  "arguments to type-generic function");
9743 			expr.set_error ();
9744 			goto out;
9745 		      }
9746 		  }
9747 	      }
9748 	    /* For a macro rounding its result to a narrower type, map
9749 	       integer types to _Float64 not double if the return type
9750 	       is a _FloatN or _FloatNx type.  */
9751 	    bool arg_int_float64 = false;
9752 	    if (parm_kind[0] == tgmath_fixed
9753 		&& SCALAR_FLOAT_TYPE_P (parm_first[0])
9754 		&& float64_type_node != NULL_TREE)
9755 	      for (unsigned int j = 0; j < NUM_FLOATN_NX_TYPES; j++)
9756 		if (parm_first[0] == FLOATN_TYPE_NODE (j))
9757 		  {
9758 		    arg_int_float64 = true;
9759 		    break;
9760 		  }
9761 	    tree arg_real = NULL_TREE;
9762 	    for (unsigned int j = 1; j <= nargs; j++)
9763 	      {
9764 		if (parm_kind[j] == tgmath_fixed)
9765 		  continue;
9766 		c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
9767 		tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ce->value));
9768 		if (TREE_CODE (type) == COMPLEX_TYPE)
9769 		  type = TREE_TYPE (type);
9770 		if (INTEGRAL_TYPE_P (type))
9771 		  type = (arg_int_decimal
9772 			  ? dfloat64_type_node
9773 			  : arg_int_float64
9774 			  ? float64_type_node
9775 			  : double_type_node);
9776 		if (arg_real == NULL_TREE)
9777 		  arg_real = type;
9778 		else
9779 		  arg_real = common_type (arg_real, type);
9780 		if (arg_real == error_mark_node)
9781 		  {
9782 		    expr.set_error ();
9783 		    goto out;
9784 		  }
9785 	      }
9786 	    tree arg_type = (arg_complex
9787 			     ? build_complex_type (arg_real)
9788 			     : arg_real);
9789 
9790 	    /* Look for a function to call with type-generic parameter
9791 	       type ARG_TYPE.  */
9792 	    c_expr_t *fn = NULL;
9793 	    for (unsigned int j = 0; j < num_functions; j++)
9794 	      {
9795 		if (tg_type[j] == arg_type)
9796 		  {
9797 		    fn = &(*cexpr_list)[j];
9798 		    break;
9799 		  }
9800 	      }
9801 	    if (fn == NULL
9802 		&& parm_kind[0] == tgmath_fixed
9803 		&& SCALAR_FLOAT_TYPE_P (parm_first[0]))
9804 	      {
9805 		/* Presume this is a macro that rounds its result to a
9806 		   narrower type, and look for the first function with
9807 		   at least the range and precision of the argument
9808 		   type.  */
9809 		for (unsigned int j = 0; j < num_functions; j++)
9810 		  {
9811 		    if (arg_complex
9812 			!= (TREE_CODE (tg_type[j]) == COMPLEX_TYPE))
9813 		      continue;
9814 		    tree real_tg_type = (arg_complex
9815 					 ? TREE_TYPE (tg_type[j])
9816 					 : tg_type[j]);
9817 		    if (DECIMAL_FLOAT_TYPE_P (arg_real)
9818 			!= DECIMAL_FLOAT_TYPE_P (real_tg_type))
9819 		      continue;
9820 		    scalar_float_mode arg_mode
9821 		      = SCALAR_FLOAT_TYPE_MODE (arg_real);
9822 		    scalar_float_mode tg_mode
9823 		      = SCALAR_FLOAT_TYPE_MODE (real_tg_type);
9824 		    const real_format *arg_fmt = REAL_MODE_FORMAT (arg_mode);
9825 		    const real_format *tg_fmt = REAL_MODE_FORMAT (tg_mode);
9826 		    if (arg_fmt->b == tg_fmt->b
9827 			&& arg_fmt->p <= tg_fmt->p
9828 			&& arg_fmt->emax <= tg_fmt->emax
9829 			&& (arg_fmt->emin - arg_fmt->p
9830 			    >= tg_fmt->emin - tg_fmt->p))
9831 		      {
9832 			fn = &(*cexpr_list)[j];
9833 			break;
9834 		      }
9835 		  }
9836 	      }
9837 	    if (fn == NULL)
9838 	      {
9839 		error_at (loc, "no matching function for type-generic call");
9840 		expr.set_error ();
9841 		break;
9842 	      }
9843 
9844 	    /* Construct a call to FN.  */
9845 	    vec<tree, va_gc> *args;
9846 	    vec_alloc (args, nargs);
9847 	    vec<tree, va_gc> *origtypes;
9848 	    vec_alloc (origtypes, nargs);
9849 	    auto_vec<location_t> arg_loc (nargs);
9850 	    for (unsigned int j = 0; j < nargs; j++)
9851 	      {
9852 		c_expr_t *ce = &(*cexpr_list)[num_functions + j];
9853 		args->quick_push (ce->value);
9854 		arg_loc.quick_push (ce->get_location ());
9855 		origtypes->quick_push (ce->original_type);
9856 	      }
9857 	    expr.value = c_build_function_call_vec (loc, arg_loc, fn->value,
9858 						    args, origtypes);
9859 	    set_c_expr_source_range (&expr, loc, close_paren_loc);
9860 	    break;
9861 	  }
9862 	case RID_BUILTIN_CALL_WITH_STATIC_CHAIN:
9863 	  {
9864 	    vec<c_expr_t, va_gc> *cexpr_list;
9865 	    c_expr_t *e2_p;
9866 	    tree chain_value;
9867 	    location_t close_paren_loc;
9868 
9869 	    c_parser_consume_token (parser);
9870 	    if (!c_parser_get_builtin_args (parser,
9871 					    "__builtin_call_with_static_chain",
9872 					    &cexpr_list, false,
9873 					    &close_paren_loc))
9874 	      {
9875 		expr.set_error ();
9876 		break;
9877 	      }
9878 	    if (vec_safe_length (cexpr_list) != 2)
9879 	      {
9880 		error_at (loc, "wrong number of arguments to "
9881 			       "%<__builtin_call_with_static_chain%>");
9882 		expr.set_error ();
9883 		break;
9884 	      }
9885 
9886 	    expr = (*cexpr_list)[0];
9887 	    e2_p = &(*cexpr_list)[1];
9888 	    *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
9889 	    chain_value = e2_p->value;
9890 	    mark_exp_read (chain_value);
9891 
9892 	    if (TREE_CODE (expr.value) != CALL_EXPR)
9893 	      error_at (loc, "first argument to "
9894 			"%<__builtin_call_with_static_chain%> "
9895 			"must be a call expression");
9896 	    else if (TREE_CODE (TREE_TYPE (chain_value)) != POINTER_TYPE)
9897 	      error_at (loc, "second argument to "
9898 			"%<__builtin_call_with_static_chain%> "
9899 			"must be a pointer type");
9900 	    else
9901 	      CALL_EXPR_STATIC_CHAIN (expr.value) = chain_value;
9902 	    set_c_expr_source_range (&expr, loc, close_paren_loc);
9903 	    break;
9904 	  }
9905 	case RID_BUILTIN_COMPLEX:
9906 	  {
9907 	    vec<c_expr_t, va_gc> *cexpr_list;
9908 	    c_expr_t *e1_p, *e2_p;
9909 	    location_t close_paren_loc;
9910 
9911 	    c_parser_consume_token (parser);
9912 	    if (!c_parser_get_builtin_args (parser,
9913 					    "__builtin_complex",
9914 					    &cexpr_list, false,
9915 					    &close_paren_loc))
9916 	      {
9917 		expr.set_error ();
9918 		break;
9919 	      }
9920 
9921 	    if (vec_safe_length (cexpr_list) != 2)
9922 	      {
9923 		error_at (loc, "wrong number of arguments to "
9924 			       "%<__builtin_complex%>");
9925 		expr.set_error ();
9926 		break;
9927 	      }
9928 
9929 	    e1_p = &(*cexpr_list)[0];
9930 	    e2_p = &(*cexpr_list)[1];
9931 
9932 	    *e1_p = convert_lvalue_to_rvalue (loc, *e1_p, true, true);
9933 	    if (TREE_CODE (e1_p->value) == EXCESS_PRECISION_EXPR)
9934 	      e1_p->value = convert (TREE_TYPE (e1_p->value),
9935 				     TREE_OPERAND (e1_p->value, 0));
9936 	    *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
9937 	    if (TREE_CODE (e2_p->value) == EXCESS_PRECISION_EXPR)
9938 	      e2_p->value = convert (TREE_TYPE (e2_p->value),
9939 				     TREE_OPERAND (e2_p->value, 0));
9940 	    if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
9941 		|| DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
9942 		|| !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p->value))
9943 		|| DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p->value)))
9944 	      {
9945 		error_at (loc, "%<__builtin_complex%> operand "
9946 			  "not of real binary floating-point type");
9947 		expr.set_error ();
9948 		break;
9949 	      }
9950 	    if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p->value))
9951 		!= TYPE_MAIN_VARIANT (TREE_TYPE (e2_p->value)))
9952 	      {
9953 		error_at (loc,
9954 			  "%<__builtin_complex%> operands of different types");
9955 		expr.set_error ();
9956 		break;
9957 	      }
9958 	    pedwarn_c90 (loc, OPT_Wpedantic,
9959 			 "ISO C90 does not support complex types");
9960 	    expr.value = build2_loc (loc, COMPLEX_EXPR,
9961 				     build_complex_type
9962 				     (TYPE_MAIN_VARIANT
9963 				      (TREE_TYPE (e1_p->value))),
9964 				     e1_p->value, e2_p->value);
9965 	    set_c_expr_source_range (&expr, loc, close_paren_loc);
9966 	    break;
9967 	  }
9968 	case RID_BUILTIN_SHUFFLE:
9969 	  {
9970 	    vec<c_expr_t, va_gc> *cexpr_list;
9971 	    unsigned int i;
9972 	    c_expr_t *p;
9973 	    location_t close_paren_loc;
9974 
9975 	    c_parser_consume_token (parser);
9976 	    if (!c_parser_get_builtin_args (parser,
9977 					    "__builtin_shuffle",
9978 					    &cexpr_list, false,
9979 					    &close_paren_loc))
9980 	      {
9981 		expr.set_error ();
9982 		break;
9983 	      }
9984 
9985 	    FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
9986 	      *p = convert_lvalue_to_rvalue (loc, *p, true, true);
9987 
9988 	    if (vec_safe_length (cexpr_list) == 2)
9989 	      expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
9990 						  NULL_TREE,
9991 						  (*cexpr_list)[1].value);
9992 
9993 	    else if (vec_safe_length (cexpr_list) == 3)
9994 	      expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
9995 						  (*cexpr_list)[1].value,
9996 						  (*cexpr_list)[2].value);
9997 	    else
9998 	      {
9999 		error_at (loc, "wrong number of arguments to "
10000 			       "%<__builtin_shuffle%>");
10001 		expr.set_error ();
10002 	      }
10003 	    set_c_expr_source_range (&expr, loc, close_paren_loc);
10004 	    break;
10005 	  }
10006 	case RID_BUILTIN_CONVERTVECTOR:
10007 	  {
10008 	    location_t start_loc = loc;
10009 	    c_parser_consume_token (parser);
10010 	    matching_parens parens;
10011 	    if (!parens.require_open (parser))
10012 	      {
10013 		expr.set_error ();
10014 		break;
10015 	      }
10016 	    e1 = c_parser_expr_no_commas (parser, NULL);
10017 	    mark_exp_read (e1.value);
10018 	    if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10019 	      {
10020 		c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10021 		expr.set_error ();
10022 		break;
10023 	      }
10024 	    loc = c_parser_peek_token (parser)->location;
10025 	    t1 = c_parser_type_name (parser);
10026 	    location_t end_loc = c_parser_peek_token (parser)->get_finish ();
10027 	    c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10028 				       "expected %<)%>");
10029 	    if (t1 == NULL)
10030 	      expr.set_error ();
10031 	    else
10032 	      {
10033 		tree type_expr = NULL_TREE;
10034 		expr.value = c_build_vec_convert (start_loc, e1.value, loc,
10035 						  groktypename (t1, &type_expr,
10036 								NULL));
10037 		set_c_expr_source_range (&expr, start_loc, end_loc);
10038 	      }
10039 	  }
10040 	  break;
10041 	case RID_AT_SELECTOR:
10042 	  {
10043 	    gcc_assert (c_dialect_objc ());
10044 	    c_parser_consume_token (parser);
10045 	    matching_parens parens;
10046 	    if (!parens.require_open (parser))
10047 	      {
10048 		expr.set_error ();
10049 		break;
10050 	      }
10051 	    tree sel = c_parser_objc_selector_arg (parser);
10052 	    location_t close_loc = c_parser_peek_token (parser)->location;
10053 	    parens.skip_until_found_close (parser);
10054 	    expr.value = objc_build_selector_expr (loc, sel);
10055 	    set_c_expr_source_range (&expr, loc, close_loc);
10056 	  }
10057 	  break;
10058 	case RID_AT_PROTOCOL:
10059 	  {
10060 	    gcc_assert (c_dialect_objc ());
10061 	    c_parser_consume_token (parser);
10062 	    matching_parens parens;
10063 	    if (!parens.require_open (parser))
10064 	      {
10065 		expr.set_error ();
10066 		break;
10067 	      }
10068 	    if (c_parser_next_token_is_not (parser, CPP_NAME))
10069 	      {
10070 		c_parser_error (parser, "expected identifier");
10071 		c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10072 		expr.set_error ();
10073 		break;
10074 	      }
10075 	    tree id = c_parser_peek_token (parser)->value;
10076 	    c_parser_consume_token (parser);
10077 	    location_t close_loc = c_parser_peek_token (parser)->location;
10078 	    parens.skip_until_found_close (parser);
10079 	    expr.value = objc_build_protocol_expr (id);
10080 	    set_c_expr_source_range (&expr, loc, close_loc);
10081 	  }
10082 	  break;
10083 	case RID_AT_ENCODE:
10084 	  {
10085 	    /* Extension to support C-structures in the archiver.  */
10086 	    gcc_assert (c_dialect_objc ());
10087 	    c_parser_consume_token (parser);
10088 	    matching_parens parens;
10089 	    if (!parens.require_open (parser))
10090 	      {
10091 		expr.set_error ();
10092 		break;
10093 	      }
10094 	    t1 = c_parser_type_name (parser);
10095 	    if (t1 == NULL)
10096 	      {
10097 		expr.set_error ();
10098 		c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10099 		break;
10100 	      }
10101 	    location_t close_loc = c_parser_peek_token (parser)->location;
10102 	    parens.skip_until_found_close (parser);
10103 	    tree type = groktypename (t1, NULL, NULL);
10104 	    expr.value = objc_build_encode_expr (type);
10105 	    set_c_expr_source_range (&expr, loc, close_loc);
10106 	  }
10107 	  break;
10108 	case RID_GENERIC:
10109 	  expr = c_parser_generic_selection (parser);
10110 	  break;
10111 	default:
10112 	  c_parser_error (parser, "expected expression");
10113 	  expr.set_error ();
10114 	  break;
10115 	}
10116       break;
10117     case CPP_OPEN_SQUARE:
10118       if (c_dialect_objc ())
10119 	{
10120 	  tree receiver, args;
10121 	  c_parser_consume_token (parser);
10122 	  receiver = c_parser_objc_receiver (parser);
10123 	  args = c_parser_objc_message_args (parser);
10124 	  location_t close_loc = c_parser_peek_token (parser)->location;
10125 	  c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10126 				     "expected %<]%>");
10127 	  expr.value = objc_build_message_expr (receiver, args);
10128 	  set_c_expr_source_range (&expr, loc, close_loc);
10129 	  break;
10130 	}
10131       /* Else fall through to report error.  */
10132       /* FALLTHRU */
10133     default:
10134       c_parser_error (parser, "expected expression");
10135       expr.set_error ();
10136       break;
10137     }
10138  out:
10139   return c_parser_postfix_expression_after_primary
10140     (parser, EXPR_LOC_OR_LOC (expr.value, loc), expr);
10141 }
10142 
10143 /* Parse a postfix expression after a parenthesized type name: the
10144    brace-enclosed initializer of a compound literal, possibly followed
10145    by some postfix operators.  This is separate because it is not
10146    possible to tell until after the type name whether a cast
10147    expression has a cast or a compound literal, or whether the operand
10148    of sizeof is a parenthesized type name or starts with a compound
10149    literal.  TYPE_LOC is the location where TYPE_NAME starts--the
10150    location of the first token after the parentheses around the type
10151    name.  */
10152 
10153 static struct c_expr
c_parser_postfix_expression_after_paren_type(c_parser * parser,struct c_type_name * type_name,location_t type_loc)10154 c_parser_postfix_expression_after_paren_type (c_parser *parser,
10155 					      struct c_type_name *type_name,
10156 					      location_t type_loc)
10157 {
10158   tree type;
10159   struct c_expr init;
10160   bool non_const;
10161   struct c_expr expr;
10162   location_t start_loc;
10163   tree type_expr = NULL_TREE;
10164   bool type_expr_const = true;
10165   check_compound_literal_type (type_loc, type_name);
10166   rich_location richloc (line_table, type_loc);
10167   start_init (NULL_TREE, NULL, 0, &richloc);
10168   type = groktypename (type_name, &type_expr, &type_expr_const);
10169   start_loc = c_parser_peek_token (parser)->location;
10170   if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type))
10171     {
10172       error_at (type_loc, "compound literal has variable size");
10173       type = error_mark_node;
10174     }
10175   init = c_parser_braced_init (parser, type, false, NULL);
10176   finish_init ();
10177   maybe_warn_string_init (type_loc, type, init);
10178 
10179   if (type != error_mark_node
10180       && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type))
10181       && current_function_decl)
10182     {
10183       error ("compound literal qualified by address-space qualifier");
10184       type = error_mark_node;
10185     }
10186 
10187   pedwarn_c90 (start_loc, OPT_Wpedantic, "ISO C90 forbids compound literals");
10188   non_const = ((init.value && TREE_CODE (init.value) == CONSTRUCTOR)
10189 	       ? CONSTRUCTOR_NON_CONST (init.value)
10190 	       : init.original_code == C_MAYBE_CONST_EXPR);
10191   non_const |= !type_expr_const;
10192   unsigned int alignas_align = 0;
10193   if (type != error_mark_node
10194       && type_name->specs->align_log != -1)
10195     {
10196       alignas_align = 1U << type_name->specs->align_log;
10197       if (alignas_align < min_align_of_type (type))
10198 	{
10199 	  error_at (type_name->specs->locations[cdw_alignas],
10200 		    "%<_Alignas%> specifiers cannot reduce "
10201 		    "alignment of compound literal");
10202 	  alignas_align = 0;
10203 	}
10204     }
10205   expr.value = build_compound_literal (start_loc, type, init.value, non_const,
10206 				       alignas_align);
10207   set_c_expr_source_range (&expr, init.src_range);
10208   expr.original_code = ERROR_MARK;
10209   expr.original_type = NULL;
10210   if (type != error_mark_node
10211       && expr.value != error_mark_node
10212       && type_expr)
10213     {
10214       if (TREE_CODE (expr.value) == C_MAYBE_CONST_EXPR)
10215 	{
10216 	  gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr.value) == NULL_TREE);
10217 	  C_MAYBE_CONST_EXPR_PRE (expr.value) = type_expr;
10218 	}
10219       else
10220 	{
10221 	  gcc_assert (!non_const);
10222 	  expr.value = build2 (C_MAYBE_CONST_EXPR, type,
10223 			       type_expr, expr.value);
10224 	}
10225     }
10226   return c_parser_postfix_expression_after_primary (parser, start_loc, expr);
10227 }
10228 
10229 /* Callback function for sizeof_pointer_memaccess_warning to compare
10230    types.  */
10231 
10232 static bool
sizeof_ptr_memacc_comptypes(tree type1,tree type2)10233 sizeof_ptr_memacc_comptypes (tree type1, tree type2)
10234 {
10235   return comptypes (type1, type2) == 1;
10236 }
10237 
10238 /* Warn for patterns where abs-like function appears to be used incorrectly,
10239    gracefully ignore any non-abs-like function.  The warning location should
10240    be LOC.  FNDECL is the declaration of called function, it must be a
10241    BUILT_IN_NORMAL function.  ARG is the first and only argument of the
10242    call.  */
10243 
10244 static void
warn_for_abs(location_t loc,tree fndecl,tree arg)10245 warn_for_abs (location_t loc, tree fndecl, tree arg)
10246 {
10247   /* Avoid warning in unreachable subexpressions.  */
10248   if (c_inhibit_evaluation_warnings)
10249     return;
10250 
10251   tree atype = TREE_TYPE (arg);
10252 
10253   /* Casts from pointers (and thus arrays and fndecls) will generate
10254      -Wint-conversion warnings.  Most other wrong types hopefully lead to type
10255      mismatch errors.  TODO: Think about what to do with FIXED_POINT_TYPE_P
10256      types and possibly other exotic types.  */
10257   if (!INTEGRAL_TYPE_P (atype)
10258       && !SCALAR_FLOAT_TYPE_P (atype)
10259       && TREE_CODE (atype) != COMPLEX_TYPE)
10260     return;
10261 
10262   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10263 
10264   switch (fcode)
10265     {
10266     case BUILT_IN_ABS:
10267     case BUILT_IN_LABS:
10268     case BUILT_IN_LLABS:
10269     case BUILT_IN_IMAXABS:
10270       if (!INTEGRAL_TYPE_P (atype))
10271 	{
10272 	  if (SCALAR_FLOAT_TYPE_P (atype))
10273 	    warning_at (loc, OPT_Wabsolute_value,
10274 			"using integer absolute value function %qD when "
10275 			"argument is of floating-point type %qT",
10276 			fndecl, atype);
10277 	  else if (TREE_CODE (atype) == COMPLEX_TYPE)
10278 	    warning_at (loc, OPT_Wabsolute_value,
10279 			"using integer absolute value function %qD when "
10280 			"argument is of complex type %qT", fndecl, atype);
10281 	  else
10282 	    gcc_unreachable ();
10283 	  return;
10284 	}
10285       if (TYPE_UNSIGNED (atype))
10286 	warning_at (loc, OPT_Wabsolute_value,
10287 		    "taking the absolute value of unsigned type %qT "
10288 		    "has no effect", atype);
10289       break;
10290 
10291     CASE_FLT_FN (BUILT_IN_FABS):
10292     CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS):
10293       if (!SCALAR_FLOAT_TYPE_P (atype)
10294 	  || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype)))
10295 	{
10296 	  if (INTEGRAL_TYPE_P (atype))
10297 	    warning_at (loc, OPT_Wabsolute_value,
10298 			"using floating-point absolute value function %qD "
10299 			"when argument is of integer type %qT", fndecl, atype);
10300 	  else if (DECIMAL_FLOAT_TYPE_P (atype))
10301 	    warning_at (loc, OPT_Wabsolute_value,
10302 			"using floating-point absolute value function %qD "
10303 			"when argument is of decimal floating-point type %qT",
10304 			fndecl, atype);
10305 	  else if (TREE_CODE (atype) == COMPLEX_TYPE)
10306 	    warning_at (loc, OPT_Wabsolute_value,
10307 			"using floating-point absolute value function %qD when "
10308 			"argument is of complex type %qT", fndecl, atype);
10309 	  else
10310 	    gcc_unreachable ();
10311 	  return;
10312 	}
10313       break;
10314 
10315     CASE_FLT_FN (BUILT_IN_CABS):
10316       if (TREE_CODE (atype) != COMPLEX_TYPE)
10317 	{
10318 	  if (INTEGRAL_TYPE_P (atype))
10319 	    warning_at (loc, OPT_Wabsolute_value,
10320 			"using complex absolute value function %qD when "
10321 			"argument is of integer type %qT", fndecl, atype);
10322 	  else if (SCALAR_FLOAT_TYPE_P (atype))
10323 	    warning_at (loc, OPT_Wabsolute_value,
10324 			"using complex absolute value function %qD when "
10325 			"argument is of floating-point type %qT",
10326 			fndecl, atype);
10327 	  else
10328 	    gcc_unreachable ();
10329 
10330 	  return;
10331 	}
10332       break;
10333 
10334     case BUILT_IN_FABSD32:
10335     case BUILT_IN_FABSD64:
10336     case BUILT_IN_FABSD128:
10337       if (!DECIMAL_FLOAT_TYPE_P (atype))
10338 	{
10339 	  if (INTEGRAL_TYPE_P (atype))
10340 	    warning_at (loc, OPT_Wabsolute_value,
10341 			"using decimal floating-point absolute value "
10342 			"function %qD when argument is of integer type %qT",
10343 			fndecl, atype);
10344 	  else if (SCALAR_FLOAT_TYPE_P (atype))
10345 	    warning_at (loc, OPT_Wabsolute_value,
10346 			"using decimal floating-point absolute value "
10347 			"function %qD when argument is of floating-point "
10348 			"type %qT", fndecl, atype);
10349 	  else if (TREE_CODE (atype) == COMPLEX_TYPE)
10350 	    warning_at (loc, OPT_Wabsolute_value,
10351 			"using decimal floating-point absolute value "
10352 			"function %qD when argument is of complex type %qT",
10353 			fndecl, atype);
10354 	  else
10355 	    gcc_unreachable ();
10356 	  return;
10357 	}
10358       break;
10359 
10360     default:
10361       return;
10362     }
10363 
10364   if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
10365     return;
10366 
10367   tree ftype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
10368   if (TREE_CODE (atype) == COMPLEX_TYPE)
10369     {
10370       gcc_assert (TREE_CODE (ftype) == COMPLEX_TYPE);
10371       atype = TREE_TYPE (atype);
10372       ftype = TREE_TYPE (ftype);
10373     }
10374 
10375   if (TYPE_PRECISION (ftype) < TYPE_PRECISION (atype))
10376     warning_at (loc, OPT_Wabsolute_value,
10377 		"absolute value function %qD given an argument of type %qT "
10378 		"but has parameter of type %qT which may cause truncation "
10379 		"of value", fndecl, atype, ftype);
10380 }
10381 
10382 
10383 /* Parse a postfix expression after the initial primary or compound
10384    literal; that is, parse a series of postfix operators.
10385 
10386    EXPR_LOC is the location of the primary expression.  */
10387 
10388 static struct c_expr
c_parser_postfix_expression_after_primary(c_parser * parser,location_t expr_loc,struct c_expr expr)10389 c_parser_postfix_expression_after_primary (c_parser *parser,
10390 					   location_t expr_loc,
10391 					   struct c_expr expr)
10392 {
10393   struct c_expr orig_expr;
10394   tree ident, idx;
10395   location_t sizeof_arg_loc[3], comp_loc;
10396   tree sizeof_arg[3];
10397   unsigned int literal_zero_mask;
10398   unsigned int i;
10399   vec<tree, va_gc> *exprlist;
10400   vec<tree, va_gc> *origtypes = NULL;
10401   vec<location_t> arg_loc = vNULL;
10402   location_t start;
10403   location_t finish;
10404 
10405   while (true)
10406     {
10407       location_t op_loc = c_parser_peek_token (parser)->location;
10408       switch (c_parser_peek_token (parser)->type)
10409 	{
10410 	case CPP_OPEN_SQUARE:
10411 	  /* Array reference.  */
10412 	  c_parser_consume_token (parser);
10413 	  idx = c_parser_expression (parser).value;
10414 	  c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10415 				     "expected %<]%>");
10416 	  start = expr.get_start ();
10417 	  finish = parser->tokens_buf[0].location;
10418 	  expr.value = build_array_ref (op_loc, expr.value, idx);
10419 	  set_c_expr_source_range (&expr, start, finish);
10420 	  expr.original_code = ERROR_MARK;
10421 	  expr.original_type = NULL;
10422 	  break;
10423 	case CPP_OPEN_PAREN:
10424 	  /* Function call.  */
10425 	  {
10426 	    matching_parens parens;
10427 	    parens.consume_open (parser);
10428 	    for (i = 0; i < 3; i++)
10429 	      {
10430 		sizeof_arg[i] = NULL_TREE;
10431 		sizeof_arg_loc[i] = UNKNOWN_LOCATION;
10432 	      }
10433 	    literal_zero_mask = 0;
10434 	    if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10435 	      exprlist = NULL;
10436 	    else
10437 	      exprlist = c_parser_expr_list (parser, true, false, &origtypes,
10438 					     sizeof_arg_loc, sizeof_arg,
10439 					     &arg_loc, &literal_zero_mask);
10440 	    parens.skip_until_found_close (parser);
10441 	  }
10442 	  orig_expr = expr;
10443 	  mark_exp_read (expr.value);
10444 	  if (warn_sizeof_pointer_memaccess)
10445 	    sizeof_pointer_memaccess_warning (sizeof_arg_loc,
10446 					      expr.value, exprlist,
10447 					      sizeof_arg,
10448 					      sizeof_ptr_memacc_comptypes);
10449 	  if (TREE_CODE (expr.value) == FUNCTION_DECL)
10450 	    {
10451 	      if (fndecl_built_in_p (expr.value, BUILT_IN_MEMSET)
10452 		  && vec_safe_length (exprlist) == 3)
10453 		{
10454 		  tree arg0 = (*exprlist)[0];
10455 		  tree arg2 = (*exprlist)[2];
10456 		  warn_for_memset (expr_loc, arg0, arg2, literal_zero_mask);
10457 		}
10458 	      if (warn_absolute_value
10459 		  && fndecl_built_in_p (expr.value, BUILT_IN_NORMAL)
10460 		  && vec_safe_length (exprlist) == 1)
10461 		warn_for_abs (expr_loc, expr.value, (*exprlist)[0]);
10462 	    }
10463 
10464 	  start = expr.get_start ();
10465 	  finish = parser->tokens_buf[0].get_finish ();
10466 	  expr.value
10467 	    = c_build_function_call_vec (expr_loc, arg_loc, expr.value,
10468 					 exprlist, origtypes);
10469 	  set_c_expr_source_range (&expr, start, finish);
10470 
10471 	  expr.original_code = ERROR_MARK;
10472 	  if (TREE_CODE (expr.value) == INTEGER_CST
10473 	      && TREE_CODE (orig_expr.value) == FUNCTION_DECL
10474 	      && fndecl_built_in_p (orig_expr.value, BUILT_IN_CONSTANT_P))
10475 	    expr.original_code = C_MAYBE_CONST_EXPR;
10476 	  expr.original_type = NULL;
10477 	  if (exprlist)
10478 	    {
10479 	      release_tree_vector (exprlist);
10480 	      release_tree_vector (origtypes);
10481 	    }
10482 	  arg_loc.release ();
10483 	  break;
10484 	case CPP_DOT:
10485 	  /* Structure element reference.  */
10486 	  c_parser_consume_token (parser);
10487 	  expr = default_function_array_conversion (expr_loc, expr);
10488 	  if (c_parser_next_token_is (parser, CPP_NAME))
10489 	    {
10490 	      c_token *comp_tok = c_parser_peek_token (parser);
10491 	      ident = comp_tok->value;
10492 	      comp_loc = comp_tok->location;
10493 	    }
10494 	  else
10495 	    {
10496 	      c_parser_error (parser, "expected identifier");
10497 	      expr.set_error ();
10498 	      expr.original_code = ERROR_MARK;
10499               expr.original_type = NULL;
10500 	      return expr;
10501 	    }
10502 	  start = expr.get_start ();
10503 	  finish = c_parser_peek_token (parser)->get_finish ();
10504 	  c_parser_consume_token (parser);
10505 	  expr.value = build_component_ref (op_loc, expr.value, ident,
10506 					    comp_loc);
10507 	  set_c_expr_source_range (&expr, start, finish);
10508 	  expr.original_code = ERROR_MARK;
10509 	  if (TREE_CODE (expr.value) != COMPONENT_REF)
10510 	    expr.original_type = NULL;
10511 	  else
10512 	    {
10513 	      /* Remember the original type of a bitfield.  */
10514 	      tree field = TREE_OPERAND (expr.value, 1);
10515 	      if (TREE_CODE (field) != FIELD_DECL)
10516 		expr.original_type = NULL;
10517 	      else
10518 		expr.original_type = DECL_BIT_FIELD_TYPE (field);
10519 	    }
10520 	  break;
10521 	case CPP_DEREF:
10522 	  /* Structure element reference.  */
10523 	  c_parser_consume_token (parser);
10524 	  expr = convert_lvalue_to_rvalue (expr_loc, expr, true, false);
10525 	  if (c_parser_next_token_is (parser, CPP_NAME))
10526 	    {
10527 	      c_token *comp_tok = c_parser_peek_token (parser);
10528 	      ident = comp_tok->value;
10529 	      comp_loc = comp_tok->location;
10530 	    }
10531 	  else
10532 	    {
10533 	      c_parser_error (parser, "expected identifier");
10534 	      expr.set_error ();
10535 	      expr.original_code = ERROR_MARK;
10536 	      expr.original_type = NULL;
10537 	      return expr;
10538 	    }
10539 	  start = expr.get_start ();
10540 	  finish = c_parser_peek_token (parser)->get_finish ();
10541 	  c_parser_consume_token (parser);
10542 	  expr.value = build_component_ref (op_loc,
10543 					    build_indirect_ref (op_loc,
10544 								expr.value,
10545 								RO_ARROW),
10546 					    ident, comp_loc);
10547 	  set_c_expr_source_range (&expr, start, finish);
10548 	  expr.original_code = ERROR_MARK;
10549 	  if (TREE_CODE (expr.value) != COMPONENT_REF)
10550 	    expr.original_type = NULL;
10551 	  else
10552 	    {
10553 	      /* Remember the original type of a bitfield.  */
10554 	      tree field = TREE_OPERAND (expr.value, 1);
10555 	      if (TREE_CODE (field) != FIELD_DECL)
10556 		expr.original_type = NULL;
10557 	      else
10558 		expr.original_type = DECL_BIT_FIELD_TYPE (field);
10559 	    }
10560 	  break;
10561 	case CPP_PLUS_PLUS:
10562 	  /* Postincrement.  */
10563 	  start = expr.get_start ();
10564 	  finish = c_parser_peek_token (parser)->get_finish ();
10565 	  c_parser_consume_token (parser);
10566 	  expr = default_function_array_read_conversion (expr_loc, expr);
10567 	  expr.value = build_unary_op (op_loc, POSTINCREMENT_EXPR,
10568 				       expr.value, false);
10569 	  set_c_expr_source_range (&expr, start, finish);
10570 	  expr.original_code = ERROR_MARK;
10571 	  expr.original_type = NULL;
10572 	  break;
10573 	case CPP_MINUS_MINUS:
10574 	  /* Postdecrement.  */
10575 	  start = expr.get_start ();
10576 	  finish = c_parser_peek_token (parser)->get_finish ();
10577 	  c_parser_consume_token (parser);
10578 	  expr = default_function_array_read_conversion (expr_loc, expr);
10579 	  expr.value = build_unary_op (op_loc, POSTDECREMENT_EXPR,
10580 				       expr.value, false);
10581 	  set_c_expr_source_range (&expr, start, finish);
10582 	  expr.original_code = ERROR_MARK;
10583 	  expr.original_type = NULL;
10584 	  break;
10585 	default:
10586 	  return expr;
10587 	}
10588     }
10589 }
10590 
10591 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
10592 
10593    expression:
10594      assignment-expression
10595      expression , assignment-expression
10596 */
10597 
10598 static struct c_expr
c_parser_expression(c_parser * parser)10599 c_parser_expression (c_parser *parser)
10600 {
10601   location_t tloc = c_parser_peek_token (parser)->location;
10602   struct c_expr expr;
10603   expr = c_parser_expr_no_commas (parser, NULL);
10604   if (c_parser_next_token_is (parser, CPP_COMMA))
10605     expr = convert_lvalue_to_rvalue (tloc, expr, true, false);
10606   while (c_parser_next_token_is (parser, CPP_COMMA))
10607     {
10608       struct c_expr next;
10609       tree lhsval;
10610       location_t loc = c_parser_peek_token (parser)->location;
10611       location_t expr_loc;
10612       c_parser_consume_token (parser);
10613       expr_loc = c_parser_peek_token (parser)->location;
10614       lhsval = expr.value;
10615       while (TREE_CODE (lhsval) == COMPOUND_EXPR
10616 	     || TREE_CODE (lhsval) == NOP_EXPR)
10617 	{
10618 	  if (TREE_CODE (lhsval) == COMPOUND_EXPR)
10619 	    lhsval = TREE_OPERAND (lhsval, 1);
10620 	  else
10621 	    lhsval = TREE_OPERAND (lhsval, 0);
10622 	}
10623       if (DECL_P (lhsval) || handled_component_p (lhsval))
10624 	mark_exp_read (lhsval);
10625       next = c_parser_expr_no_commas (parser, NULL);
10626       next = convert_lvalue_to_rvalue (expr_loc, next, true, false);
10627       expr.value = build_compound_expr (loc, expr.value, next.value);
10628       expr.original_code = COMPOUND_EXPR;
10629       expr.original_type = next.original_type;
10630     }
10631   return expr;
10632 }
10633 
10634 /* Parse an expression and convert functions or arrays to pointers and
10635    lvalues to rvalues.  */
10636 
10637 static struct c_expr
c_parser_expression_conv(c_parser * parser)10638 c_parser_expression_conv (c_parser *parser)
10639 {
10640   struct c_expr expr;
10641   location_t loc = c_parser_peek_token (parser)->location;
10642   expr = c_parser_expression (parser);
10643   expr = convert_lvalue_to_rvalue (loc, expr, true, false);
10644   return expr;
10645 }
10646 
10647 /* Helper function of c_parser_expr_list.  Check if IDXth (0 based)
10648    argument is a literal zero alone and if so, set it in literal_zero_mask.  */
10649 
10650 static inline void
c_parser_check_literal_zero(c_parser * parser,unsigned * literal_zero_mask,unsigned int idx)10651 c_parser_check_literal_zero (c_parser *parser, unsigned *literal_zero_mask,
10652 			     unsigned int idx)
10653 {
10654   if (idx >= HOST_BITS_PER_INT)
10655     return;
10656 
10657   c_token *tok = c_parser_peek_token (parser);
10658   switch (tok->type)
10659     {
10660     case CPP_NUMBER:
10661     case CPP_CHAR:
10662     case CPP_WCHAR:
10663     case CPP_CHAR16:
10664     case CPP_CHAR32:
10665     case CPP_UTF8CHAR:
10666       /* If a parameter is literal zero alone, remember it
10667 	 for -Wmemset-transposed-args warning.  */
10668       if (integer_zerop (tok->value)
10669 	  && !TREE_OVERFLOW (tok->value)
10670 	  && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
10671 	      || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
10672 	*literal_zero_mask |= 1U << idx;
10673     default:
10674       break;
10675     }
10676 }
10677 
10678 /* Parse a non-empty list of expressions.  If CONVERT_P, convert
10679    functions and arrays to pointers and lvalues to rvalues.  If
10680    FOLD_P, fold the expressions.  If LOCATIONS is non-NULL, save the
10681    locations of function arguments into this vector.
10682 
10683    nonempty-expr-list:
10684      assignment-expression
10685      nonempty-expr-list , assignment-expression
10686 */
10687 
10688 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)10689 c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
10690 		    vec<tree, va_gc> **p_orig_types,
10691 		    location_t *sizeof_arg_loc, tree *sizeof_arg,
10692 		    vec<location_t> *locations,
10693 		    unsigned int *literal_zero_mask)
10694 {
10695   vec<tree, va_gc> *ret;
10696   vec<tree, va_gc> *orig_types;
10697   struct c_expr expr;
10698   unsigned int idx = 0;
10699 
10700   ret = make_tree_vector ();
10701   if (p_orig_types == NULL)
10702     orig_types = NULL;
10703   else
10704     orig_types = make_tree_vector ();
10705 
10706   if (literal_zero_mask)
10707     c_parser_check_literal_zero (parser, literal_zero_mask, 0);
10708   expr = c_parser_expr_no_commas (parser, NULL);
10709   if (convert_p)
10710     expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true, true);
10711   if (fold_p)
10712     expr.value = c_fully_fold (expr.value, false, NULL);
10713   ret->quick_push (expr.value);
10714   if (orig_types)
10715     orig_types->quick_push (expr.original_type);
10716   if (locations)
10717     locations->safe_push (expr.get_location ());
10718   if (sizeof_arg != NULL
10719       && (expr.original_code == SIZEOF_EXPR
10720 	  || expr.original_code == PAREN_SIZEOF_EXPR))
10721     {
10722       sizeof_arg[0] = c_last_sizeof_arg;
10723       sizeof_arg_loc[0] = c_last_sizeof_loc;
10724     }
10725   while (c_parser_next_token_is (parser, CPP_COMMA))
10726     {
10727       c_parser_consume_token (parser);
10728       if (literal_zero_mask)
10729 	c_parser_check_literal_zero (parser, literal_zero_mask, idx + 1);
10730       expr = c_parser_expr_no_commas (parser, NULL);
10731       if (convert_p)
10732 	expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true,
10733 					 true);
10734       if (fold_p)
10735 	expr.value = c_fully_fold (expr.value, false, NULL);
10736       vec_safe_push (ret, expr.value);
10737       if (orig_types)
10738 	vec_safe_push (orig_types, expr.original_type);
10739       if (locations)
10740 	locations->safe_push (expr.get_location ());
10741       if (++idx < 3
10742 	  && sizeof_arg != NULL
10743 	  && (expr.original_code == SIZEOF_EXPR
10744 	      || expr.original_code == PAREN_SIZEOF_EXPR))
10745 	{
10746 	  sizeof_arg[idx] = c_last_sizeof_arg;
10747 	  sizeof_arg_loc[idx] = c_last_sizeof_loc;
10748 	}
10749     }
10750   if (orig_types)
10751     *p_orig_types = orig_types;
10752   return ret;
10753 }
10754 
10755 /* Parse Objective-C-specific constructs.  */
10756 
10757 /* Parse an objc-class-definition.
10758 
10759    objc-class-definition:
10760      @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
10761        objc-class-instance-variables[opt] objc-methodprotolist @end
10762      @implementation identifier objc-superclass[opt]
10763        objc-class-instance-variables[opt]
10764      @interface identifier ( identifier ) objc-protocol-refs[opt]
10765        objc-methodprotolist @end
10766      @interface identifier ( ) objc-protocol-refs[opt]
10767        objc-methodprotolist @end
10768      @implementation identifier ( identifier )
10769 
10770    objc-superclass:
10771      : identifier
10772 
10773    "@interface identifier (" must start "@interface identifier (
10774    identifier ) ...": objc-methodprotolist in the first production may
10775    not start with a parenthesized identifier as a declarator of a data
10776    definition with no declaration specifiers if the objc-superclass,
10777    objc-protocol-refs and objc-class-instance-variables are omitted.  */
10778 
10779 static void
c_parser_objc_class_definition(c_parser * parser,tree attributes)10780 c_parser_objc_class_definition (c_parser *parser, tree attributes)
10781 {
10782   bool iface_p;
10783   tree id1;
10784   tree superclass;
10785   if (c_parser_next_token_is_keyword (parser, RID_AT_INTERFACE))
10786     iface_p = true;
10787   else if (c_parser_next_token_is_keyword (parser, RID_AT_IMPLEMENTATION))
10788     iface_p = false;
10789   else
10790     gcc_unreachable ();
10791 
10792   c_parser_consume_token (parser);
10793   if (c_parser_next_token_is_not (parser, CPP_NAME))
10794     {
10795       c_parser_error (parser, "expected identifier");
10796       return;
10797     }
10798   id1 = c_parser_peek_token (parser)->value;
10799   location_t loc1 = c_parser_peek_token (parser)->location;
10800   c_parser_consume_token (parser);
10801   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
10802     {
10803       /* We have a category or class extension.  */
10804       tree id2;
10805       tree proto = NULL_TREE;
10806       matching_parens parens;
10807       parens.consume_open (parser);
10808       if (c_parser_next_token_is_not (parser, CPP_NAME))
10809 	{
10810 	  if (iface_p && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10811 	    {
10812 	      /* We have a class extension.  */
10813 	      id2 = NULL_TREE;
10814 	    }
10815 	  else
10816 	    {
10817 	      c_parser_error (parser, "expected identifier or %<)%>");
10818 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10819 	      return;
10820 	    }
10821 	}
10822       else
10823 	{
10824 	  id2 = c_parser_peek_token (parser)->value;
10825 	  c_parser_consume_token (parser);
10826 	}
10827       parens.skip_until_found_close (parser);
10828       if (!iface_p)
10829 	{
10830 	  objc_start_category_implementation (id1, id2);
10831 	  return;
10832 	}
10833       if (c_parser_next_token_is (parser, CPP_LESS))
10834 	proto = c_parser_objc_protocol_refs (parser);
10835       objc_start_category_interface (id1, id2, proto, attributes);
10836       c_parser_objc_methodprotolist (parser);
10837       c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
10838       objc_finish_interface ();
10839       return;
10840     }
10841   if (c_parser_next_token_is (parser, CPP_COLON))
10842     {
10843       c_parser_consume_token (parser);
10844       if (c_parser_next_token_is_not (parser, CPP_NAME))
10845 	{
10846 	  c_parser_error (parser, "expected identifier");
10847 	  return;
10848 	}
10849       superclass = c_parser_peek_token (parser)->value;
10850       c_parser_consume_token (parser);
10851     }
10852   else
10853     superclass = NULL_TREE;
10854   if (iface_p)
10855     {
10856       tree proto = NULL_TREE;
10857       if (c_parser_next_token_is (parser, CPP_LESS))
10858 	proto = c_parser_objc_protocol_refs (parser);
10859       objc_start_class_interface (id1, loc1, superclass, proto, attributes);
10860     }
10861   else
10862     objc_start_class_implementation (id1, superclass);
10863   if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
10864     c_parser_objc_class_instance_variables (parser);
10865   if (iface_p)
10866     {
10867       objc_continue_interface ();
10868       c_parser_objc_methodprotolist (parser);
10869       c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
10870       objc_finish_interface ();
10871     }
10872   else
10873     {
10874       objc_continue_implementation ();
10875       return;
10876     }
10877 }
10878 
10879 /* Parse objc-class-instance-variables.
10880 
10881    objc-class-instance-variables:
10882      { objc-instance-variable-decl-list[opt] }
10883 
10884    objc-instance-variable-decl-list:
10885      objc-visibility-spec
10886      objc-instance-variable-decl ;
10887      ;
10888      objc-instance-variable-decl-list objc-visibility-spec
10889      objc-instance-variable-decl-list objc-instance-variable-decl ;
10890      objc-instance-variable-decl-list ;
10891 
10892    objc-visibility-spec:
10893      @private
10894      @protected
10895      @public
10896 
10897    objc-instance-variable-decl:
10898      struct-declaration
10899 */
10900 
10901 static void
c_parser_objc_class_instance_variables(c_parser * parser)10902 c_parser_objc_class_instance_variables (c_parser *parser)
10903 {
10904   gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
10905   c_parser_consume_token (parser);
10906   while (c_parser_next_token_is_not (parser, CPP_EOF))
10907     {
10908       tree decls;
10909       /* Parse any stray semicolon.  */
10910       if (c_parser_next_token_is (parser, CPP_SEMICOLON))
10911 	{
10912 	  pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
10913 		   "extra semicolon");
10914 	  c_parser_consume_token (parser);
10915 	  continue;
10916 	}
10917       /* Stop if at the end of the instance variables.  */
10918       if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
10919 	{
10920 	  c_parser_consume_token (parser);
10921 	  break;
10922 	}
10923       /* Parse any objc-visibility-spec.  */
10924       if (c_parser_next_token_is_keyword (parser, RID_AT_PRIVATE))
10925 	{
10926 	  c_parser_consume_token (parser);
10927 	  objc_set_visibility (OBJC_IVAR_VIS_PRIVATE);
10928 	  continue;
10929 	}
10930       else if (c_parser_next_token_is_keyword (parser, RID_AT_PROTECTED))
10931 	{
10932 	  c_parser_consume_token (parser);
10933 	  objc_set_visibility (OBJC_IVAR_VIS_PROTECTED);
10934 	  continue;
10935 	}
10936       else if (c_parser_next_token_is_keyword (parser, RID_AT_PUBLIC))
10937 	{
10938 	  c_parser_consume_token (parser);
10939 	  objc_set_visibility (OBJC_IVAR_VIS_PUBLIC);
10940 	  continue;
10941 	}
10942       else if (c_parser_next_token_is_keyword (parser, RID_AT_PACKAGE))
10943 	{
10944 	  c_parser_consume_token (parser);
10945 	  objc_set_visibility (OBJC_IVAR_VIS_PACKAGE);
10946 	  continue;
10947 	}
10948       else if (c_parser_next_token_is (parser, CPP_PRAGMA))
10949 	{
10950 	  c_parser_pragma (parser, pragma_external, NULL);
10951 	  continue;
10952 	}
10953 
10954       /* Parse some comma-separated declarations.  */
10955       decls = c_parser_struct_declaration (parser);
10956       if (decls == NULL)
10957 	{
10958 	  /* There is a syntax error.  We want to skip the offending
10959 	     tokens up to the next ';' (included) or '}'
10960 	     (excluded).  */
10961 
10962 	  /* First, skip manually a ')' or ']'.  This is because they
10963 	     reduce the nesting level, so c_parser_skip_until_found()
10964 	     wouldn't be able to skip past them.  */
10965 	  c_token *token = c_parser_peek_token (parser);
10966 	  if (token->type == CPP_CLOSE_PAREN || token->type == CPP_CLOSE_SQUARE)
10967 	    c_parser_consume_token (parser);
10968 
10969 	  /* Then, do the standard skipping.  */
10970 	  c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
10971 
10972 	  /* We hopefully recovered.  Start normal parsing again.  */
10973 	  parser->error = false;
10974 	  continue;
10975 	}
10976       else
10977 	{
10978 	  /* Comma-separated instance variables are chained together
10979 	     in reverse order; add them one by one.  */
10980 	  tree ivar = nreverse (decls);
10981 	  for (; ivar; ivar = DECL_CHAIN (ivar))
10982 	    objc_add_instance_variable (copy_node (ivar));
10983 	}
10984       c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
10985     }
10986 }
10987 
10988 /* Parse an objc-class-declaration.
10989 
10990    objc-class-declaration:
10991      @class identifier-list ;
10992 */
10993 
10994 static void
c_parser_objc_class_declaration(c_parser * parser)10995 c_parser_objc_class_declaration (c_parser *parser)
10996 {
10997   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_CLASS));
10998   c_parser_consume_token (parser);
10999   /* Any identifiers, including those declared as type names, are OK
11000      here.  */
11001   while (true)
11002     {
11003       tree id;
11004       if (c_parser_next_token_is_not (parser, CPP_NAME))
11005 	{
11006 	  c_parser_error (parser, "expected identifier");
11007 	  c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11008 	  parser->error = false;
11009 	  return;
11010 	}
11011       id = c_parser_peek_token (parser)->value;
11012       objc_declare_class (id);
11013       c_parser_consume_token (parser);
11014       if (c_parser_next_token_is (parser, CPP_COMMA))
11015 	c_parser_consume_token (parser);
11016       else
11017 	break;
11018     }
11019   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11020 }
11021 
11022 /* Parse an objc-alias-declaration.
11023 
11024    objc-alias-declaration:
11025      @compatibility_alias identifier identifier ;
11026 */
11027 
11028 static void
c_parser_objc_alias_declaration(c_parser * parser)11029 c_parser_objc_alias_declaration (c_parser *parser)
11030 {
11031   tree id1, id2;
11032   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_ALIAS));
11033   c_parser_consume_token (parser);
11034   if (c_parser_next_token_is_not (parser, CPP_NAME))
11035     {
11036       c_parser_error (parser, "expected identifier");
11037       c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11038       return;
11039     }
11040   id1 = c_parser_peek_token (parser)->value;
11041   c_parser_consume_token (parser);
11042   if (c_parser_next_token_is_not (parser, CPP_NAME))
11043     {
11044       c_parser_error (parser, "expected identifier");
11045       c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11046       return;
11047     }
11048   id2 = c_parser_peek_token (parser)->value;
11049   c_parser_consume_token (parser);
11050   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11051   objc_declare_alias (id1, id2);
11052 }
11053 
11054 /* Parse an objc-protocol-definition.
11055 
11056    objc-protocol-definition:
11057      @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
11058      @protocol identifier-list ;
11059 
11060    "@protocol identifier ;" should be resolved as "@protocol
11061    identifier-list ;": objc-methodprotolist may not start with a
11062    semicolon in the first alternative if objc-protocol-refs are
11063    omitted.  */
11064 
11065 static void
c_parser_objc_protocol_definition(c_parser * parser,tree attributes)11066 c_parser_objc_protocol_definition (c_parser *parser, tree attributes)
11067 {
11068   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROTOCOL));
11069 
11070   c_parser_consume_token (parser);
11071   if (c_parser_next_token_is_not (parser, CPP_NAME))
11072     {
11073       c_parser_error (parser, "expected identifier");
11074       return;
11075     }
11076   if (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
11077       || c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON)
11078     {
11079       /* Any identifiers, including those declared as type names, are
11080 	 OK here.  */
11081       while (true)
11082 	{
11083 	  tree id;
11084 	  if (c_parser_next_token_is_not (parser, CPP_NAME))
11085 	    {
11086 	      c_parser_error (parser, "expected identifier");
11087 	      break;
11088 	    }
11089 	  id = c_parser_peek_token (parser)->value;
11090 	  objc_declare_protocol (id, attributes);
11091 	  c_parser_consume_token (parser);
11092 	  if (c_parser_next_token_is (parser, CPP_COMMA))
11093 	    c_parser_consume_token (parser);
11094 	  else
11095 	    break;
11096 	}
11097       c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11098     }
11099   else
11100     {
11101       tree id = c_parser_peek_token (parser)->value;
11102       tree proto = NULL_TREE;
11103       c_parser_consume_token (parser);
11104       if (c_parser_next_token_is (parser, CPP_LESS))
11105 	proto = c_parser_objc_protocol_refs (parser);
11106       parser->objc_pq_context = true;
11107       objc_start_protocol (id, proto, attributes);
11108       c_parser_objc_methodprotolist (parser);
11109       c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
11110       parser->objc_pq_context = false;
11111       objc_finish_interface ();
11112     }
11113 }
11114 
11115 /* Parse an objc-method-type.
11116 
11117    objc-method-type:
11118      +
11119      -
11120 
11121    Return true if it is a class method (+) and false if it is
11122    an instance method (-).
11123 */
11124 static inline bool
c_parser_objc_method_type(c_parser * parser)11125 c_parser_objc_method_type (c_parser *parser)
11126 {
11127   switch (c_parser_peek_token (parser)->type)
11128     {
11129     case CPP_PLUS:
11130       c_parser_consume_token (parser);
11131       return true;
11132     case CPP_MINUS:
11133       c_parser_consume_token (parser);
11134       return false;
11135     default:
11136       gcc_unreachable ();
11137     }
11138 }
11139 
11140 /* Parse an objc-method-definition.
11141 
11142    objc-method-definition:
11143      objc-method-type objc-method-decl ;[opt] compound-statement
11144 */
11145 
11146 static void
c_parser_objc_method_definition(c_parser * parser)11147 c_parser_objc_method_definition (c_parser *parser)
11148 {
11149   bool is_class_method = c_parser_objc_method_type (parser);
11150   tree decl, attributes = NULL_TREE, expr = NULL_TREE;
11151   parser->objc_pq_context = true;
11152   decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
11153 				    &expr);
11154   if (decl == error_mark_node)
11155     return;  /* Bail here. */
11156 
11157   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
11158     {
11159       c_parser_consume_token (parser);
11160       pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11161 	       "extra semicolon in method definition specified");
11162     }
11163 
11164   if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11165     {
11166       c_parser_error (parser, "expected %<{%>");
11167       return;
11168     }
11169 
11170   parser->objc_pq_context = false;
11171   if (objc_start_method_definition (is_class_method, decl, attributes, expr))
11172     {
11173       add_stmt (c_parser_compound_statement (parser));
11174       objc_finish_method_definition (current_function_decl);
11175     }
11176   else
11177     {
11178       /* This code is executed when we find a method definition
11179 	 outside of an @implementation context (or invalid for other
11180 	 reasons).  Parse the method (to keep going) but do not emit
11181 	 any code.
11182       */
11183       c_parser_compound_statement (parser);
11184     }
11185 }
11186 
11187 /* Parse an objc-methodprotolist.
11188 
11189    objc-methodprotolist:
11190      empty
11191      objc-methodprotolist objc-methodproto
11192      objc-methodprotolist declaration
11193      objc-methodprotolist ;
11194      @optional
11195      @required
11196 
11197    The declaration is a data definition, which may be missing
11198    declaration specifiers under the same rules and diagnostics as
11199    other data definitions outside functions, and the stray semicolon
11200    is diagnosed the same way as a stray semicolon outside a
11201    function.  */
11202 
11203 static void
c_parser_objc_methodprotolist(c_parser * parser)11204 c_parser_objc_methodprotolist (c_parser *parser)
11205 {
11206   while (true)
11207     {
11208       /* The list is terminated by @end.  */
11209       switch (c_parser_peek_token (parser)->type)
11210 	{
11211 	case CPP_SEMICOLON:
11212 	  pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11213 		   "ISO C does not allow extra %<;%> outside of a function");
11214 	  c_parser_consume_token (parser);
11215 	  break;
11216 	case CPP_PLUS:
11217 	case CPP_MINUS:
11218 	  c_parser_objc_methodproto (parser);
11219 	  break;
11220 	case CPP_PRAGMA:
11221 	  c_parser_pragma (parser, pragma_external, NULL);
11222 	  break;
11223 	case CPP_EOF:
11224 	  return;
11225 	default:
11226 	  if (c_parser_next_token_is_keyword (parser, RID_AT_END))
11227 	    return;
11228 	  else if (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY))
11229 	    c_parser_objc_at_property_declaration (parser);
11230 	  else if (c_parser_next_token_is_keyword (parser, RID_AT_OPTIONAL))
11231 	    {
11232 	      objc_set_method_opt (true);
11233 	      c_parser_consume_token (parser);
11234 	    }
11235 	  else if (c_parser_next_token_is_keyword (parser, RID_AT_REQUIRED))
11236 	    {
11237 	      objc_set_method_opt (false);
11238 	      c_parser_consume_token (parser);
11239 	    }
11240 	  else
11241 	    c_parser_declaration_or_fndef (parser, false, false, true,
11242 					   false, true, NULL, vNULL);
11243 	  break;
11244 	}
11245     }
11246 }
11247 
11248 /* Parse an objc-methodproto.
11249 
11250    objc-methodproto:
11251      objc-method-type objc-method-decl ;
11252 */
11253 
11254 static void
c_parser_objc_methodproto(c_parser * parser)11255 c_parser_objc_methodproto (c_parser *parser)
11256 {
11257   bool is_class_method = c_parser_objc_method_type (parser);
11258   tree decl, attributes = NULL_TREE;
11259 
11260   /* Remember protocol qualifiers in prototypes.  */
11261   parser->objc_pq_context = true;
11262   decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
11263 				    NULL);
11264   /* Forget protocol qualifiers now.  */
11265   parser->objc_pq_context = false;
11266 
11267   /* Do not allow the presence of attributes to hide an erroneous
11268      method implementation in the interface section.  */
11269   if (!c_parser_next_token_is (parser, CPP_SEMICOLON))
11270     {
11271       c_parser_error (parser, "expected %<;%>");
11272       return;
11273     }
11274 
11275   if (decl != error_mark_node)
11276     objc_add_method_declaration (is_class_method, decl, attributes);
11277 
11278   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11279 }
11280 
11281 /* If we are at a position that method attributes may be present, check that
11282    there are not any parsed already (a syntax error) and then collect any
11283    specified at the current location.  Finally, if new attributes were present,
11284    check that the next token is legal ( ';' for decls and '{' for defs).  */
11285 
11286 static bool
c_parser_objc_maybe_method_attributes(c_parser * parser,tree * attributes)11287 c_parser_objc_maybe_method_attributes (c_parser* parser, tree* attributes)
11288 {
11289   bool bad = false;
11290   if (*attributes)
11291     {
11292       c_parser_error (parser,
11293 		    "method attributes must be specified at the end only");
11294       *attributes = NULL_TREE;
11295       bad = true;
11296     }
11297 
11298   if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
11299     *attributes = c_parser_gnu_attributes (parser);
11300 
11301   /* If there were no attributes here, just report any earlier error.  */
11302   if (*attributes == NULL_TREE || bad)
11303     return bad;
11304 
11305   /* If the attributes are followed by a ; or {, then just report any earlier
11306      error.  */
11307   if (c_parser_next_token_is (parser, CPP_SEMICOLON)
11308       || c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11309     return bad;
11310 
11311   /* We've got attributes, but not at the end.  */
11312   c_parser_error (parser,
11313 		  "expected %<;%> or %<{%> after method attribute definition");
11314   return true;
11315 }
11316 
11317 /* Parse an objc-method-decl.
11318 
11319    objc-method-decl:
11320      ( objc-type-name ) objc-selector
11321      objc-selector
11322      ( objc-type-name ) objc-keyword-selector objc-optparmlist
11323      objc-keyword-selector objc-optparmlist
11324      gnu-attributes
11325 
11326    objc-keyword-selector:
11327      objc-keyword-decl
11328      objc-keyword-selector objc-keyword-decl
11329 
11330    objc-keyword-decl:
11331      objc-selector : ( objc-type-name ) identifier
11332      objc-selector : identifier
11333      : ( objc-type-name ) identifier
11334      : identifier
11335 
11336    objc-optparmlist:
11337      objc-optparms objc-optellipsis
11338 
11339    objc-optparms:
11340      empty
11341      objc-opt-parms , parameter-declaration
11342 
11343    objc-optellipsis:
11344      empty
11345      , ...
11346 */
11347 
11348 static tree
c_parser_objc_method_decl(c_parser * parser,bool is_class_method,tree * attributes,tree * expr)11349 c_parser_objc_method_decl (c_parser *parser, bool is_class_method,
11350 			   tree *attributes, tree *expr)
11351 {
11352   tree type = NULL_TREE;
11353   tree sel;
11354   tree parms = NULL_TREE;
11355   bool ellipsis = false;
11356   bool attr_err = false;
11357 
11358   *attributes = NULL_TREE;
11359   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11360     {
11361       matching_parens parens;
11362       parens.consume_open (parser);
11363       type = c_parser_objc_type_name (parser);
11364       parens.skip_until_found_close (parser);
11365     }
11366   sel = c_parser_objc_selector (parser);
11367   /* If there is no selector, or a colon follows, we have an
11368      objc-keyword-selector.  If there is a selector, and a colon does
11369      not follow, that selector ends the objc-method-decl.  */
11370   if (!sel || c_parser_next_token_is (parser, CPP_COLON))
11371     {
11372       tree tsel = sel;
11373       tree list = NULL_TREE;
11374       while (true)
11375 	{
11376 	  tree atype = NULL_TREE, id, keyworddecl;
11377 	  tree param_attr = NULL_TREE;
11378 	  if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11379 	    break;
11380 	  if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11381 	    {
11382 	      c_parser_consume_token (parser);
11383 	      atype = c_parser_objc_type_name (parser);
11384 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
11385 					 "expected %<)%>");
11386 	    }
11387 	  /* New ObjC allows attributes on method parameters.  */
11388 	  if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
11389 	    param_attr = c_parser_gnu_attributes (parser);
11390 	  if (c_parser_next_token_is_not (parser, CPP_NAME))
11391 	    {
11392 	      c_parser_error (parser, "expected identifier");
11393 	      return error_mark_node;
11394 	    }
11395 	  id = c_parser_peek_token (parser)->value;
11396 	  c_parser_consume_token (parser);
11397 	  keyworddecl = objc_build_keyword_decl (tsel, atype, id, param_attr);
11398 	  list = chainon (list, keyworddecl);
11399 	  tsel = c_parser_objc_selector (parser);
11400 	  if (!tsel && c_parser_next_token_is_not (parser, CPP_COLON))
11401 	    break;
11402 	}
11403 
11404       attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
11405 
11406       /* Parse the optional parameter list.  Optional Objective-C
11407 	 method parameters follow the C syntax, and may include '...'
11408 	 to denote a variable number of arguments.  */
11409       parms = make_node (TREE_LIST);
11410       while (c_parser_next_token_is (parser, CPP_COMMA))
11411 	{
11412 	  struct c_parm *parm;
11413 	  c_parser_consume_token (parser);
11414 	  if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
11415 	    {
11416 	      ellipsis = true;
11417 	      c_parser_consume_token (parser);
11418 	      attr_err |= c_parser_objc_maybe_method_attributes
11419 						(parser, attributes) ;
11420 	      break;
11421 	    }
11422 	  parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
11423 	  if (parm == NULL)
11424 	    break;
11425 	  parms = chainon (parms,
11426 			   build_tree_list (NULL_TREE, grokparm (parm, expr)));
11427 	}
11428       sel = list;
11429     }
11430   else
11431     attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
11432 
11433   if (sel == NULL)
11434     {
11435       c_parser_error (parser, "objective-c method declaration is expected");
11436       return error_mark_node;
11437     }
11438 
11439   if (attr_err)
11440     return error_mark_node;
11441 
11442   return objc_build_method_signature (is_class_method, type, sel, parms, ellipsis);
11443 }
11444 
11445 /* Parse an objc-type-name.
11446 
11447    objc-type-name:
11448      objc-type-qualifiers[opt] type-name
11449      objc-type-qualifiers[opt]
11450 
11451    objc-type-qualifiers:
11452      objc-type-qualifier
11453      objc-type-qualifiers objc-type-qualifier
11454 
11455    objc-type-qualifier: one of
11456      in out inout bycopy byref oneway
11457 */
11458 
11459 static tree
c_parser_objc_type_name(c_parser * parser)11460 c_parser_objc_type_name (c_parser *parser)
11461 {
11462   tree quals = NULL_TREE;
11463   struct c_type_name *type_name = NULL;
11464   tree type = NULL_TREE;
11465   while (true)
11466     {
11467       c_token *token = c_parser_peek_token (parser);
11468       if (token->type == CPP_KEYWORD
11469 	  && (token->keyword == RID_IN
11470 	      || token->keyword == RID_OUT
11471 	      || token->keyword == RID_INOUT
11472 	      || token->keyword == RID_BYCOPY
11473 	      || token->keyword == RID_BYREF
11474 	      || token->keyword == RID_ONEWAY))
11475 	{
11476 	  quals = chainon (build_tree_list (NULL_TREE, token->value), quals);
11477 	  c_parser_consume_token (parser);
11478 	}
11479       else
11480 	break;
11481     }
11482   if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
11483     type_name = c_parser_type_name (parser);
11484   if (type_name)
11485     type = groktypename (type_name, NULL, NULL);
11486 
11487   /* If the type is unknown, and error has already been produced and
11488      we need to recover from the error.  In that case, use NULL_TREE
11489      for the type, as if no type had been specified; this will use the
11490      default type ('id') which is good for error recovery.  */
11491   if (type == error_mark_node)
11492     type = NULL_TREE;
11493 
11494   return build_tree_list (quals, type);
11495 }
11496 
11497 /* Parse objc-protocol-refs.
11498 
11499    objc-protocol-refs:
11500      < identifier-list >
11501 */
11502 
11503 static tree
c_parser_objc_protocol_refs(c_parser * parser)11504 c_parser_objc_protocol_refs (c_parser *parser)
11505 {
11506   tree list = NULL_TREE;
11507   gcc_assert (c_parser_next_token_is (parser, CPP_LESS));
11508   c_parser_consume_token (parser);
11509   /* Any identifiers, including those declared as type names, are OK
11510      here.  */
11511   while (true)
11512     {
11513       tree id;
11514       if (c_parser_next_token_is_not (parser, CPP_NAME))
11515 	{
11516 	  c_parser_error (parser, "expected identifier");
11517 	  break;
11518 	}
11519       id = c_parser_peek_token (parser)->value;
11520       list = chainon (list, build_tree_list (NULL_TREE, id));
11521       c_parser_consume_token (parser);
11522       if (c_parser_next_token_is (parser, CPP_COMMA))
11523 	c_parser_consume_token (parser);
11524       else
11525 	break;
11526     }
11527   c_parser_require (parser, CPP_GREATER, "expected %<>%>");
11528   return list;
11529 }
11530 
11531 /* Parse an objc-try-catch-finally-statement.
11532 
11533    objc-try-catch-finally-statement:
11534      @try compound-statement objc-catch-list[opt]
11535      @try compound-statement objc-catch-list[opt] @finally compound-statement
11536 
11537    objc-catch-list:
11538      @catch ( objc-catch-parameter-declaration ) compound-statement
11539      objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
11540 
11541    objc-catch-parameter-declaration:
11542      parameter-declaration
11543      '...'
11544 
11545    where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
11546 
11547    PS: This function is identical to cp_parser_objc_try_catch_finally_statement
11548    for C++.  Keep them in sync.  */
11549 
11550 static void
c_parser_objc_try_catch_finally_statement(c_parser * parser)11551 c_parser_objc_try_catch_finally_statement (c_parser *parser)
11552 {
11553   location_t location;
11554   tree stmt;
11555 
11556   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_TRY));
11557   c_parser_consume_token (parser);
11558   location = c_parser_peek_token (parser)->location;
11559   objc_maybe_warn_exceptions (location);
11560   stmt = c_parser_compound_statement (parser);
11561   objc_begin_try_stmt (location, stmt);
11562 
11563   while (c_parser_next_token_is_keyword (parser, RID_AT_CATCH))
11564     {
11565       struct c_parm *parm;
11566       tree parameter_declaration = error_mark_node;
11567       bool seen_open_paren = false;
11568 
11569       c_parser_consume_token (parser);
11570       matching_parens parens;
11571       if (!parens.require_open (parser))
11572 	seen_open_paren = true;
11573       if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
11574 	{
11575 	  /* We have "@catch (...)" (where the '...' are literally
11576 	     what is in the code).  Skip the '...'.
11577 	     parameter_declaration is set to NULL_TREE, and
11578 	     objc_being_catch_clauses() knows that that means
11579 	     '...'.  */
11580 	  c_parser_consume_token (parser);
11581 	  parameter_declaration = NULL_TREE;
11582 	}
11583       else
11584 	{
11585 	  /* We have "@catch (NSException *exception)" or something
11586 	     like that.  Parse the parameter declaration.  */
11587 	  parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
11588 	  if (parm == NULL)
11589 	    parameter_declaration = error_mark_node;
11590 	  else
11591 	    parameter_declaration = grokparm (parm, NULL);
11592 	}
11593       if (seen_open_paren)
11594 	parens.require_close (parser);
11595       else
11596 	{
11597 	  /* If there was no open parenthesis, we are recovering from
11598 	     an error, and we are trying to figure out what mistake
11599 	     the user has made.  */
11600 
11601 	  /* If there is an immediate closing parenthesis, the user
11602 	     probably forgot the opening one (ie, they typed "@catch
11603 	     NSException *e)".  Parse the closing parenthesis and keep
11604 	     going.  */
11605 	  if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
11606 	    c_parser_consume_token (parser);
11607 
11608 	  /* If these is no immediate closing parenthesis, the user
11609 	     probably doesn't know that parenthesis are required at
11610 	     all (ie, they typed "@catch NSException *e").  So, just
11611 	     forget about the closing parenthesis and keep going.  */
11612 	}
11613       objc_begin_catch_clause (parameter_declaration);
11614       if (c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
11615 	c_parser_compound_statement_nostart (parser);
11616       objc_finish_catch_clause ();
11617     }
11618   if (c_parser_next_token_is_keyword (parser, RID_AT_FINALLY))
11619     {
11620       c_parser_consume_token (parser);
11621       location = c_parser_peek_token (parser)->location;
11622       stmt = c_parser_compound_statement (parser);
11623       objc_build_finally_clause (location, stmt);
11624     }
11625   objc_finish_try_stmt ();
11626 }
11627 
11628 /* Parse an objc-synchronized-statement.
11629 
11630    objc-synchronized-statement:
11631      @synchronized ( expression ) compound-statement
11632 */
11633 
11634 static void
c_parser_objc_synchronized_statement(c_parser * parser)11635 c_parser_objc_synchronized_statement (c_parser *parser)
11636 {
11637   location_t loc;
11638   tree expr, stmt;
11639   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNCHRONIZED));
11640   c_parser_consume_token (parser);
11641   loc = c_parser_peek_token (parser)->location;
11642   objc_maybe_warn_exceptions (loc);
11643   matching_parens parens;
11644   if (parens.require_open (parser))
11645     {
11646       struct c_expr ce = c_parser_expression (parser);
11647       ce = convert_lvalue_to_rvalue (loc, ce, false, false);
11648       expr = ce.value;
11649       expr = c_fully_fold (expr, false, NULL);
11650       parens.skip_until_found_close (parser);
11651     }
11652   else
11653     expr = error_mark_node;
11654   stmt = c_parser_compound_statement (parser);
11655   objc_build_synchronized (loc, expr, stmt);
11656 }
11657 
11658 /* Parse an objc-selector; return NULL_TREE without an error if the
11659    next token is not an objc-selector.
11660 
11661    objc-selector:
11662      identifier
11663      one of
11664        enum struct union if else while do for switch case default
11665        break continue return goto asm sizeof typeof __alignof
11666        unsigned long const short volatile signed restrict _Complex
11667        in out inout bycopy byref oneway int char float double void _Bool
11668        _Atomic
11669 
11670    ??? Why this selection of keywords but not, for example, storage
11671    class specifiers?  */
11672 
11673 static tree
c_parser_objc_selector(c_parser * parser)11674 c_parser_objc_selector (c_parser *parser)
11675 {
11676   c_token *token = c_parser_peek_token (parser);
11677   tree value = token->value;
11678   if (token->type == CPP_NAME)
11679     {
11680       c_parser_consume_token (parser);
11681       return value;
11682     }
11683   if (token->type != CPP_KEYWORD)
11684     return NULL_TREE;
11685   switch (token->keyword)
11686     {
11687     case RID_ENUM:
11688     case RID_STRUCT:
11689     case RID_UNION:
11690     case RID_IF:
11691     case RID_ELSE:
11692     case RID_WHILE:
11693     case RID_DO:
11694     case RID_FOR:
11695     case RID_SWITCH:
11696     case RID_CASE:
11697     case RID_DEFAULT:
11698     case RID_BREAK:
11699     case RID_CONTINUE:
11700     case RID_RETURN:
11701     case RID_GOTO:
11702     case RID_ASM:
11703     case RID_SIZEOF:
11704     case RID_TYPEOF:
11705     case RID_ALIGNOF:
11706     case RID_UNSIGNED:
11707     case RID_LONG:
11708     case RID_CONST:
11709     case RID_SHORT:
11710     case RID_VOLATILE:
11711     case RID_SIGNED:
11712     case RID_RESTRICT:
11713     case RID_COMPLEX:
11714     case RID_IN:
11715     case RID_OUT:
11716     case RID_INOUT:
11717     case RID_BYCOPY:
11718     case RID_BYREF:
11719     case RID_ONEWAY:
11720     case RID_INT:
11721     case RID_CHAR:
11722     case RID_FLOAT:
11723     case RID_DOUBLE:
11724     CASE_RID_FLOATN_NX:
11725     case RID_VOID:
11726     case RID_BOOL:
11727     case RID_ATOMIC:
11728     case RID_AUTO_TYPE:
11729     case RID_INT_N_0:
11730     case RID_INT_N_1:
11731     case RID_INT_N_2:
11732     case RID_INT_N_3:
11733       c_parser_consume_token (parser);
11734       return value;
11735     default:
11736       return NULL_TREE;
11737     }
11738 }
11739 
11740 /* Parse an objc-selector-arg.
11741 
11742    objc-selector-arg:
11743      objc-selector
11744      objc-keywordname-list
11745 
11746    objc-keywordname-list:
11747      objc-keywordname
11748      objc-keywordname-list objc-keywordname
11749 
11750    objc-keywordname:
11751      objc-selector :
11752      :
11753 */
11754 
11755 static tree
c_parser_objc_selector_arg(c_parser * parser)11756 c_parser_objc_selector_arg (c_parser *parser)
11757 {
11758   tree sel = c_parser_objc_selector (parser);
11759   tree list = NULL_TREE;
11760   if (sel
11761       && c_parser_next_token_is_not (parser, CPP_COLON)
11762       && c_parser_next_token_is_not (parser, CPP_SCOPE))
11763     return sel;
11764   while (true)
11765     {
11766       if (c_parser_next_token_is (parser, CPP_SCOPE))
11767 	{
11768 	  c_parser_consume_token (parser);
11769 	  list = chainon (list, build_tree_list (sel, NULL_TREE));
11770 	  list = chainon (list, build_tree_list (NULL_TREE, NULL_TREE));
11771 	}
11772       else
11773 	{
11774 	  if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11775 	    return list;
11776 	  list = chainon (list, build_tree_list (sel, NULL_TREE));
11777 	}
11778       sel = c_parser_objc_selector (parser);
11779       if (!sel
11780 	  && c_parser_next_token_is_not (parser, CPP_COLON)
11781 	  && c_parser_next_token_is_not (parser, CPP_SCOPE))
11782 	break;
11783     }
11784   return list;
11785 }
11786 
11787 /* Parse an objc-receiver.
11788 
11789    objc-receiver:
11790      expression
11791      class-name
11792      type-name
11793 */
11794 
11795 static tree
c_parser_objc_receiver(c_parser * parser)11796 c_parser_objc_receiver (c_parser *parser)
11797 {
11798   location_t loc = c_parser_peek_token (parser)->location;
11799 
11800   if (c_parser_peek_token (parser)->type == CPP_NAME
11801       && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
11802 	  || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
11803     {
11804       tree id = c_parser_peek_token (parser)->value;
11805       c_parser_consume_token (parser);
11806       return objc_get_class_reference (id);
11807     }
11808   struct c_expr ce = c_parser_expression (parser);
11809   ce = convert_lvalue_to_rvalue (loc, ce, false, false);
11810   return c_fully_fold (ce.value, false, NULL);
11811 }
11812 
11813 /* Parse objc-message-args.
11814 
11815    objc-message-args:
11816      objc-selector
11817      objc-keywordarg-list
11818 
11819    objc-keywordarg-list:
11820      objc-keywordarg
11821      objc-keywordarg-list objc-keywordarg
11822 
11823    objc-keywordarg:
11824      objc-selector : objc-keywordexpr
11825      : objc-keywordexpr
11826 */
11827 
11828 static tree
c_parser_objc_message_args(c_parser * parser)11829 c_parser_objc_message_args (c_parser *parser)
11830 {
11831   tree sel = c_parser_objc_selector (parser);
11832   tree list = NULL_TREE;
11833   if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
11834     return sel;
11835   while (true)
11836     {
11837       tree keywordexpr;
11838       if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11839 	return error_mark_node;
11840       keywordexpr = c_parser_objc_keywordexpr (parser);
11841       list = chainon (list, build_tree_list (sel, keywordexpr));
11842       sel = c_parser_objc_selector (parser);
11843       if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
11844 	break;
11845     }
11846   return list;
11847 }
11848 
11849 /* Parse an objc-keywordexpr.
11850 
11851    objc-keywordexpr:
11852      nonempty-expr-list
11853 */
11854 
11855 static tree
c_parser_objc_keywordexpr(c_parser * parser)11856 c_parser_objc_keywordexpr (c_parser *parser)
11857 {
11858   tree ret;
11859   vec<tree, va_gc> *expr_list = c_parser_expr_list (parser, true, true,
11860 						NULL, NULL, NULL, NULL);
11861   if (vec_safe_length (expr_list) == 1)
11862     {
11863       /* Just return the expression, remove a level of
11864 	 indirection.  */
11865       ret = (*expr_list)[0];
11866     }
11867   else
11868     {
11869       /* We have a comma expression, we will collapse later.  */
11870       ret = build_tree_list_vec (expr_list);
11871     }
11872   release_tree_vector (expr_list);
11873   return ret;
11874 }
11875 
11876 /* A check, needed in several places, that ObjC interface, implementation or
11877    method definitions are not prefixed by incorrect items.  */
11878 static bool
c_parser_objc_diagnose_bad_element_prefix(c_parser * parser,struct c_declspecs * specs)11879 c_parser_objc_diagnose_bad_element_prefix (c_parser *parser,
11880 					   struct c_declspecs *specs)
11881 {
11882   if (!specs->declspecs_seen_p || specs->non_sc_seen_p
11883       || specs->typespec_kind != ctsk_none)
11884     {
11885       c_parser_error (parser,
11886       		      "no type or storage class may be specified here,");
11887       c_parser_skip_to_end_of_block_or_statement (parser);
11888       return true;
11889     }
11890   return false;
11891 }
11892 
11893 /* Parse an Objective-C @property declaration.  The syntax is:
11894 
11895    objc-property-declaration:
11896      '@property' objc-property-attributes[opt] struct-declaration ;
11897 
11898    objc-property-attributes:
11899     '(' objc-property-attribute-list ')'
11900 
11901    objc-property-attribute-list:
11902      objc-property-attribute
11903      objc-property-attribute-list, objc-property-attribute
11904 
11905    objc-property-attribute
11906      'getter' = identifier
11907      'setter' = identifier
11908      'readonly'
11909      'readwrite'
11910      'assign'
11911      'retain'
11912      'copy'
11913      'nonatomic'
11914 
11915   For example:
11916     @property NSString *name;
11917     @property (readonly) id object;
11918     @property (retain, nonatomic, getter=getTheName) id name;
11919     @property int a, b, c;
11920 
11921   PS: This function is identical to cp_parser_objc_at_propery_declaration
11922   for C++.  Keep them in sync.  */
11923 static void
c_parser_objc_at_property_declaration(c_parser * parser)11924 c_parser_objc_at_property_declaration (c_parser *parser)
11925 {
11926   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY));
11927   location_t loc = c_parser_peek_token (parser)->location;
11928   c_parser_consume_token (parser);  /* Eat '@property'.  */
11929 
11930   /* Parse the optional attribute list.
11931 
11932      A list of parsed, but not verified, attributes.  */
11933   vec<property_attribute_info *> prop_attr_list = vNULL;
11934 
11935   bool syntax_error = false;
11936   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11937     {
11938       matching_parens parens;
11939 
11940       location_t attr_start = c_parser_peek_token (parser)->location;
11941       /* Eat the '(' */
11942       parens.consume_open (parser);
11943 
11944       /* Property attribute keywords are valid now.  */
11945       parser->objc_property_attr_context = true;
11946 
11947       /* Allow @property (), with a warning.  */
11948       location_t attr_end = c_parser_peek_token (parser)->location;
11949 
11950       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
11951 	{
11952 	  location_t attr_comb = make_location (attr_end, attr_start, attr_end);
11953 	  warning_at (attr_comb, OPT_Wattributes,
11954 		      "empty property attribute list");
11955 	}
11956       else
11957 	while (true)
11958 	  {
11959 	    c_token *token = c_parser_peek_token (parser);
11960 	    attr_start = token->location;
11961 	    attr_end = get_finish (token->location);
11962 	    location_t attr_comb = make_location (attr_start, attr_start,
11963 						  attr_end);
11964 
11965 	    if (token->type == CPP_CLOSE_PAREN || token->type == CPP_COMMA)
11966 	      {
11967 		warning_at (attr_comb, OPT_Wattributes,
11968 			    "missing property attribute");
11969 		if (token->type == CPP_CLOSE_PAREN)
11970 		  break;
11971 		c_parser_consume_token (parser);
11972 		continue;
11973 	      }
11974 
11975 	    tree attr_name = NULL_TREE;
11976 	    enum rid keyword = RID_MAX; /* Not a valid property attribute.  */
11977 	    bool add_at = false;
11978 	    if (token->type == CPP_KEYWORD)
11979 	      {
11980 		keyword = token->keyword;
11981 		if (OBJC_IS_AT_KEYWORD (keyword))
11982 		  {
11983 		    /* For '@' keywords the token value has the keyword,
11984 		       prepend the '@' for diagnostics.  */
11985 		    attr_name = token->value;
11986 		    add_at = true;
11987 		  }
11988 		else
11989 		  attr_name = ridpointers[(int)keyword];
11990 	      }
11991 	    else if (token->type == CPP_NAME)
11992 	      attr_name = token->value;
11993 	    c_parser_consume_token (parser);
11994 
11995 	    enum objc_property_attribute_kind prop_kind
11996 	      = objc_prop_attr_kind_for_rid (keyword);
11997 	    property_attribute_info *prop
11998 	      = new property_attribute_info (attr_name, attr_comb, prop_kind);
11999 	    prop_attr_list.safe_push (prop);
12000 
12001 	    tree meth_name;
12002 	    switch (prop->prop_kind)
12003 	      {
12004 	      default: break;
12005 	      case OBJC_PROPERTY_ATTR_UNKNOWN:
12006 		if (attr_name)
12007 		  error_at (attr_comb, "unknown property attribute %<%s%s%>",
12008 			    add_at ? "@" : "", IDENTIFIER_POINTER (attr_name));
12009 		else
12010 		  error_at (attr_comb, "unknown property attribute");
12011 		prop->parse_error = syntax_error = true;
12012 		break;
12013 
12014 	      case OBJC_PROPERTY_ATTR_GETTER:
12015 	      case OBJC_PROPERTY_ATTR_SETTER:
12016 		if (c_parser_next_token_is_not (parser, CPP_EQ))
12017 		  {
12018 		    attr_comb = make_location (attr_end, attr_start, attr_end);
12019 		    error_at (attr_comb, "expected %<=%> after Objective-C %qE",
12020 			      attr_name);
12021 		    prop->parse_error = syntax_error = true;
12022 		    break;
12023 		  }
12024 		token = c_parser_peek_token (parser);
12025 		attr_end = token->location;
12026 		c_parser_consume_token (parser); /* eat the = */
12027 		if (c_parser_next_token_is_not (parser, CPP_NAME))
12028 		  {
12029 		    attr_comb = make_location (attr_end, attr_start, attr_end);
12030 		    error_at (attr_comb, "expected %qE selector name",
12031 			      attr_name);
12032 		    prop->parse_error = syntax_error = true;
12033 		    break;
12034 		  }
12035 		/* Get the end of the method name, and consume the name.  */
12036 		token = c_parser_peek_token (parser);
12037 		attr_end = get_finish (token->location);
12038 		meth_name = token->value;
12039 		c_parser_consume_token (parser);
12040 		if (prop->prop_kind == OBJC_PROPERTY_ATTR_SETTER)
12041 		  {
12042 		    if (c_parser_next_token_is_not (parser, CPP_COLON))
12043 		      {
12044 			attr_comb = make_location (attr_end, attr_start,
12045 						   attr_end);
12046 			error_at (attr_comb, "setter method names must"
12047 				  " terminate with %<:%>");
12048 			prop->parse_error = syntax_error = true;
12049 		      }
12050 		    else
12051 		      {
12052 			attr_end = get_finish (c_parser_peek_token
12053 					       (parser)->location);
12054 			c_parser_consume_token (parser);
12055 		      }
12056 		    attr_comb = make_location (attr_start, attr_start,
12057 					       attr_end);
12058 		  }
12059 		else
12060 		  attr_comb = make_location (attr_start, attr_start,
12061 					       attr_end);
12062 		prop->ident = meth_name;
12063 		/* Updated location including all that was successfully
12064 		   parsed.  */
12065 		prop->prop_loc = attr_comb;
12066 		break;
12067 	    }
12068 
12069 	  /* If we see a comma here, then keep going - even if we already
12070 	     saw a syntax error.  For simple mistakes e.g. (asign, getter=x)
12071 	     this makes a more useful output and avoid spurious warnings about
12072 	     missing attributes that are, in fact, specified after the one with
12073 	     the syntax error.  */
12074 	  if (c_parser_next_token_is (parser, CPP_COMMA))
12075 	    c_parser_consume_token (parser);
12076 	  else
12077 	    break;
12078 	}
12079       parser->objc_property_attr_context = false;
12080 
12081       if (syntax_error && c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
12082 	/* We don't really want to chew the whole of the file looking for a
12083 	   matching closing parenthesis, so we will try to read the decl and
12084 	   let the error handling for that close out the statement.  */
12085 	;
12086       else
12087 	syntax_error = false, parens.skip_until_found_close (parser);
12088     }
12089 
12090   /* 'properties' is the list of properties that we read.  Usually a
12091      single one, but maybe more (eg, in "@property int a, b, c;" there
12092      are three).  */
12093   tree properties = c_parser_struct_declaration (parser);
12094 
12095   if (properties == error_mark_node)
12096     c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12097   else
12098     {
12099       if (properties == NULL_TREE)
12100 	c_parser_error (parser, "expected identifier");
12101       else
12102 	{
12103 	  /* Comma-separated properties are chained together in reverse order;
12104 	     add them one by one.  */
12105 	  properties = nreverse (properties);
12106 	  for (; properties; properties = TREE_CHAIN (properties))
12107 	    objc_add_property_declaration (loc, copy_node (properties),
12108 					    prop_attr_list);
12109 	}
12110       c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12111     }
12112 
12113   while (!prop_attr_list.is_empty())
12114     delete prop_attr_list.pop ();
12115   prop_attr_list.release ();
12116   parser->error = false;
12117 }
12118 
12119 /* Parse an Objective-C @synthesize declaration.  The syntax is:
12120 
12121    objc-synthesize-declaration:
12122      @synthesize objc-synthesize-identifier-list ;
12123 
12124    objc-synthesize-identifier-list:
12125      objc-synthesize-identifier
12126      objc-synthesize-identifier-list, objc-synthesize-identifier
12127 
12128    objc-synthesize-identifier
12129      identifier
12130      identifier = identifier
12131 
12132   For example:
12133     @synthesize MyProperty;
12134     @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
12135 
12136   PS: This function is identical to cp_parser_objc_at_synthesize_declaration
12137   for C++.  Keep them in sync.
12138 */
12139 static void
c_parser_objc_at_synthesize_declaration(c_parser * parser)12140 c_parser_objc_at_synthesize_declaration (c_parser *parser)
12141 {
12142   tree list = NULL_TREE;
12143   location_t loc;
12144   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNTHESIZE));
12145   loc = c_parser_peek_token (parser)->location;
12146 
12147   c_parser_consume_token (parser);
12148   while (true)
12149     {
12150       tree property, ivar;
12151       if (c_parser_next_token_is_not (parser, CPP_NAME))
12152 	{
12153 	  c_parser_error (parser, "expected identifier");
12154 	  c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12155 	  /* Once we find the semicolon, we can resume normal parsing.
12156 	     We have to reset parser->error manually because
12157 	     c_parser_skip_until_found() won't reset it for us if the
12158 	     next token is precisely a semicolon.  */
12159 	  parser->error = false;
12160 	  return;
12161 	}
12162       property = c_parser_peek_token (parser)->value;
12163       c_parser_consume_token (parser);
12164       if (c_parser_next_token_is (parser, CPP_EQ))
12165 	{
12166 	  c_parser_consume_token (parser);
12167 	  if (c_parser_next_token_is_not (parser, CPP_NAME))
12168 	    {
12169 	      c_parser_error (parser, "expected identifier");
12170 	      c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12171 	      parser->error = false;
12172 	      return;
12173 	    }
12174 	  ivar = c_parser_peek_token (parser)->value;
12175 	  c_parser_consume_token (parser);
12176 	}
12177       else
12178 	ivar = NULL_TREE;
12179       list = chainon (list, build_tree_list (ivar, property));
12180       if (c_parser_next_token_is (parser, CPP_COMMA))
12181 	c_parser_consume_token (parser);
12182       else
12183 	break;
12184     }
12185   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12186   objc_add_synthesize_declaration (loc, list);
12187 }
12188 
12189 /* Parse an Objective-C @dynamic declaration.  The syntax is:
12190 
12191    objc-dynamic-declaration:
12192      @dynamic identifier-list ;
12193 
12194    For example:
12195      @dynamic MyProperty;
12196      @dynamic MyProperty, AnotherProperty;
12197 
12198   PS: This function is identical to cp_parser_objc_at_dynamic_declaration
12199   for C++.  Keep them in sync.
12200 */
12201 static void
c_parser_objc_at_dynamic_declaration(c_parser * parser)12202 c_parser_objc_at_dynamic_declaration (c_parser *parser)
12203 {
12204   tree list = NULL_TREE;
12205   location_t loc;
12206   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_DYNAMIC));
12207   loc = c_parser_peek_token (parser)->location;
12208 
12209   c_parser_consume_token (parser);
12210   while (true)
12211     {
12212       tree property;
12213       if (c_parser_next_token_is_not (parser, CPP_NAME))
12214 	{
12215 	  c_parser_error (parser, "expected identifier");
12216 	  c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12217 	  parser->error = false;
12218 	  return;
12219 	}
12220       property = c_parser_peek_token (parser)->value;
12221       list = chainon (list, build_tree_list (NULL_TREE, property));
12222       c_parser_consume_token (parser);
12223       if (c_parser_next_token_is (parser, CPP_COMMA))
12224 	c_parser_consume_token (parser);
12225       else
12226 	break;
12227     }
12228   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12229   objc_add_dynamic_declaration (loc, list);
12230 }
12231 
12232 
12233 /* Parse a pragma GCC ivdep.  */
12234 
12235 static bool
c_parse_pragma_ivdep(c_parser * parser)12236 c_parse_pragma_ivdep (c_parser *parser)
12237 {
12238   c_parser_consume_pragma (parser);
12239   c_parser_skip_to_pragma_eol (parser);
12240   return true;
12241 }
12242 
12243 /* Parse a pragma GCC unroll.  */
12244 
12245 static unsigned short
c_parser_pragma_unroll(c_parser * parser)12246 c_parser_pragma_unroll (c_parser *parser)
12247 {
12248   unsigned short unroll;
12249   c_parser_consume_pragma (parser);
12250   location_t location = c_parser_peek_token (parser)->location;
12251   tree expr = c_parser_expr_no_commas (parser, NULL).value;
12252   mark_exp_read (expr);
12253   expr = c_fully_fold (expr, false, NULL);
12254   HOST_WIDE_INT lunroll = 0;
12255   if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
12256       || TREE_CODE (expr) != INTEGER_CST
12257       || (lunroll = tree_to_shwi (expr)) < 0
12258       || lunroll >= USHRT_MAX)
12259     {
12260       error_at (location, "%<#pragma GCC unroll%> requires an"
12261 		" assignment-expression that evaluates to a non-negative"
12262 		" integral constant less than %u", USHRT_MAX);
12263       unroll = 0;
12264     }
12265   else
12266     {
12267       unroll = (unsigned short)lunroll;
12268       if (unroll == 0)
12269 	unroll = 1;
12270     }
12271 
12272   c_parser_skip_to_pragma_eol (parser);
12273   return unroll;
12274 }
12275 
12276 /* Handle pragmas.  Some OpenMP pragmas are associated with, and therefore
12277    should be considered, statements.  ALLOW_STMT is true if we're within
12278    the context of a function and such pragmas are to be allowed.  Returns
12279    true if we actually parsed such a pragma.  */
12280 
12281 static bool
c_parser_pragma(c_parser * parser,enum pragma_context context,bool * if_p)12282 c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p)
12283 {
12284   unsigned int id;
12285   const char *construct = NULL;
12286 
12287   id = c_parser_peek_token (parser)->pragma_kind;
12288   gcc_assert (id != PRAGMA_NONE);
12289 
12290   switch (id)
12291     {
12292     case PRAGMA_OACC_DECLARE:
12293       c_parser_oacc_declare (parser);
12294       return false;
12295 
12296     case PRAGMA_OACC_ENTER_DATA:
12297       if (context != pragma_compound)
12298 	{
12299 	  construct = "acc enter data";
12300 	in_compound:
12301 	  if (context == pragma_stmt)
12302 	    {
12303 	      error_at (c_parser_peek_token (parser)->location,
12304 			"%<#pragma %s%> may only be used in compound "
12305 			"statements", construct);
12306 	      c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12307 	      return false;
12308 	    }
12309 	  goto bad_stmt;
12310 	}
12311       c_parser_oacc_enter_exit_data (parser, true);
12312       return false;
12313 
12314     case PRAGMA_OACC_EXIT_DATA:
12315       if (context != pragma_compound)
12316 	{
12317 	  construct = "acc exit data";
12318 	  goto in_compound;
12319 	}
12320       c_parser_oacc_enter_exit_data (parser, false);
12321       return false;
12322 
12323     case PRAGMA_OACC_ROUTINE:
12324       if (context != pragma_external)
12325 	{
12326 	  error_at (c_parser_peek_token (parser)->location,
12327 		    "%<#pragma acc routine%> must be at file scope");
12328 	  c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12329 	  return false;
12330 	}
12331       c_parser_oacc_routine (parser, context);
12332       return false;
12333 
12334     case PRAGMA_OACC_UPDATE:
12335       if (context != pragma_compound)
12336 	{
12337 	  construct = "acc update";
12338 	  goto in_compound;
12339 	}
12340       c_parser_oacc_update (parser);
12341       return false;
12342 
12343     case PRAGMA_OMP_BARRIER:
12344       if (context != pragma_compound)
12345 	{
12346 	  construct = "omp barrier";
12347 	  goto in_compound;
12348 	}
12349       c_parser_omp_barrier (parser);
12350       return false;
12351 
12352     case PRAGMA_OMP_DEPOBJ:
12353       if (context != pragma_compound)
12354 	{
12355 	  construct = "omp depobj";
12356 	  goto in_compound;
12357 	}
12358       c_parser_omp_depobj (parser);
12359       return false;
12360 
12361     case PRAGMA_OMP_FLUSH:
12362       if (context != pragma_compound)
12363 	{
12364 	  construct = "omp flush";
12365 	  goto in_compound;
12366 	}
12367       c_parser_omp_flush (parser);
12368       return false;
12369 
12370     case PRAGMA_OMP_TASKWAIT:
12371       if (context != pragma_compound)
12372 	{
12373 	  construct = "omp taskwait";
12374 	  goto in_compound;
12375 	}
12376       c_parser_omp_taskwait (parser);
12377       return false;
12378 
12379     case PRAGMA_OMP_TASKYIELD:
12380       if (context != pragma_compound)
12381 	{
12382 	  construct = "omp taskyield";
12383 	  goto in_compound;
12384 	}
12385       c_parser_omp_taskyield (parser);
12386       return false;
12387 
12388     case PRAGMA_OMP_CANCEL:
12389       if (context != pragma_compound)
12390 	{
12391 	  construct = "omp cancel";
12392 	  goto in_compound;
12393 	}
12394       c_parser_omp_cancel (parser);
12395       return false;
12396 
12397     case PRAGMA_OMP_CANCELLATION_POINT:
12398       c_parser_omp_cancellation_point (parser, context);
12399       return false;
12400 
12401     case PRAGMA_OMP_THREADPRIVATE:
12402       c_parser_omp_threadprivate (parser);
12403       return false;
12404 
12405     case PRAGMA_OMP_TARGET:
12406       return c_parser_omp_target (parser, context, if_p);
12407 
12408     case PRAGMA_OMP_END_DECLARE_TARGET:
12409       c_parser_omp_end_declare_target (parser);
12410       return false;
12411 
12412     case PRAGMA_OMP_SCAN:
12413       error_at (c_parser_peek_token (parser)->location,
12414 		"%<#pragma omp scan%> may only be used in "
12415 		"a loop construct with %<inscan%> %<reduction%> clause");
12416       c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12417       return false;
12418 
12419     case PRAGMA_OMP_SECTION:
12420       error_at (c_parser_peek_token (parser)->location,
12421 		"%<#pragma omp section%> may only be used in "
12422 		"%<#pragma omp sections%> construct");
12423       c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12424       return false;
12425 
12426     case PRAGMA_OMP_DECLARE:
12427       c_parser_omp_declare (parser, context);
12428       return false;
12429 
12430     case PRAGMA_OMP_REQUIRES:
12431       if (context != pragma_external)
12432 	{
12433 	  error_at (c_parser_peek_token (parser)->location,
12434 		    "%<#pragma omp requires%> may only be used at file scope");
12435 	  c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12436 	  return false;
12437 	}
12438       c_parser_omp_requires (parser);
12439       return false;
12440 
12441     case PRAGMA_OMP_ORDERED:
12442       return c_parser_omp_ordered (parser, context, if_p);
12443 
12444     case PRAGMA_IVDEP:
12445       {
12446 	const bool ivdep = c_parse_pragma_ivdep (parser);
12447 	unsigned short unroll;
12448 	if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_UNROLL)
12449 	  unroll = c_parser_pragma_unroll (parser);
12450 	else
12451 	  unroll = 0;
12452 	if (!c_parser_next_token_is_keyword (parser, RID_FOR)
12453 	    && !c_parser_next_token_is_keyword (parser, RID_WHILE)
12454 	    && !c_parser_next_token_is_keyword (parser, RID_DO))
12455 	  {
12456 	    c_parser_error (parser, "for, while or do statement expected");
12457 	    return false;
12458 	  }
12459 	if (c_parser_next_token_is_keyword (parser, RID_FOR))
12460 	  c_parser_for_statement (parser, ivdep, unroll, if_p);
12461 	else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
12462 	  c_parser_while_statement (parser, ivdep, unroll, if_p);
12463 	else
12464 	  c_parser_do_statement (parser, ivdep, unroll);
12465       }
12466       return false;
12467 
12468     case PRAGMA_UNROLL:
12469       {
12470 	unsigned short unroll = c_parser_pragma_unroll (parser);
12471 	bool ivdep;
12472 	if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_IVDEP)
12473 	  ivdep = c_parse_pragma_ivdep (parser);
12474 	else
12475 	  ivdep = false;
12476 	if (!c_parser_next_token_is_keyword (parser, RID_FOR)
12477 	    && !c_parser_next_token_is_keyword (parser, RID_WHILE)
12478 	    && !c_parser_next_token_is_keyword (parser, RID_DO))
12479 	  {
12480 	    c_parser_error (parser, "for, while or do statement expected");
12481 	    return false;
12482 	  }
12483 	if (c_parser_next_token_is_keyword (parser, RID_FOR))
12484 	  c_parser_for_statement (parser, ivdep, unroll, if_p);
12485 	else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
12486 	  c_parser_while_statement (parser, ivdep, unroll, if_p);
12487 	else
12488 	  c_parser_do_statement (parser, ivdep, unroll);
12489       }
12490       return false;
12491 
12492     case PRAGMA_GCC_PCH_PREPROCESS:
12493       c_parser_error (parser, "%<#pragma GCC pch_preprocess%> must be first");
12494       c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12495       return false;
12496 
12497     case PRAGMA_OACC_WAIT:
12498       if (context != pragma_compound)
12499 	{
12500 	  construct = "acc wait";
12501 	  goto in_compound;
12502 	}
12503 	/* FALL THROUGH.  */
12504 
12505     default:
12506       if (id < PRAGMA_FIRST_EXTERNAL)
12507 	{
12508 	  if (context != pragma_stmt && context != pragma_compound)
12509 	    {
12510 	    bad_stmt:
12511 	      c_parser_error (parser, "expected declaration specifiers");
12512 	      c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12513 	      return false;
12514 	    }
12515 	  c_parser_omp_construct (parser, if_p);
12516 	  return true;
12517 	}
12518       break;
12519     }
12520 
12521   c_parser_consume_pragma (parser);
12522   c_invoke_pragma_handler (id);
12523 
12524   /* Skip to EOL, but suppress any error message.  Those will have been
12525      generated by the handler routine through calling error, as opposed
12526      to calling c_parser_error.  */
12527   parser->error = true;
12528   c_parser_skip_to_pragma_eol (parser);
12529 
12530   return false;
12531 }
12532 
12533 /* The interface the pragma parsers have to the lexer.  */
12534 
12535 enum cpp_ttype
pragma_lex(tree * value,location_t * loc)12536 pragma_lex (tree *value, location_t *loc)
12537 {
12538   c_token *tok = c_parser_peek_token (the_parser);
12539   enum cpp_ttype ret = tok->type;
12540 
12541   *value = tok->value;
12542   if (loc)
12543     *loc = tok->location;
12544 
12545   if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF)
12546     ret = CPP_EOF;
12547   else if (ret == CPP_STRING)
12548     *value = c_parser_string_literal (the_parser, false, false).value;
12549   else
12550     {
12551       if (ret == CPP_KEYWORD)
12552 	ret = CPP_NAME;
12553       c_parser_consume_token (the_parser);
12554     }
12555 
12556   return ret;
12557 }
12558 
12559 static void
c_parser_pragma_pch_preprocess(c_parser * parser)12560 c_parser_pragma_pch_preprocess (c_parser *parser)
12561 {
12562   tree name = NULL;
12563 
12564   parser->lex_joined_string = true;
12565   c_parser_consume_pragma (parser);
12566   if (c_parser_next_token_is (parser, CPP_STRING))
12567     {
12568       name = c_parser_peek_token (parser)->value;
12569       c_parser_consume_token (parser);
12570     }
12571   else
12572     c_parser_error (parser, "expected string literal");
12573   c_parser_skip_to_pragma_eol (parser);
12574   parser->lex_joined_string = false;
12575 
12576   if (name)
12577     c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name));
12578 }
12579 
12580 /* OpenACC and OpenMP parsing routines.  */
12581 
12582 /* Returns name of the next clause.
12583    If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
12584    the token is not consumed.  Otherwise appropriate pragma_omp_clause is
12585    returned and the token is consumed.  */
12586 
12587 static pragma_omp_clause
c_parser_omp_clause_name(c_parser * parser)12588 c_parser_omp_clause_name (c_parser *parser)
12589 {
12590   pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;
12591 
12592   if (c_parser_next_token_is_keyword (parser, RID_AUTO))
12593     result = PRAGMA_OACC_CLAUSE_AUTO;
12594   else if (c_parser_next_token_is_keyword (parser, RID_IF))
12595     result = PRAGMA_OMP_CLAUSE_IF;
12596   else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
12597     result = PRAGMA_OMP_CLAUSE_DEFAULT;
12598   else if (c_parser_next_token_is_keyword (parser, RID_FOR))
12599     result = PRAGMA_OMP_CLAUSE_FOR;
12600   else if (c_parser_next_token_is (parser, CPP_NAME))
12601     {
12602       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
12603 
12604       switch (p[0])
12605 	{
12606 	case 'a':
12607 	  if (!strcmp ("aligned", p))
12608 	    result = PRAGMA_OMP_CLAUSE_ALIGNED;
12609 	  else if (!strcmp ("allocate", p))
12610 	    result = PRAGMA_OMP_CLAUSE_ALLOCATE;
12611 	  else if (!strcmp ("async", p))
12612 	    result = PRAGMA_OACC_CLAUSE_ASYNC;
12613 	  else if (!strcmp ("attach", p))
12614 	    result = PRAGMA_OACC_CLAUSE_ATTACH;
12615 	  break;
12616 	case 'b':
12617 	  if (!strcmp ("bind", p))
12618 	    result = PRAGMA_OMP_CLAUSE_BIND;
12619 	  break;
12620 	case 'c':
12621 	  if (!strcmp ("collapse", p))
12622 	    result = PRAGMA_OMP_CLAUSE_COLLAPSE;
12623 	  else if (!strcmp ("copy", p))
12624 	    result = PRAGMA_OACC_CLAUSE_COPY;
12625 	  else if (!strcmp ("copyin", p))
12626 	    result = PRAGMA_OMP_CLAUSE_COPYIN;
12627 	  else if (!strcmp ("copyout", p))
12628 	    result = PRAGMA_OACC_CLAUSE_COPYOUT;
12629           else if (!strcmp ("copyprivate", p))
12630 	    result = PRAGMA_OMP_CLAUSE_COPYPRIVATE;
12631 	  else if (!strcmp ("create", p))
12632 	    result = PRAGMA_OACC_CLAUSE_CREATE;
12633 	  break;
12634 	case 'd':
12635 	  if (!strcmp ("defaultmap", p))
12636 	    result = PRAGMA_OMP_CLAUSE_DEFAULTMAP;
12637 	  else if (!strcmp ("delete", p))
12638 	    result = PRAGMA_OACC_CLAUSE_DELETE;
12639 	  else if (!strcmp ("depend", p))
12640 	    result = PRAGMA_OMP_CLAUSE_DEPEND;
12641 	  else if (!strcmp ("detach", p))
12642 	    result = PRAGMA_OACC_CLAUSE_DETACH;
12643 	  else if (!strcmp ("device", p))
12644 	    result = PRAGMA_OMP_CLAUSE_DEVICE;
12645 	  else if (!strcmp ("deviceptr", p))
12646 	    result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
12647 	  else if (!strcmp ("device_resident", p))
12648 	    result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
12649 	  else if (!strcmp ("device_type", p))
12650 	    result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
12651 	  else if (!strcmp ("dist_schedule", p))
12652 	    result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
12653 	  break;
12654 	case 'f':
12655 	  if (!strcmp ("final", p))
12656 	    result = PRAGMA_OMP_CLAUSE_FINAL;
12657 	  else if (!strcmp ("finalize", p))
12658 	    result = PRAGMA_OACC_CLAUSE_FINALIZE;
12659 	  else if (!strcmp ("firstprivate", p))
12660 	    result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
12661 	  else if (!strcmp ("from", p))
12662 	    result = PRAGMA_OMP_CLAUSE_FROM;
12663 	  break;
12664 	case 'g':
12665 	  if (!strcmp ("gang", p))
12666 	    result = PRAGMA_OACC_CLAUSE_GANG;
12667 	  else if (!strcmp ("grainsize", p))
12668 	    result = PRAGMA_OMP_CLAUSE_GRAINSIZE;
12669 	  break;
12670 	case 'h':
12671 	  if (!strcmp ("hint", p))
12672 	    result = PRAGMA_OMP_CLAUSE_HINT;
12673 	  else if (!strcmp ("host", p))
12674 	    result = PRAGMA_OACC_CLAUSE_HOST;
12675 	  break;
12676 	case 'i':
12677 	  if (!strcmp ("if_present", p))
12678 	    result = PRAGMA_OACC_CLAUSE_IF_PRESENT;
12679 	  else if (!strcmp ("in_reduction", p))
12680 	    result = PRAGMA_OMP_CLAUSE_IN_REDUCTION;
12681 	  else if (!strcmp ("inbranch", p))
12682 	    result = PRAGMA_OMP_CLAUSE_INBRANCH;
12683 	  else if (!strcmp ("independent", p))
12684 	    result = PRAGMA_OACC_CLAUSE_INDEPENDENT;
12685 	  else if (!strcmp ("is_device_ptr", p))
12686 	    result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR;
12687 	  break;
12688 	case 'l':
12689 	  if (!strcmp ("lastprivate", p))
12690 	    result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
12691 	  else if (!strcmp ("linear", p))
12692 	    result = PRAGMA_OMP_CLAUSE_LINEAR;
12693 	  else if (!strcmp ("link", p))
12694 	    result = PRAGMA_OMP_CLAUSE_LINK;
12695 	  break;
12696 	case 'm':
12697 	  if (!strcmp ("map", p))
12698 	    result = PRAGMA_OMP_CLAUSE_MAP;
12699 	  else if (!strcmp ("mergeable", p))
12700 	    result = PRAGMA_OMP_CLAUSE_MERGEABLE;
12701 	  break;
12702 	case 'n':
12703 	  if (!strcmp ("no_create", p))
12704 	    result = PRAGMA_OACC_CLAUSE_NO_CREATE;
12705 	  else if (!strcmp ("nogroup", p))
12706 	    result = PRAGMA_OMP_CLAUSE_NOGROUP;
12707 	  else if (!strcmp ("nontemporal", p))
12708 	    result = PRAGMA_OMP_CLAUSE_NONTEMPORAL;
12709 	  else if (!strcmp ("notinbranch", p))
12710 	    result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
12711 	  else if (!strcmp ("nowait", p))
12712 	    result = PRAGMA_OMP_CLAUSE_NOWAIT;
12713 	  else if (!strcmp ("num_gangs", p))
12714 	    result = PRAGMA_OACC_CLAUSE_NUM_GANGS;
12715 	  else if (!strcmp ("num_tasks", p))
12716 	    result = PRAGMA_OMP_CLAUSE_NUM_TASKS;
12717 	  else if (!strcmp ("num_teams", p))
12718 	    result = PRAGMA_OMP_CLAUSE_NUM_TEAMS;
12719 	  else if (!strcmp ("num_threads", p))
12720 	    result = PRAGMA_OMP_CLAUSE_NUM_THREADS;
12721 	  else if (!strcmp ("num_workers", p))
12722 	    result = PRAGMA_OACC_CLAUSE_NUM_WORKERS;
12723 	  break;
12724 	case 'o':
12725 	  if (!strcmp ("ordered", p))
12726 	    result = PRAGMA_OMP_CLAUSE_ORDERED;
12727 	  else if (!strcmp ("order", p))
12728 	    result = PRAGMA_OMP_CLAUSE_ORDER;
12729 	  break;
12730 	case 'p':
12731 	  if (!strcmp ("parallel", p))
12732 	    result = PRAGMA_OMP_CLAUSE_PARALLEL;
12733 	  else if (!strcmp ("present", p))
12734 	    result = PRAGMA_OACC_CLAUSE_PRESENT;
12735 	  /* As of OpenACC 2.5, these are now aliases of the non-present_or
12736 	     clauses.  */
12737 	  else if (!strcmp ("present_or_copy", p)
12738 		   || !strcmp ("pcopy", p))
12739 	    result = PRAGMA_OACC_CLAUSE_COPY;
12740 	  else if (!strcmp ("present_or_copyin", p)
12741 		   || !strcmp ("pcopyin", p))
12742 	    result = PRAGMA_OACC_CLAUSE_COPYIN;
12743 	  else if (!strcmp ("present_or_copyout", p)
12744 		   || !strcmp ("pcopyout", p))
12745 	    result = PRAGMA_OACC_CLAUSE_COPYOUT;
12746 	  else if (!strcmp ("present_or_create", p)
12747 		   || !strcmp ("pcreate", p))
12748 	    result = PRAGMA_OACC_CLAUSE_CREATE;
12749 	  else if (!strcmp ("priority", p))
12750 	    result = PRAGMA_OMP_CLAUSE_PRIORITY;
12751 	  else if (!strcmp ("private", p))
12752 	    result = PRAGMA_OMP_CLAUSE_PRIVATE;
12753 	  else if (!strcmp ("proc_bind", p))
12754 	    result = PRAGMA_OMP_CLAUSE_PROC_BIND;
12755 	  break;
12756 	case 'r':
12757 	  if (!strcmp ("reduction", p))
12758 	    result = PRAGMA_OMP_CLAUSE_REDUCTION;
12759 	  break;
12760 	case 's':
12761 	  if (!strcmp ("safelen", p))
12762 	    result = PRAGMA_OMP_CLAUSE_SAFELEN;
12763 	  else if (!strcmp ("schedule", p))
12764 	    result = PRAGMA_OMP_CLAUSE_SCHEDULE;
12765 	  else if (!strcmp ("sections", p))
12766 	    result = PRAGMA_OMP_CLAUSE_SECTIONS;
12767 	  else if (!strcmp ("self", p)) /* "self" is a synonym for "host".  */
12768 	    result = PRAGMA_OACC_CLAUSE_HOST;
12769 	  else if (!strcmp ("seq", p))
12770 	    result = PRAGMA_OACC_CLAUSE_SEQ;
12771 	  else if (!strcmp ("shared", p))
12772 	    result = PRAGMA_OMP_CLAUSE_SHARED;
12773 	  else if (!strcmp ("simd", p))
12774 	    result = PRAGMA_OMP_CLAUSE_SIMD;
12775 	  else if (!strcmp ("simdlen", p))
12776 	    result = PRAGMA_OMP_CLAUSE_SIMDLEN;
12777 	  break;
12778 	case 't':
12779 	  if (!strcmp ("task_reduction", p))
12780 	    result = PRAGMA_OMP_CLAUSE_TASK_REDUCTION;
12781 	  else if (!strcmp ("taskgroup", p))
12782 	    result = PRAGMA_OMP_CLAUSE_TASKGROUP;
12783 	  else if (!strcmp ("thread_limit", p))
12784 	    result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT;
12785 	  else if (!strcmp ("threads", p))
12786 	    result = PRAGMA_OMP_CLAUSE_THREADS;
12787 	  else if (!strcmp ("tile", p))
12788 	    result = PRAGMA_OACC_CLAUSE_TILE;
12789 	  else if (!strcmp ("to", p))
12790 	    result = PRAGMA_OMP_CLAUSE_TO;
12791 	  break;
12792 	case 'u':
12793 	  if (!strcmp ("uniform", p))
12794 	    result = PRAGMA_OMP_CLAUSE_UNIFORM;
12795 	  else if (!strcmp ("untied", p))
12796 	    result = PRAGMA_OMP_CLAUSE_UNTIED;
12797 	  else if (!strcmp ("use_device", p))
12798 	    result = PRAGMA_OACC_CLAUSE_USE_DEVICE;
12799 	  else if (!strcmp ("use_device_addr", p))
12800 	    result = PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR;
12801 	  else if (!strcmp ("use_device_ptr", p))
12802 	    result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR;
12803 	  break;
12804 	case 'v':
12805 	  if (!strcmp ("vector", p))
12806 	    result = PRAGMA_OACC_CLAUSE_VECTOR;
12807 	  else if (!strcmp ("vector_length", p))
12808 	    result = PRAGMA_OACC_CLAUSE_VECTOR_LENGTH;
12809 	  break;
12810 	case 'w':
12811 	  if (!strcmp ("wait", p))
12812 	    result = PRAGMA_OACC_CLAUSE_WAIT;
12813 	  else if (!strcmp ("worker", p))
12814 	    result = PRAGMA_OACC_CLAUSE_WORKER;
12815 	  break;
12816 	}
12817     }
12818 
12819   if (result != PRAGMA_OMP_CLAUSE_NONE)
12820     c_parser_consume_token (parser);
12821 
12822   return result;
12823 }
12824 
12825 /* Validate that a clause of the given type does not already exist.  */
12826 
12827 static void
check_no_duplicate_clause(tree clauses,enum omp_clause_code code,const char * name)12828 check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
12829 			   const char *name)
12830 {
12831   if (tree c = omp_find_clause (clauses, code))
12832     error_at (OMP_CLAUSE_LOCATION (c), "too many %qs clauses", name);
12833 }
12834 
12835 /* OpenACC 2.0
12836    Parse wait clause or wait directive parameters.  */
12837 
12838 static tree
c_parser_oacc_wait_list(c_parser * parser,location_t clause_loc,tree list)12839 c_parser_oacc_wait_list (c_parser *parser, location_t clause_loc, tree list)
12840 {
12841   vec<tree, va_gc> *args;
12842   tree t, args_tree;
12843 
12844   matching_parens parens;
12845   if (!parens.require_open (parser))
12846     return list;
12847 
12848   args = c_parser_expr_list (parser, false, true, NULL, NULL, NULL, NULL);
12849   args_tree = build_tree_list_vec (args);
12850 
12851   for (t = args_tree; t; t = TREE_CHAIN (t))
12852     {
12853       tree targ = TREE_VALUE (t);
12854 
12855       if (targ != error_mark_node)
12856 	{
12857 	  if (!INTEGRAL_TYPE_P (TREE_TYPE (targ)))
12858 	    {
12859 	      c_parser_error (parser, "expression must be integral");
12860 	      targ = error_mark_node;
12861 	    }
12862 	  else
12863 	    {
12864 	      tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
12865 
12866 	      OMP_CLAUSE_DECL (c) = targ;
12867 	      OMP_CLAUSE_CHAIN (c) = list;
12868 	      list = c;
12869 	    }
12870 	}
12871     }
12872 
12873   release_tree_vector (args);
12874   parens.require_close (parser);
12875   return list;
12876 }
12877 
12878 /* OpenACC 2.0, OpenMP 2.5:
12879    variable-list:
12880      identifier
12881      variable-list , identifier
12882 
12883    If KIND is nonzero, create the appropriate node and install the
12884    decl in OMP_CLAUSE_DECL and add the node to the head of the list.
12885    If KIND is nonzero, CLAUSE_LOC is the location of the clause.
12886 
12887    If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
12888    return the list created.
12889 
12890    The optional ALLOW_DEREF argument is true if list items can use the deref
12891    (->) operator.  */
12892 
12893 static tree
12894 c_parser_omp_variable_list (c_parser *parser,
12895 			    location_t clause_loc,
12896 			    enum omp_clause_code kind, tree list,
12897 			    bool allow_deref = false)
12898 {
12899   auto_vec<c_token> tokens;
12900   unsigned int tokens_avail = 0;
12901   bool first = true;
12902 
12903   while (1)
12904     {
12905       bool array_section_p = false;
12906       if (kind == OMP_CLAUSE_DEPEND)
12907 	{
12908 	  if (c_parser_next_token_is_not (parser, CPP_NAME)
12909 	      || c_parser_peek_token (parser)->id_kind != C_ID_ID)
12910 	    {
12911 	      struct c_expr expr = c_parser_expr_no_commas (parser, NULL);
12912 	      if (expr.value != error_mark_node)
12913 		{
12914 		  tree u = build_omp_clause (clause_loc, kind);
12915 		  OMP_CLAUSE_DECL (u) = expr.value;
12916 		  OMP_CLAUSE_CHAIN (u) = list;
12917 		  list = u;
12918 		}
12919 
12920 	      if (c_parser_next_token_is_not (parser, CPP_COMMA))
12921 		break;
12922 
12923 	      c_parser_consume_token (parser);
12924 	      first = false;
12925 	      continue;
12926 	    }
12927 
12928 	  tokens.truncate (0);
12929 	  unsigned int nesting_depth = 0;
12930 	  while (1)
12931 	    {
12932 	      c_token *token = c_parser_peek_token (parser);
12933 	      switch (token->type)
12934 		{
12935 		case CPP_EOF:
12936 		case CPP_PRAGMA_EOL:
12937 		  break;
12938 		case CPP_OPEN_BRACE:
12939 		case CPP_OPEN_PAREN:
12940 		case CPP_OPEN_SQUARE:
12941 		  ++nesting_depth;
12942 		  goto add;
12943 		case CPP_CLOSE_BRACE:
12944 		case CPP_CLOSE_PAREN:
12945 		case CPP_CLOSE_SQUARE:
12946 		  if (nesting_depth-- == 0)
12947 		    break;
12948 		  goto add;
12949 		case CPP_COMMA:
12950 		  if (nesting_depth == 0)
12951 		    break;
12952 		  goto add;
12953 		default:
12954 		add:
12955 		  tokens.safe_push (*token);
12956 		  c_parser_consume_token (parser);
12957 		  continue;
12958 		}
12959 	      break;
12960 	    }
12961 
12962 	  /* Make sure nothing tries to read past the end of the tokens.  */
12963 	  c_token eof_token;
12964 	  memset (&eof_token, 0, sizeof (eof_token));
12965 	  eof_token.type = CPP_EOF;
12966 	  tokens.safe_push (eof_token);
12967 	  tokens.safe_push (eof_token);
12968 
12969 	  tokens_avail = parser->tokens_avail;
12970 	  gcc_assert (parser->tokens == &parser->tokens_buf[0]);
12971 	  parser->tokens = tokens.address ();
12972 	  parser->tokens_avail = tokens.length ();
12973 	}
12974 
12975       tree t = NULL_TREE;
12976 
12977       if (c_parser_next_token_is (parser, CPP_NAME)
12978 	  && c_parser_peek_token (parser)->id_kind == C_ID_ID)
12979 	{
12980 	  t = lookup_name (c_parser_peek_token (parser)->value);
12981 
12982 	  if (t == NULL_TREE)
12983 	    {
12984 	      undeclared_variable (c_parser_peek_token (parser)->location,
12985 	      c_parser_peek_token (parser)->value);
12986 	      t = error_mark_node;
12987 	    }
12988 
12989 	  c_parser_consume_token (parser);
12990 	}
12991       else if (c_parser_next_token_is (parser, CPP_KEYWORD)
12992 	       && (c_parser_peek_token (parser)->keyword == RID_FUNCTION_NAME
12993 		   || (c_parser_peek_token (parser)->keyword
12994 		       == RID_PRETTY_FUNCTION_NAME)
12995 		   || (c_parser_peek_token (parser)->keyword
12996 		       == RID_C99_FUNCTION_NAME)))
12997 	t = c_parser_predefined_identifier (parser).value;
12998       else
12999 	{
13000 	  if (first)
13001 	    c_parser_error (parser, "expected identifier");
13002 	  break;
13003 	}
13004 
13005       if (t == error_mark_node)
13006 	;
13007       else if (kind != 0)
13008 	{
13009 	  switch (kind)
13010 	    {
13011 	    case OMP_CLAUSE__CACHE_:
13012 	      /* The OpenACC cache directive explicitly only allows "array
13013 		 elements or subarrays".  */
13014 	      if (c_parser_peek_token (parser)->type != CPP_OPEN_SQUARE)
13015 		{
13016 		  c_parser_error (parser, "expected %<[%>");
13017 		  t = error_mark_node;
13018 		  break;
13019 		}
13020 	      /* FALLTHROUGH  */
13021 	    case OMP_CLAUSE_MAP:
13022 	    case OMP_CLAUSE_FROM:
13023 	    case OMP_CLAUSE_TO:
13024 	      while (c_parser_next_token_is (parser, CPP_DOT)
13025 		     || (allow_deref
13026 			 && c_parser_next_token_is (parser, CPP_DEREF)))
13027 		{
13028 		  location_t op_loc = c_parser_peek_token (parser)->location;
13029 		  if (c_parser_next_token_is (parser, CPP_DEREF))
13030 		    t = build_simple_mem_ref (t);
13031 		  c_parser_consume_token (parser);
13032 		  if (!c_parser_next_token_is (parser, CPP_NAME))
13033 		    {
13034 		      c_parser_error (parser, "expected identifier");
13035 		      t = error_mark_node;
13036 		      break;
13037 		    }
13038 
13039 		  c_token *comp_tok = c_parser_peek_token (parser);
13040 		  tree ident = comp_tok->value;
13041 		  location_t comp_loc = comp_tok->location;
13042 		  c_parser_consume_token (parser);
13043 		  t = build_component_ref (op_loc, t, ident, comp_loc);
13044 		}
13045 	      /* FALLTHROUGH  */
13046 	    case OMP_CLAUSE_DEPEND:
13047 	    case OMP_CLAUSE_REDUCTION:
13048 	    case OMP_CLAUSE_IN_REDUCTION:
13049 	    case OMP_CLAUSE_TASK_REDUCTION:
13050 	      while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
13051 		{
13052 		  tree low_bound = NULL_TREE, length = NULL_TREE;
13053 
13054 		  c_parser_consume_token (parser);
13055 		  if (!c_parser_next_token_is (parser, CPP_COLON))
13056 		    {
13057 		      location_t expr_loc
13058 			= c_parser_peek_token (parser)->location;
13059 		      c_expr expr = c_parser_expression (parser);
13060 		      expr = convert_lvalue_to_rvalue (expr_loc, expr,
13061 						       false, true);
13062 		      low_bound = expr.value;
13063 		    }
13064 		  if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
13065 		    length = integer_one_node;
13066 		  else
13067 		    {
13068 		      /* Look for `:'.  */
13069 		      if (!c_parser_require (parser, CPP_COLON,
13070 					     "expected %<:%>"))
13071 			{
13072 			  t = error_mark_node;
13073 			  break;
13074 			}
13075 		      array_section_p = true;
13076 		      if (!c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
13077 			{
13078 			  location_t expr_loc
13079 			    = c_parser_peek_token (parser)->location;
13080 			  c_expr expr = c_parser_expression (parser);
13081 			  expr = convert_lvalue_to_rvalue (expr_loc, expr,
13082 							   false, true);
13083 			  length = expr.value;
13084 			}
13085 		    }
13086 		  /* Look for the closing `]'.  */
13087 		  if (!c_parser_require (parser, CPP_CLOSE_SQUARE,
13088 					 "expected %<]%>"))
13089 		    {
13090 		      t = error_mark_node;
13091 		      break;
13092 		    }
13093 
13094 		  t = tree_cons (low_bound, length, t);
13095 		}
13096 	      if (kind == OMP_CLAUSE_DEPEND
13097 		  && t != error_mark_node
13098 		  && parser->tokens_avail != 2)
13099 		{
13100 		  if (array_section_p)
13101 		    {
13102 		      error_at (c_parser_peek_token (parser)->location,
13103 				"expected %<)%> or %<,%>");
13104 		      t = error_mark_node;
13105 		    }
13106 		  else
13107 		    {
13108 		      parser->tokens = tokens.address ();
13109 		      parser->tokens_avail = tokens.length ();
13110 
13111 		      t = c_parser_expr_no_commas (parser, NULL).value;
13112 		      if (t != error_mark_node && parser->tokens_avail != 2)
13113 			{
13114 			  error_at (c_parser_peek_token (parser)->location,
13115 				    "expected %<)%> or %<,%>");
13116 			  t = error_mark_node;
13117 			}
13118 		    }
13119 		}
13120 	      break;
13121 	    default:
13122 	      break;
13123 	    }
13124 
13125 	  if (t != error_mark_node)
13126 	    {
13127 	      tree u = build_omp_clause (clause_loc, kind);
13128 	      OMP_CLAUSE_DECL (u) = t;
13129 	      OMP_CLAUSE_CHAIN (u) = list;
13130 	      list = u;
13131 	    }
13132 	}
13133       else
13134 	list = tree_cons (t, NULL_TREE, list);
13135 
13136       if (kind == OMP_CLAUSE_DEPEND)
13137 	{
13138 	  parser->tokens = &parser->tokens_buf[0];
13139 	  parser->tokens_avail = tokens_avail;
13140 	}
13141       if (c_parser_next_token_is_not (parser, CPP_COMMA))
13142 	break;
13143 
13144       c_parser_consume_token (parser);
13145       first = false;
13146     }
13147 
13148   return list;
13149 }
13150 
13151 /* Similarly, but expect leading and trailing parenthesis.  This is a very
13152    common case for OpenACC and OpenMP clauses.  The optional ALLOW_DEREF
13153    argument is true if list items can use the deref (->) operator.  */
13154 
13155 static tree
13156 c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind,
13157 			      tree list, bool allow_deref = false)
13158 {
13159   /* The clauses location.  */
13160   location_t loc = c_parser_peek_token (parser)->location;
13161 
13162   matching_parens parens;
13163   if (parens.require_open (parser))
13164     {
13165       list = c_parser_omp_variable_list (parser, loc, kind, list, allow_deref);
13166       parens.skip_until_found_close (parser);
13167     }
13168   return list;
13169 }
13170 
13171 /* OpenACC 2.0:
13172    copy ( variable-list )
13173    copyin ( variable-list )
13174    copyout ( variable-list )
13175    create ( variable-list )
13176    delete ( variable-list )
13177    present ( variable-list )
13178 
13179    OpenACC 2.6:
13180    no_create ( variable-list )
13181    attach ( variable-list )
13182    detach ( variable-list ) */
13183 
13184 static tree
c_parser_oacc_data_clause(c_parser * parser,pragma_omp_clause c_kind,tree list)13185 c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind,
13186 			   tree list)
13187 {
13188   enum gomp_map_kind kind;
13189   switch (c_kind)
13190     {
13191     case PRAGMA_OACC_CLAUSE_ATTACH:
13192       kind = GOMP_MAP_ATTACH;
13193       break;
13194     case PRAGMA_OACC_CLAUSE_COPY:
13195       kind = GOMP_MAP_TOFROM;
13196       break;
13197     case PRAGMA_OACC_CLAUSE_COPYIN:
13198       kind = GOMP_MAP_TO;
13199       break;
13200     case PRAGMA_OACC_CLAUSE_COPYOUT:
13201       kind = GOMP_MAP_FROM;
13202       break;
13203     case PRAGMA_OACC_CLAUSE_CREATE:
13204       kind = GOMP_MAP_ALLOC;
13205       break;
13206     case PRAGMA_OACC_CLAUSE_DELETE:
13207       kind = GOMP_MAP_RELEASE;
13208       break;
13209     case PRAGMA_OACC_CLAUSE_DETACH:
13210       kind = GOMP_MAP_DETACH;
13211       break;
13212     case PRAGMA_OACC_CLAUSE_DEVICE:
13213       kind = GOMP_MAP_FORCE_TO;
13214       break;
13215     case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
13216       kind = GOMP_MAP_DEVICE_RESIDENT;
13217       break;
13218     case PRAGMA_OACC_CLAUSE_HOST:
13219       kind = GOMP_MAP_FORCE_FROM;
13220       break;
13221     case PRAGMA_OACC_CLAUSE_LINK:
13222       kind = GOMP_MAP_LINK;
13223       break;
13224     case PRAGMA_OACC_CLAUSE_NO_CREATE:
13225       kind = GOMP_MAP_IF_PRESENT;
13226       break;
13227     case PRAGMA_OACC_CLAUSE_PRESENT:
13228       kind = GOMP_MAP_FORCE_PRESENT;
13229       break;
13230     default:
13231       gcc_unreachable ();
13232     }
13233   tree nl, c;
13234   nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_MAP, list, true);
13235 
13236   for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
13237     OMP_CLAUSE_SET_MAP_KIND (c, kind);
13238 
13239   return nl;
13240 }
13241 
13242 /* OpenACC 2.0:
13243    deviceptr ( variable-list ) */
13244 
13245 static tree
c_parser_oacc_data_clause_deviceptr(c_parser * parser,tree list)13246 c_parser_oacc_data_clause_deviceptr (c_parser *parser, tree list)
13247 {
13248   location_t loc = c_parser_peek_token (parser)->location;
13249   tree vars, t;
13250 
13251   /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
13252      c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
13253      variable-list must only allow for pointer variables.  */
13254   vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
13255   for (t = vars; t && t; t = TREE_CHAIN (t))
13256     {
13257       tree v = TREE_PURPOSE (t);
13258 
13259       /* FIXME diagnostics: Ideally we should keep individual
13260 	 locations for all the variables in the var list to make the
13261 	 following errors more precise.  Perhaps
13262 	 c_parser_omp_var_list_parens() should construct a list of
13263 	 locations to go along with the var list.  */
13264 
13265       if (!VAR_P (v) && TREE_CODE (v) != PARM_DECL)
13266 	error_at (loc, "%qD is not a variable", v);
13267       else if (TREE_TYPE (v) == error_mark_node)
13268 	;
13269       else if (!POINTER_TYPE_P (TREE_TYPE (v)))
13270 	error_at (loc, "%qD is not a pointer variable", v);
13271 
13272       tree u = build_omp_clause (loc, OMP_CLAUSE_MAP);
13273       OMP_CLAUSE_SET_MAP_KIND (u, GOMP_MAP_FORCE_DEVICEPTR);
13274       OMP_CLAUSE_DECL (u) = v;
13275       OMP_CLAUSE_CHAIN (u) = list;
13276       list = u;
13277     }
13278 
13279   return list;
13280 }
13281 
13282 /* OpenACC 2.0, OpenMP 3.0:
13283    collapse ( constant-expression ) */
13284 
13285 static tree
c_parser_omp_clause_collapse(c_parser * parser,tree list)13286 c_parser_omp_clause_collapse (c_parser *parser, tree list)
13287 {
13288   tree c, num = error_mark_node;
13289   HOST_WIDE_INT n;
13290   location_t loc;
13291 
13292   check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
13293   check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
13294 
13295   loc = c_parser_peek_token (parser)->location;
13296   matching_parens parens;
13297   if (parens.require_open (parser))
13298     {
13299       num = c_parser_expr_no_commas (parser, NULL).value;
13300       parens.skip_until_found_close (parser);
13301     }
13302   if (num == error_mark_node)
13303     return list;
13304   mark_exp_read (num);
13305   num = c_fully_fold (num, false, NULL);
13306   if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
13307       || !tree_fits_shwi_p (num)
13308       || (n = tree_to_shwi (num)) <= 0
13309       || (int) n != n)
13310     {
13311       error_at (loc,
13312 		"collapse argument needs positive constant integer expression");
13313       return list;
13314     }
13315   c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE);
13316   OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
13317   OMP_CLAUSE_CHAIN (c) = list;
13318   return c;
13319 }
13320 
13321 /* OpenMP 2.5:
13322    copyin ( variable-list ) */
13323 
13324 static tree
c_parser_omp_clause_copyin(c_parser * parser,tree list)13325 c_parser_omp_clause_copyin (c_parser *parser, tree list)
13326 {
13327   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYIN, list);
13328 }
13329 
13330 /* OpenMP 2.5:
13331    copyprivate ( variable-list ) */
13332 
13333 static tree
c_parser_omp_clause_copyprivate(c_parser * parser,tree list)13334 c_parser_omp_clause_copyprivate (c_parser *parser, tree list)
13335 {
13336   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYPRIVATE, list);
13337 }
13338 
13339 /* OpenMP 2.5:
13340    default ( none | shared )
13341 
13342    OpenACC:
13343    default ( none | present ) */
13344 
13345 static tree
c_parser_omp_clause_default(c_parser * parser,tree list,bool is_oacc)13346 c_parser_omp_clause_default (c_parser *parser, tree list, bool is_oacc)
13347 {
13348   enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
13349   location_t loc = c_parser_peek_token (parser)->location;
13350   tree c;
13351 
13352   matching_parens parens;
13353   if (!parens.require_open (parser))
13354     return list;
13355   if (c_parser_next_token_is (parser, CPP_NAME))
13356     {
13357       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13358 
13359       switch (p[0])
13360 	{
13361 	case 'n':
13362 	  if (strcmp ("none", p) != 0)
13363 	    goto invalid_kind;
13364 	  kind = OMP_CLAUSE_DEFAULT_NONE;
13365 	  break;
13366 
13367 	case 'p':
13368 	  if (strcmp ("present", p) != 0 || !is_oacc)
13369 	    goto invalid_kind;
13370 	  kind = OMP_CLAUSE_DEFAULT_PRESENT;
13371 	  break;
13372 
13373 	case 's':
13374 	  if (strcmp ("shared", p) != 0 || is_oacc)
13375 	    goto invalid_kind;
13376 	  kind = OMP_CLAUSE_DEFAULT_SHARED;
13377 	  break;
13378 
13379 	default:
13380 	  goto invalid_kind;
13381 	}
13382 
13383       c_parser_consume_token (parser);
13384     }
13385   else
13386     {
13387     invalid_kind:
13388       if (is_oacc)
13389 	c_parser_error (parser, "expected %<none%> or %<present%>");
13390       else
13391 	c_parser_error (parser, "expected %<none%> or %<shared%>");
13392     }
13393   parens.skip_until_found_close (parser);
13394 
13395   if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED)
13396     return list;
13397 
13398   check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default");
13399   c = build_omp_clause (loc, OMP_CLAUSE_DEFAULT);
13400   OMP_CLAUSE_CHAIN (c) = list;
13401   OMP_CLAUSE_DEFAULT_KIND (c) = kind;
13402 
13403   return c;
13404 }
13405 
13406 /* OpenMP 2.5:
13407    firstprivate ( variable-list ) */
13408 
13409 static tree
c_parser_omp_clause_firstprivate(c_parser * parser,tree list)13410 c_parser_omp_clause_firstprivate (c_parser *parser, tree list)
13411 {
13412   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FIRSTPRIVATE, list);
13413 }
13414 
13415 /* OpenMP 3.1:
13416    final ( expression ) */
13417 
13418 static tree
c_parser_omp_clause_final(c_parser * parser,tree list)13419 c_parser_omp_clause_final (c_parser *parser, tree list)
13420 {
13421   location_t loc = c_parser_peek_token (parser)->location;
13422   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
13423     {
13424       matching_parens parens;
13425       tree t, c;
13426       if (!parens.require_open (parser))
13427 	t = error_mark_node;
13428       else
13429 	{
13430 	  location_t eloc = c_parser_peek_token (parser)->location;
13431 	  c_expr expr = c_parser_expr_no_commas (parser, NULL);
13432 	  t = convert_lvalue_to_rvalue (eloc, expr, true, true).value;
13433 	  t = c_objc_common_truthvalue_conversion (eloc, t);
13434 	  t = c_fully_fold (t, false, NULL);
13435 	  parens.skip_until_found_close (parser);
13436 	}
13437 
13438       check_no_duplicate_clause (list, OMP_CLAUSE_FINAL, "final");
13439 
13440       c = build_omp_clause (loc, OMP_CLAUSE_FINAL);
13441       OMP_CLAUSE_FINAL_EXPR (c) = t;
13442       OMP_CLAUSE_CHAIN (c) = list;
13443       list = c;
13444     }
13445   else
13446     c_parser_error (parser, "expected %<(%>");
13447 
13448   return list;
13449 }
13450 
13451 /* OpenACC, OpenMP 2.5:
13452    if ( expression )
13453 
13454    OpenMP 4.5:
13455    if ( directive-name-modifier : expression )
13456 
13457    directive-name-modifier:
13458      parallel | task | taskloop | target data | target | target update
13459      | target enter data | target exit data
13460 
13461    OpenMP 5.0:
13462    directive-name-modifier:
13463      ... | simd | cancel  */
13464 
13465 static tree
c_parser_omp_clause_if(c_parser * parser,tree list,bool is_omp)13466 c_parser_omp_clause_if (c_parser *parser, tree list, bool is_omp)
13467 {
13468   location_t location = c_parser_peek_token (parser)->location;
13469   enum tree_code if_modifier = ERROR_MARK;
13470 
13471   matching_parens parens;
13472   if (!parens.require_open (parser))
13473     return list;
13474 
13475   if (is_omp && c_parser_next_token_is (parser, CPP_NAME))
13476     {
13477       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13478       int n = 2;
13479       if (strcmp (p, "cancel") == 0)
13480 	if_modifier = VOID_CST;
13481       else if (strcmp (p, "parallel") == 0)
13482 	if_modifier = OMP_PARALLEL;
13483       else if (strcmp (p, "simd") == 0)
13484 	if_modifier = OMP_SIMD;
13485       else if (strcmp (p, "task") == 0)
13486 	if_modifier = OMP_TASK;
13487       else if (strcmp (p, "taskloop") == 0)
13488 	if_modifier = OMP_TASKLOOP;
13489       else if (strcmp (p, "target") == 0)
13490 	{
13491 	  if_modifier = OMP_TARGET;
13492 	  if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
13493 	    {
13494 	      p = IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser)->value);
13495 	      if (strcmp ("data", p) == 0)
13496 		if_modifier = OMP_TARGET_DATA;
13497 	      else if (strcmp ("update", p) == 0)
13498 		if_modifier = OMP_TARGET_UPDATE;
13499 	      else if (strcmp ("enter", p) == 0)
13500 		if_modifier = OMP_TARGET_ENTER_DATA;
13501 	      else if (strcmp ("exit", p) == 0)
13502 		if_modifier = OMP_TARGET_EXIT_DATA;
13503 	      if (if_modifier != OMP_TARGET)
13504 		{
13505 		  n = 3;
13506 		  c_parser_consume_token (parser);
13507 		}
13508 	      else
13509 		{
13510 		  location_t loc = c_parser_peek_2nd_token (parser)->location;
13511 		  error_at (loc, "expected %<data%>, %<update%>, %<enter%> "
13512 				 "or %<exit%>");
13513 		  if_modifier = ERROR_MARK;
13514 		}
13515 	      if (if_modifier == OMP_TARGET_ENTER_DATA
13516 		  || if_modifier == OMP_TARGET_EXIT_DATA)
13517 		{
13518 		  if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
13519 		    {
13520 		      p = IDENTIFIER_POINTER
13521 				(c_parser_peek_2nd_token (parser)->value);
13522 		      if (strcmp ("data", p) == 0)
13523 			n = 4;
13524 		    }
13525 		  if (n == 4)
13526 		    c_parser_consume_token (parser);
13527 		  else
13528 		    {
13529 		      location_t loc
13530 			= c_parser_peek_2nd_token (parser)->location;
13531 		      error_at (loc, "expected %<data%>");
13532 		      if_modifier = ERROR_MARK;
13533 		    }
13534 		}
13535 	    }
13536 	}
13537       if (if_modifier != ERROR_MARK)
13538 	{
13539 	  if (c_parser_peek_2nd_token (parser)->type == CPP_COLON)
13540 	    {
13541 	      c_parser_consume_token (parser);
13542 	      c_parser_consume_token (parser);
13543 	    }
13544 	  else
13545 	    {
13546 	      if (n > 2)
13547 		{
13548 		  location_t loc = c_parser_peek_2nd_token (parser)->location;
13549 		  error_at (loc, "expected %<:%>");
13550 		}
13551 	      if_modifier = ERROR_MARK;
13552 	    }
13553 	}
13554     }
13555 
13556   location_t loc = c_parser_peek_token (parser)->location;
13557   c_expr expr = c_parser_expr_no_commas (parser, NULL);
13558   expr = convert_lvalue_to_rvalue (loc, expr, true, true);
13559   tree t = c_objc_common_truthvalue_conversion (loc, expr.value), c;
13560   t = c_fully_fold (t, false, NULL);
13561   parens.skip_until_found_close (parser);
13562 
13563   for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
13564     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF)
13565       {
13566 	if (if_modifier != ERROR_MARK
13567 	    && OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
13568 	  {
13569 	    const char *p = NULL;
13570 	    switch (if_modifier)
13571 	      {
13572 	      case VOID_CST: p = "cancel"; break;
13573 	      case OMP_PARALLEL: p = "parallel"; break;
13574 	      case OMP_SIMD: p = "simd"; break;
13575 	      case OMP_TASK: p = "task"; break;
13576 	      case OMP_TASKLOOP: p = "taskloop"; break;
13577 	      case OMP_TARGET_DATA: p = "target data"; break;
13578 	      case OMP_TARGET: p = "target"; break;
13579 	      case OMP_TARGET_UPDATE: p = "target update"; break;
13580 	      case OMP_TARGET_ENTER_DATA: p = "target enter data"; break;
13581 	      case OMP_TARGET_EXIT_DATA: p = "target exit data"; break;
13582 	      default: gcc_unreachable ();
13583 	      }
13584 	    error_at (location, "too many %<if%> clauses with %qs modifier",
13585 		      p);
13586 	    return list;
13587 	  }
13588 	else if (OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
13589 	  {
13590 	    if (!is_omp)
13591 	      error_at (location, "too many %<if%> clauses");
13592 	    else
13593 	      error_at (location, "too many %<if%> clauses without modifier");
13594 	    return list;
13595 	  }
13596 	else if (if_modifier == ERROR_MARK
13597 		 || OMP_CLAUSE_IF_MODIFIER (c) == ERROR_MARK)
13598 	  {
13599 	    error_at (location, "if any %<if%> clause has modifier, then all "
13600 				"%<if%> clauses have to use modifier");
13601 	    return list;
13602 	  }
13603       }
13604 
13605   c = build_omp_clause (location, OMP_CLAUSE_IF);
13606   OMP_CLAUSE_IF_MODIFIER (c) = if_modifier;
13607   OMP_CLAUSE_IF_EXPR (c) = t;
13608   OMP_CLAUSE_CHAIN (c) = list;
13609   return c;
13610 }
13611 
13612 /* OpenMP 2.5:
13613    lastprivate ( variable-list )
13614 
13615    OpenMP 5.0:
13616    lastprivate ( [ lastprivate-modifier : ] variable-list ) */
13617 
13618 static tree
c_parser_omp_clause_lastprivate(c_parser * parser,tree list)13619 c_parser_omp_clause_lastprivate (c_parser *parser, tree list)
13620 {
13621   /* The clauses location.  */
13622   location_t loc = c_parser_peek_token (parser)->location;
13623 
13624   if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
13625     {
13626       bool conditional = false;
13627       if (c_parser_next_token_is (parser, CPP_NAME)
13628 	  && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
13629 	{
13630 	  const char *p
13631 	    = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13632 	  if (strcmp (p, "conditional") == 0)
13633 	    {
13634 	      conditional = true;
13635 	      c_parser_consume_token (parser);
13636 	      c_parser_consume_token (parser);
13637 	    }
13638 	}
13639       tree nlist = c_parser_omp_variable_list (parser, loc,
13640 					       OMP_CLAUSE_LASTPRIVATE, list);
13641       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
13642       if (conditional)
13643 	for (tree c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
13644 	  OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 1;
13645       return nlist;
13646     }
13647   return list;
13648 }
13649 
13650 /* OpenMP 3.1:
13651    mergeable */
13652 
13653 static tree
c_parser_omp_clause_mergeable(c_parser * parser ATTRIBUTE_UNUSED,tree list)13654 c_parser_omp_clause_mergeable (c_parser *parser ATTRIBUTE_UNUSED, tree list)
13655 {
13656   tree c;
13657 
13658   /* FIXME: Should we allow duplicates?  */
13659   check_no_duplicate_clause (list, OMP_CLAUSE_MERGEABLE, "mergeable");
13660 
13661   c = build_omp_clause (c_parser_peek_token (parser)->location,
13662 			OMP_CLAUSE_MERGEABLE);
13663   OMP_CLAUSE_CHAIN (c) = list;
13664 
13665   return c;
13666 }
13667 
13668 /* OpenMP 2.5:
13669    nowait */
13670 
13671 static tree
c_parser_omp_clause_nowait(c_parser * parser ATTRIBUTE_UNUSED,tree list)13672 c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list)
13673 {
13674   tree c;
13675   location_t loc = c_parser_peek_token (parser)->location;
13676 
13677   check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait");
13678 
13679   c = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
13680   OMP_CLAUSE_CHAIN (c) = list;
13681   return c;
13682 }
13683 
13684 /* OpenMP 2.5:
13685    num_threads ( expression ) */
13686 
13687 static tree
c_parser_omp_clause_num_threads(c_parser * parser,tree list)13688 c_parser_omp_clause_num_threads (c_parser *parser, tree list)
13689 {
13690   location_t num_threads_loc = c_parser_peek_token (parser)->location;
13691   matching_parens parens;
13692   if (parens.require_open (parser))
13693     {
13694       location_t expr_loc = c_parser_peek_token (parser)->location;
13695       c_expr expr = c_parser_expr_no_commas (parser, NULL);
13696       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13697       tree c, t = expr.value;
13698       t = c_fully_fold (t, false, NULL);
13699 
13700       parens.skip_until_found_close (parser);
13701 
13702       if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13703 	{
13704 	  c_parser_error (parser, "expected integer expression");
13705 	  return list;
13706 	}
13707 
13708       /* Attempt to statically determine when the number isn't positive.  */
13709       c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13710 		       build_int_cst (TREE_TYPE (t), 0));
13711       protected_set_expr_location (c, expr_loc);
13712       if (c == boolean_true_node)
13713 	{
13714 	  warning_at (expr_loc, 0,
13715 		      "%<num_threads%> value must be positive");
13716 	  t = integer_one_node;
13717 	}
13718 
13719       check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads");
13720 
13721       c = build_omp_clause (num_threads_loc, OMP_CLAUSE_NUM_THREADS);
13722       OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
13723       OMP_CLAUSE_CHAIN (c) = list;
13724       list = c;
13725     }
13726 
13727   return list;
13728 }
13729 
13730 /* OpenMP 4.5:
13731    num_tasks ( expression ) */
13732 
13733 static tree
c_parser_omp_clause_num_tasks(c_parser * parser,tree list)13734 c_parser_omp_clause_num_tasks (c_parser *parser, tree list)
13735 {
13736   location_t num_tasks_loc = c_parser_peek_token (parser)->location;
13737   matching_parens parens;
13738   if (parens.require_open (parser))
13739     {
13740       location_t expr_loc = c_parser_peek_token (parser)->location;
13741       c_expr expr = c_parser_expr_no_commas (parser, NULL);
13742       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13743       tree c, t = expr.value;
13744       t = c_fully_fold (t, false, NULL);
13745 
13746       parens.skip_until_found_close (parser);
13747 
13748       if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13749 	{
13750 	  c_parser_error (parser, "expected integer expression");
13751 	  return list;
13752 	}
13753 
13754       /* Attempt to statically determine when the number isn't positive.  */
13755       c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13756 			   build_int_cst (TREE_TYPE (t), 0));
13757       if (CAN_HAVE_LOCATION_P (c))
13758 	SET_EXPR_LOCATION (c, expr_loc);
13759       if (c == boolean_true_node)
13760 	{
13761 	  warning_at (expr_loc, 0, "%<num_tasks%> value must be positive");
13762 	  t = integer_one_node;
13763 	}
13764 
13765       check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TASKS, "num_tasks");
13766 
13767       c = build_omp_clause (num_tasks_loc, OMP_CLAUSE_NUM_TASKS);
13768       OMP_CLAUSE_NUM_TASKS_EXPR (c) = t;
13769       OMP_CLAUSE_CHAIN (c) = list;
13770       list = c;
13771     }
13772 
13773   return list;
13774 }
13775 
13776 /* OpenMP 4.5:
13777    grainsize ( expression ) */
13778 
13779 static tree
c_parser_omp_clause_grainsize(c_parser * parser,tree list)13780 c_parser_omp_clause_grainsize (c_parser *parser, tree list)
13781 {
13782   location_t grainsize_loc = c_parser_peek_token (parser)->location;
13783   matching_parens parens;
13784   if (parens.require_open (parser))
13785     {
13786       location_t expr_loc = c_parser_peek_token (parser)->location;
13787       c_expr expr = c_parser_expr_no_commas (parser, NULL);
13788       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13789       tree c, t = expr.value;
13790       t = c_fully_fold (t, false, NULL);
13791 
13792       parens.skip_until_found_close (parser);
13793 
13794       if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13795 	{
13796 	  c_parser_error (parser, "expected integer expression");
13797 	  return list;
13798 	}
13799 
13800       /* Attempt to statically determine when the number isn't positive.  */
13801       c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13802 			   build_int_cst (TREE_TYPE (t), 0));
13803       if (CAN_HAVE_LOCATION_P (c))
13804 	SET_EXPR_LOCATION (c, expr_loc);
13805       if (c == boolean_true_node)
13806 	{
13807 	  warning_at (expr_loc, 0, "%<grainsize%> value must be positive");
13808 	  t = integer_one_node;
13809 	}
13810 
13811       check_no_duplicate_clause (list, OMP_CLAUSE_GRAINSIZE, "grainsize");
13812 
13813       c = build_omp_clause (grainsize_loc, OMP_CLAUSE_GRAINSIZE);
13814       OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
13815       OMP_CLAUSE_CHAIN (c) = list;
13816       list = c;
13817     }
13818 
13819   return list;
13820 }
13821 
13822 /* OpenMP 4.5:
13823    priority ( expression ) */
13824 
13825 static tree
c_parser_omp_clause_priority(c_parser * parser,tree list)13826 c_parser_omp_clause_priority (c_parser *parser, tree list)
13827 {
13828   location_t priority_loc = c_parser_peek_token (parser)->location;
13829   matching_parens parens;
13830   if (parens.require_open (parser))
13831     {
13832       location_t expr_loc = c_parser_peek_token (parser)->location;
13833       c_expr expr = c_parser_expr_no_commas (parser, NULL);
13834       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13835       tree c, t = expr.value;
13836       t = c_fully_fold (t, false, NULL);
13837 
13838       parens.skip_until_found_close (parser);
13839 
13840       if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13841 	{
13842 	  c_parser_error (parser, "expected integer expression");
13843 	  return list;
13844 	}
13845 
13846       /* Attempt to statically determine when the number isn't
13847 	 non-negative.  */
13848       c = fold_build2_loc (expr_loc, LT_EXPR, boolean_type_node, t,
13849 			   build_int_cst (TREE_TYPE (t), 0));
13850       if (CAN_HAVE_LOCATION_P (c))
13851 	SET_EXPR_LOCATION (c, expr_loc);
13852       if (c == boolean_true_node)
13853 	{
13854 	  warning_at (expr_loc, 0, "%<priority%> value must be non-negative");
13855 	  t = integer_one_node;
13856 	}
13857 
13858       check_no_duplicate_clause (list, OMP_CLAUSE_PRIORITY, "priority");
13859 
13860       c = build_omp_clause (priority_loc, OMP_CLAUSE_PRIORITY);
13861       OMP_CLAUSE_PRIORITY_EXPR (c) = t;
13862       OMP_CLAUSE_CHAIN (c) = list;
13863       list = c;
13864     }
13865 
13866   return list;
13867 }
13868 
13869 /* OpenMP 4.5:
13870    hint ( expression ) */
13871 
13872 static tree
c_parser_omp_clause_hint(c_parser * parser,tree list)13873 c_parser_omp_clause_hint (c_parser *parser, tree list)
13874 {
13875   location_t hint_loc = c_parser_peek_token (parser)->location;
13876   matching_parens parens;
13877   if (parens.require_open (parser))
13878     {
13879       location_t expr_loc = c_parser_peek_token (parser)->location;
13880       c_expr expr = c_parser_expr_no_commas (parser, NULL);
13881       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13882       tree c, t = expr.value;
13883       t = c_fully_fold (t, false, NULL);
13884       if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
13885 	  || TREE_CODE (t) != INTEGER_CST
13886 	  || tree_int_cst_sgn (t) == -1)
13887 	{
13888 	  c_parser_error (parser, "expected constant integer expression "
13889 				  "with valid sync-hint value");
13890 	  return list;
13891 	}
13892       parens.skip_until_found_close (parser);
13893       check_no_duplicate_clause (list, OMP_CLAUSE_HINT, "hint");
13894 
13895       c = build_omp_clause (hint_loc, OMP_CLAUSE_HINT);
13896       OMP_CLAUSE_HINT_EXPR (c) = t;
13897       OMP_CLAUSE_CHAIN (c) = list;
13898       list = c;
13899     }
13900 
13901   return list;
13902 }
13903 
13904 /* OpenMP 4.5:
13905    defaultmap ( tofrom : scalar )
13906 
13907    OpenMP 5.0:
13908    defaultmap ( implicit-behavior [ : variable-category ] ) */
13909 
13910 static tree
c_parser_omp_clause_defaultmap(c_parser * parser,tree list)13911 c_parser_omp_clause_defaultmap (c_parser *parser, tree list)
13912 {
13913   location_t loc = c_parser_peek_token (parser)->location;
13914   tree c;
13915   const char *p;
13916   enum omp_clause_defaultmap_kind behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
13917   enum omp_clause_defaultmap_kind category
13918     = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
13919 
13920   matching_parens parens;
13921   if (!parens.require_open (parser))
13922     return list;
13923   if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
13924     p = "default";
13925   else if (!c_parser_next_token_is (parser, CPP_NAME))
13926     {
13927     invalid_behavior:
13928       c_parser_error (parser, "expected %<alloc%>, %<to%>, %<from%>, "
13929 			      "%<tofrom%>, %<firstprivate%>, %<none%> "
13930 			      "or %<default%>");
13931       goto out_err;
13932     }
13933   else
13934     p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13935 
13936   switch (p[0])
13937     {
13938     case 'a':
13939       if (strcmp ("alloc", p) == 0)
13940 	behavior = OMP_CLAUSE_DEFAULTMAP_ALLOC;
13941       else
13942 	goto invalid_behavior;
13943       break;
13944 
13945     case 'd':
13946       if (strcmp ("default", p) == 0)
13947 	behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
13948       else
13949 	goto invalid_behavior;
13950       break;
13951 
13952     case 'f':
13953       if (strcmp ("firstprivate", p) == 0)
13954 	behavior = OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
13955       else if (strcmp ("from", p) == 0)
13956 	behavior = OMP_CLAUSE_DEFAULTMAP_FROM;
13957       else
13958 	goto invalid_behavior;
13959       break;
13960 
13961     case 'n':
13962       if (strcmp ("none", p) == 0)
13963 	behavior = OMP_CLAUSE_DEFAULTMAP_NONE;
13964       else
13965 	goto invalid_behavior;
13966       break;
13967 
13968     case 't':
13969       if (strcmp ("tofrom", p) == 0)
13970 	behavior = OMP_CLAUSE_DEFAULTMAP_TOFROM;
13971       else if (strcmp ("to", p) == 0)
13972 	behavior = OMP_CLAUSE_DEFAULTMAP_TO;
13973       else
13974 	goto invalid_behavior;
13975       break;
13976 
13977     default:
13978       goto invalid_behavior;
13979     }
13980   c_parser_consume_token (parser);
13981 
13982   if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
13983     {
13984       if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
13985 	goto out_err;
13986       if (!c_parser_next_token_is (parser, CPP_NAME))
13987 	{
13988 	invalid_category:
13989 	  c_parser_error (parser, "expected %<scalar%>, %<aggregate%> or "
13990 				  "%<pointer%>");
13991 	  goto out_err;
13992 	}
13993       p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13994       switch (p[0])
13995 	{
13996 	case 'a':
13997 	  if (strcmp ("aggregate", p) == 0)
13998 	    category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE;
13999 	  else
14000 	    goto invalid_category;
14001 	  break;
14002 
14003 	case 'p':
14004 	  if (strcmp ("pointer", p) == 0)
14005 	    category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER;
14006 	  else
14007 	    goto invalid_category;
14008 	  break;
14009 
14010 	case 's':
14011 	  if (strcmp ("scalar", p) == 0)
14012 	    category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR;
14013 	  else
14014 	    goto invalid_category;
14015 	  break;
14016 
14017 	default:
14018 	  goto invalid_category;
14019 	}
14020 
14021       c_parser_consume_token (parser);
14022     }
14023   parens.skip_until_found_close (parser);
14024 
14025   for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
14026     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEFAULTMAP
14027 	&& (category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
14028 	    || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c) == category
14029 	    || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
14030 		== OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)))
14031       {
14032 	enum omp_clause_defaultmap_kind cat = category;
14033 	location_t loc = OMP_CLAUSE_LOCATION (c);
14034 	if (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
14035 	  cat = OMP_CLAUSE_DEFAULTMAP_CATEGORY (c);
14036 	p = NULL;
14037 	switch (cat)
14038 	  {
14039 	  case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
14040 	    p = NULL;
14041 	    break;
14042 	  case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
14043 	    p = "aggregate";
14044 	    break;
14045 	  case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
14046 	    p = "pointer";
14047 	    break;
14048 	  case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
14049 	    p = "scalar";
14050 	    break;
14051 	  default:
14052 	    gcc_unreachable ();
14053 	  }
14054 	if (p)
14055 	  error_at (loc, "too many %<defaultmap%> clauses with %qs category",
14056 		    p);
14057 	else
14058 	  error_at (loc, "too many %<defaultmap%> clauses with unspecified "
14059 			 "category");
14060 	break;
14061       }
14062 
14063   c = build_omp_clause (loc, OMP_CLAUSE_DEFAULTMAP);
14064   OMP_CLAUSE_DEFAULTMAP_SET_KIND (c, behavior, category);
14065   OMP_CLAUSE_CHAIN (c) = list;
14066   return c;
14067 
14068  out_err:
14069   parens.skip_until_found_close (parser);
14070   return list;
14071 }
14072 
14073 /* OpenACC 2.0:
14074    use_device ( variable-list )
14075 
14076    OpenMP 4.5:
14077    use_device_ptr ( variable-list ) */
14078 
14079 static tree
c_parser_omp_clause_use_device_ptr(c_parser * parser,tree list)14080 c_parser_omp_clause_use_device_ptr (c_parser *parser, tree list)
14081 {
14082   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_PTR,
14083 				       list);
14084 }
14085 
14086 /* OpenMP 5.0:
14087    use_device_addr ( variable-list ) */
14088 
14089 static tree
c_parser_omp_clause_use_device_addr(c_parser * parser,tree list)14090 c_parser_omp_clause_use_device_addr (c_parser *parser, tree list)
14091 {
14092   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_ADDR,
14093 				       list);
14094 }
14095 
14096 /* OpenMP 4.5:
14097    is_device_ptr ( variable-list ) */
14098 
14099 static tree
c_parser_omp_clause_is_device_ptr(c_parser * parser,tree list)14100 c_parser_omp_clause_is_device_ptr (c_parser *parser, tree list)
14101 {
14102   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_IS_DEVICE_PTR, list);
14103 }
14104 
14105 /* OpenACC:
14106    num_gangs ( expression )
14107    num_workers ( expression )
14108    vector_length ( expression )  */
14109 
14110 static tree
c_parser_oacc_single_int_clause(c_parser * parser,omp_clause_code code,tree list)14111 c_parser_oacc_single_int_clause (c_parser *parser, omp_clause_code code,
14112 				 tree list)
14113 {
14114   location_t loc = c_parser_peek_token (parser)->location;
14115 
14116   matching_parens parens;
14117   if (!parens.require_open (parser))
14118     return list;
14119 
14120   location_t expr_loc = c_parser_peek_token (parser)->location;
14121   c_expr expr = c_parser_expression (parser);
14122   expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14123   tree c, t = expr.value;
14124   t = c_fully_fold (t, false, NULL);
14125 
14126   parens.skip_until_found_close (parser);
14127 
14128   if (t == error_mark_node)
14129     return list;
14130   else if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14131     {
14132       error_at (expr_loc, "%qs expression must be integral",
14133 		omp_clause_code_name[code]);
14134       return list;
14135     }
14136 
14137   /* Attempt to statically determine when the number isn't positive.  */
14138   c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14139 		       build_int_cst (TREE_TYPE (t), 0));
14140   protected_set_expr_location (c, expr_loc);
14141   if (c == boolean_true_node)
14142     {
14143       warning_at (expr_loc, 0,
14144 		  "%qs value must be positive",
14145 		  omp_clause_code_name[code]);
14146       t = integer_one_node;
14147     }
14148 
14149   check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14150 
14151   c = build_omp_clause (loc, code);
14152   OMP_CLAUSE_OPERAND (c, 0) = t;
14153   OMP_CLAUSE_CHAIN (c) = list;
14154   return c;
14155 }
14156 
14157 /* OpenACC:
14158 
14159     gang [( gang-arg-list )]
14160     worker [( [num:] int-expr )]
14161     vector [( [length:] int-expr )]
14162 
14163   where gang-arg is one of:
14164 
14165     [num:] int-expr
14166     static: size-expr
14167 
14168   and size-expr may be:
14169 
14170     *
14171     int-expr
14172 */
14173 
14174 static tree
c_parser_oacc_shape_clause(c_parser * parser,location_t loc,omp_clause_code kind,const char * str,tree list)14175 c_parser_oacc_shape_clause (c_parser *parser, location_t loc,
14176 			    omp_clause_code kind,
14177 			    const char *str, tree list)
14178 {
14179   const char *id = "num";
14180   tree ops[2] = { NULL_TREE, NULL_TREE }, c;
14181 
14182   if (kind == OMP_CLAUSE_VECTOR)
14183     id = "length";
14184 
14185   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14186     {
14187       c_parser_consume_token (parser);
14188 
14189       do
14190 	{
14191 	  c_token *next = c_parser_peek_token (parser);
14192 	  int idx = 0;
14193 
14194 	  /* Gang static argument.  */
14195 	  if (kind == OMP_CLAUSE_GANG
14196 	      && c_parser_next_token_is_keyword (parser, RID_STATIC))
14197 	    {
14198 	      c_parser_consume_token (parser);
14199 
14200 	      if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14201 		goto cleanup_error;
14202 
14203 	      idx = 1;
14204 	      if (ops[idx] != NULL_TREE)
14205 		{
14206 		  c_parser_error (parser, "too many %<static%> arguments");
14207 		  goto cleanup_error;
14208 		}
14209 
14210 	      /* Check for the '*' argument.  */
14211 	      if (c_parser_next_token_is (parser, CPP_MULT)
14212 		  && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
14213 		      || c_parser_peek_2nd_token (parser)->type
14214 		         == CPP_CLOSE_PAREN))
14215 		{
14216 		  c_parser_consume_token (parser);
14217 		  ops[idx] = integer_minus_one_node;
14218 
14219 		  if (c_parser_next_token_is (parser, CPP_COMMA))
14220 		    {
14221 		      c_parser_consume_token (parser);
14222 		      continue;
14223 		    }
14224 		  else
14225 		    break;
14226 		}
14227 	    }
14228 	  /* Worker num: argument and vector length: arguments.  */
14229 	  else if (c_parser_next_token_is (parser, CPP_NAME)
14230 		   && strcmp (id, IDENTIFIER_POINTER (next->value)) == 0
14231 		   && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
14232 	    {
14233 	      c_parser_consume_token (parser);  /* id  */
14234 	      c_parser_consume_token (parser);  /* ':'  */
14235 	    }
14236 
14237 	  /* Now collect the actual argument.  */
14238 	  if (ops[idx] != NULL_TREE)
14239 	    {
14240 	      c_parser_error (parser, "unexpected argument");
14241 	      goto cleanup_error;
14242 	    }
14243 
14244 	  location_t expr_loc = c_parser_peek_token (parser)->location;
14245 	  c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
14246 	  cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
14247 	  tree expr = cexpr.value;
14248 	  if (expr == error_mark_node)
14249 	    goto cleanup_error;
14250 
14251 	  expr = c_fully_fold (expr, false, NULL);
14252 
14253 	  /* Attempt to statically determine when the number isn't a
14254 	     positive integer.  */
14255 
14256 	  if (!INTEGRAL_TYPE_P (TREE_TYPE (expr)))
14257 	    {
14258 	      c_parser_error (parser, "expected integer expression");
14259 	      return list;
14260 	    }
14261 
14262 	  tree c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, expr,
14263 				    build_int_cst (TREE_TYPE (expr), 0));
14264 	  if (c == boolean_true_node)
14265 	    {
14266 	      warning_at (loc, 0,
14267 			  "%qs value must be positive", str);
14268 	      expr = integer_one_node;
14269 	    }
14270 
14271 	  ops[idx] = expr;
14272 
14273 	  if (kind == OMP_CLAUSE_GANG
14274 	      && c_parser_next_token_is (parser, CPP_COMMA))
14275 	    {
14276 	      c_parser_consume_token (parser);
14277 	      continue;
14278 	    }
14279 	  break;
14280 	}
14281       while (1);
14282 
14283       if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
14284 	goto cleanup_error;
14285     }
14286 
14287   check_no_duplicate_clause (list, kind, str);
14288 
14289   c = build_omp_clause (loc, kind);
14290 
14291   if (ops[1])
14292     OMP_CLAUSE_OPERAND (c, 1) = ops[1];
14293 
14294   OMP_CLAUSE_OPERAND (c, 0) = ops[0];
14295   OMP_CLAUSE_CHAIN (c) = list;
14296 
14297   return c;
14298 
14299  cleanup_error:
14300   c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
14301   return list;
14302 }
14303 
14304 /* OpenACC 2.5:
14305    auto
14306    finalize
14307    independent
14308    nohost
14309    seq */
14310 
14311 static tree
c_parser_oacc_simple_clause(location_t loc,enum omp_clause_code code,tree list)14312 c_parser_oacc_simple_clause (location_t loc, enum omp_clause_code code,
14313 			     tree list)
14314 {
14315   check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14316 
14317   tree c = build_omp_clause (loc, code);
14318   OMP_CLAUSE_CHAIN (c) = list;
14319 
14320   return c;
14321 }
14322 
14323 /* OpenACC:
14324    async [( int-expr )] */
14325 
14326 static tree
c_parser_oacc_clause_async(c_parser * parser,tree list)14327 c_parser_oacc_clause_async (c_parser *parser, tree list)
14328 {
14329   tree c, t;
14330   location_t loc = c_parser_peek_token (parser)->location;
14331 
14332   t = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
14333 
14334   if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
14335     {
14336       c_parser_consume_token (parser);
14337 
14338       t = c_parser_expr_no_commas (parser, NULL).value;
14339       if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14340 	c_parser_error (parser, "expected integer expression");
14341       else if (t == error_mark_node
14342 	  || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
14343 	return list;
14344     }
14345   else
14346     t = c_fully_fold (t, false, NULL);
14347 
14348   check_no_duplicate_clause (list, OMP_CLAUSE_ASYNC, "async");
14349 
14350   c = build_omp_clause (loc, OMP_CLAUSE_ASYNC);
14351   OMP_CLAUSE_ASYNC_EXPR (c) = t;
14352   OMP_CLAUSE_CHAIN (c) = list;
14353   list = c;
14354 
14355   return list;
14356 }
14357 
14358 /* OpenACC 2.0:
14359    tile ( size-expr-list ) */
14360 
14361 static tree
c_parser_oacc_clause_tile(c_parser * parser,tree list)14362 c_parser_oacc_clause_tile (c_parser *parser, tree list)
14363 {
14364   tree c, expr = error_mark_node;
14365   location_t loc;
14366   tree tile = NULL_TREE;
14367 
14368   check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
14369   check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
14370 
14371   loc = c_parser_peek_token (parser)->location;
14372   if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
14373     return list;
14374 
14375   do
14376     {
14377       if (tile && !c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
14378 	return list;
14379 
14380       if (c_parser_next_token_is (parser, CPP_MULT)
14381 	  && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
14382 	      || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
14383 	{
14384 	  c_parser_consume_token (parser);
14385 	  expr = integer_zero_node;
14386 	}
14387       else
14388 	{
14389 	  location_t expr_loc = c_parser_peek_token (parser)->location;
14390 	  c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
14391 	  cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
14392 	  expr = cexpr.value;
14393 
14394 	  if (expr == error_mark_node)
14395 	    {
14396 	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
14397 					 "expected %<)%>");
14398 	      return list;
14399 	    }
14400 
14401 	  expr = c_fully_fold (expr, false, NULL);
14402 
14403 	  if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
14404 	      || !tree_fits_shwi_p (expr)
14405 	      || tree_to_shwi (expr) <= 0)
14406 	    {
14407 	      error_at (expr_loc, "%<tile%> argument needs positive"
14408 			" integral constant");
14409 	      expr = integer_zero_node;
14410 	    }
14411 	}
14412 
14413       tile = tree_cons (NULL_TREE, expr, tile);
14414     }
14415   while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN));
14416 
14417   /* Consume the trailing ')'.  */
14418   c_parser_consume_token (parser);
14419 
14420   c = build_omp_clause (loc, OMP_CLAUSE_TILE);
14421   tile = nreverse (tile);
14422   OMP_CLAUSE_TILE_LIST (c) = tile;
14423   OMP_CLAUSE_CHAIN (c) = list;
14424   return c;
14425 }
14426 
14427 /* OpenACC:
14428    wait [( int-expr-list )] */
14429 
14430 static tree
c_parser_oacc_clause_wait(c_parser * parser,tree list)14431 c_parser_oacc_clause_wait (c_parser *parser, tree list)
14432 {
14433   location_t clause_loc = c_parser_peek_token (parser)->location;
14434 
14435   if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
14436     list = c_parser_oacc_wait_list (parser, clause_loc, list);
14437   else
14438     {
14439       tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
14440 
14441       OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
14442       OMP_CLAUSE_CHAIN (c) = list;
14443       list = c;
14444     }
14445 
14446   return list;
14447 }
14448 
14449 
14450 /* OpenMP 5.0:
14451    order ( concurrent ) */
14452 
14453 static tree
c_parser_omp_clause_order(c_parser * parser,tree list)14454 c_parser_omp_clause_order (c_parser *parser, tree list)
14455 {
14456   location_t loc = c_parser_peek_token (parser)->location;
14457   tree c;
14458   const char *p;
14459 
14460   matching_parens parens;
14461   if (!parens.require_open (parser))
14462     return list;
14463   if (!c_parser_next_token_is (parser, CPP_NAME))
14464     {
14465       c_parser_error (parser, "expected %<concurrent%>");
14466       goto out_err;
14467     }
14468   p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14469   if (strcmp (p, "concurrent") != 0)
14470     {
14471       c_parser_error (parser, "expected %<concurrent%>");
14472       goto out_err;
14473     }
14474   c_parser_consume_token (parser);
14475   parens.skip_until_found_close (parser);
14476   /* check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order"); */
14477   c = build_omp_clause (loc, OMP_CLAUSE_ORDER);
14478   OMP_CLAUSE_CHAIN (c) = list;
14479   return c;
14480 
14481  out_err:
14482   parens.skip_until_found_close (parser);
14483   return list;
14484 }
14485 
14486 
14487 /* OpenMP 5.0:
14488    bind ( teams | parallel | thread ) */
14489 
14490 static tree
c_parser_omp_clause_bind(c_parser * parser,tree list)14491 c_parser_omp_clause_bind (c_parser *parser, tree list)
14492 {
14493   location_t loc = c_parser_peek_token (parser)->location;
14494   tree c;
14495   const char *p;
14496   enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
14497 
14498   matching_parens parens;
14499   if (!parens.require_open (parser))
14500     return list;
14501   if (!c_parser_next_token_is (parser, CPP_NAME))
14502     {
14503      invalid:
14504       c_parser_error (parser,
14505 		      "expected %<teams%>, %<parallel%> or %<thread%>");
14506       parens.skip_until_found_close (parser);
14507       return list;
14508     }
14509   p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14510   if (strcmp (p, "teams") == 0)
14511     kind = OMP_CLAUSE_BIND_TEAMS;
14512   else if (strcmp (p, "parallel") == 0)
14513     kind = OMP_CLAUSE_BIND_PARALLEL;
14514   else if (strcmp (p, "thread") != 0)
14515     goto invalid;
14516   c_parser_consume_token (parser);
14517   parens.skip_until_found_close (parser);
14518   /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
14519   c = build_omp_clause (loc, OMP_CLAUSE_BIND);
14520   OMP_CLAUSE_BIND_KIND (c) = kind;
14521   OMP_CLAUSE_CHAIN (c) = list;
14522   return c;
14523 }
14524 
14525 
14526 /* OpenMP 2.5:
14527    ordered
14528 
14529    OpenMP 4.5:
14530    ordered ( constant-expression ) */
14531 
14532 static tree
c_parser_omp_clause_ordered(c_parser * parser,tree list)14533 c_parser_omp_clause_ordered (c_parser *parser, tree list)
14534 {
14535   check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered");
14536 
14537   tree c, num = NULL_TREE;
14538   HOST_WIDE_INT n;
14539   location_t loc = c_parser_peek_token (parser)->location;
14540   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14541     {
14542       matching_parens parens;
14543       parens.consume_open (parser);
14544       num = c_parser_expr_no_commas (parser, NULL).value;
14545       parens.skip_until_found_close (parser);
14546     }
14547   if (num == error_mark_node)
14548     return list;
14549   if (num)
14550     {
14551       mark_exp_read (num);
14552       num = c_fully_fold (num, false, NULL);
14553       if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
14554 	  || !tree_fits_shwi_p (num)
14555 	  || (n = tree_to_shwi (num)) <= 0
14556 	  || (int) n != n)
14557 	{
14558 	  error_at (loc, "ordered argument needs positive "
14559 			 "constant integer expression");
14560 	  return list;
14561 	}
14562     }
14563   c = build_omp_clause (loc, OMP_CLAUSE_ORDERED);
14564   OMP_CLAUSE_ORDERED_EXPR (c) = num;
14565   OMP_CLAUSE_CHAIN (c) = list;
14566   return c;
14567 }
14568 
14569 /* OpenMP 2.5:
14570    private ( variable-list ) */
14571 
14572 static tree
c_parser_omp_clause_private(c_parser * parser,tree list)14573 c_parser_omp_clause_private (c_parser *parser, tree list)
14574 {
14575   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_PRIVATE, list);
14576 }
14577 
14578 /* OpenMP 2.5:
14579    reduction ( reduction-operator : variable-list )
14580 
14581    reduction-operator:
14582      One of: + * - & ^ | && ||
14583 
14584    OpenMP 3.1:
14585 
14586    reduction-operator:
14587      One of: + * - & ^ | && || max min
14588 
14589    OpenMP 4.0:
14590 
14591    reduction-operator:
14592      One of: + * - & ^ | && ||
14593      identifier
14594 
14595    OpenMP 5.0:
14596    reduction ( reduction-modifier, reduction-operator : variable-list )
14597    in_reduction ( reduction-operator : variable-list )
14598    task_reduction ( reduction-operator : variable-list )  */
14599 
14600 static tree
c_parser_omp_clause_reduction(c_parser * parser,enum omp_clause_code kind,bool is_omp,tree list)14601 c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind,
14602 			       bool is_omp, tree list)
14603 {
14604   location_t clause_loc = c_parser_peek_token (parser)->location;
14605   matching_parens parens;
14606   if (parens.require_open (parser))
14607     {
14608       bool task = false;
14609       bool inscan = false;
14610       enum tree_code code = ERROR_MARK;
14611       tree reduc_id = NULL_TREE;
14612 
14613       if (kind == OMP_CLAUSE_REDUCTION && is_omp)
14614 	{
14615 	  if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)
14616 	      && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
14617 	    {
14618 	      c_parser_consume_token (parser);
14619 	      c_parser_consume_token (parser);
14620 	    }
14621 	  else if (c_parser_next_token_is (parser, CPP_NAME)
14622 		   && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
14623 	    {
14624 	      const char *p
14625 		= IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14626 	      if (strcmp (p, "task") == 0)
14627 		task = true;
14628 	      else if (strcmp (p, "inscan") == 0)
14629 		inscan = true;
14630 	      if (task || inscan)
14631 		{
14632 		  c_parser_consume_token (parser);
14633 		  c_parser_consume_token (parser);
14634 		}
14635 	    }
14636 	}
14637 
14638       switch (c_parser_peek_token (parser)->type)
14639 	{
14640 	case CPP_PLUS:
14641 	  code = PLUS_EXPR;
14642 	  break;
14643 	case CPP_MULT:
14644 	  code = MULT_EXPR;
14645 	  break;
14646 	case CPP_MINUS:
14647 	  code = MINUS_EXPR;
14648 	  break;
14649 	case CPP_AND:
14650 	  code = BIT_AND_EXPR;
14651 	  break;
14652 	case CPP_XOR:
14653 	  code = BIT_XOR_EXPR;
14654 	  break;
14655 	case CPP_OR:
14656 	  code = BIT_IOR_EXPR;
14657 	  break;
14658 	case CPP_AND_AND:
14659 	  code = TRUTH_ANDIF_EXPR;
14660 	  break;
14661 	case CPP_OR_OR:
14662 	  code = TRUTH_ORIF_EXPR;
14663 	  break;
14664         case CPP_NAME:
14665 	  {
14666 	    const char *p
14667 	      = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14668 	    if (strcmp (p, "min") == 0)
14669 	      {
14670 		code = MIN_EXPR;
14671 		break;
14672 	      }
14673 	    if (strcmp (p, "max") == 0)
14674 	      {
14675 		code = MAX_EXPR;
14676 		break;
14677 	      }
14678 	    reduc_id = c_parser_peek_token (parser)->value;
14679 	    break;
14680 	  }
14681 	default:
14682 	  c_parser_error (parser,
14683 			  "expected %<+%>, %<*%>, %<-%>, %<&%>, "
14684 			  "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
14685 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
14686 	  return list;
14687 	}
14688       c_parser_consume_token (parser);
14689       reduc_id = c_omp_reduction_id (code, reduc_id);
14690       if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14691 	{
14692 	  tree nl, c;
14693 
14694 	  nl = c_parser_omp_variable_list (parser, clause_loc, kind, list);
14695 	  for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
14696 	    {
14697 	      tree d = OMP_CLAUSE_DECL (c), type;
14698 	      if (TREE_CODE (d) != TREE_LIST)
14699 		type = TREE_TYPE (d);
14700 	      else
14701 		{
14702 		  int cnt = 0;
14703 		  tree t;
14704 		  for (t = d; TREE_CODE (t) == TREE_LIST; t = TREE_CHAIN (t))
14705 		    cnt++;
14706 		  type = TREE_TYPE (t);
14707 		  while (cnt > 0)
14708 		    {
14709 		      if (TREE_CODE (type) != POINTER_TYPE
14710 			  && TREE_CODE (type) != ARRAY_TYPE)
14711 			break;
14712 		      type = TREE_TYPE (type);
14713 		      cnt--;
14714 		    }
14715 		}
14716 	      while (TREE_CODE (type) == ARRAY_TYPE)
14717 		type = TREE_TYPE (type);
14718 	      OMP_CLAUSE_REDUCTION_CODE (c) = code;
14719 	      if (task)
14720 		OMP_CLAUSE_REDUCTION_TASK (c) = 1;
14721 	      else if (inscan)
14722 		OMP_CLAUSE_REDUCTION_INSCAN (c) = 1;
14723 	      if (code == ERROR_MARK
14724 		  || !(INTEGRAL_TYPE_P (type)
14725 		       || TREE_CODE (type) == REAL_TYPE
14726 		       || TREE_CODE (type) == COMPLEX_TYPE))
14727 		OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
14728 		  = c_omp_reduction_lookup (reduc_id,
14729 					    TYPE_MAIN_VARIANT (type));
14730 	    }
14731 
14732 	  list = nl;
14733 	}
14734       parens.skip_until_found_close (parser);
14735     }
14736   return list;
14737 }
14738 
14739 /* OpenMP 2.5:
14740    schedule ( schedule-kind )
14741    schedule ( schedule-kind , expression )
14742 
14743    schedule-kind:
14744      static | dynamic | guided | runtime | auto
14745 
14746    OpenMP 4.5:
14747    schedule ( schedule-modifier : schedule-kind )
14748    schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
14749 
14750    schedule-modifier:
14751      simd
14752      monotonic
14753      nonmonotonic  */
14754 
14755 static tree
c_parser_omp_clause_schedule(c_parser * parser,tree list)14756 c_parser_omp_clause_schedule (c_parser *parser, tree list)
14757 {
14758   tree c, t;
14759   location_t loc = c_parser_peek_token (parser)->location;
14760   int modifiers = 0, nmodifiers = 0;
14761 
14762   matching_parens parens;
14763   if (!parens.require_open (parser))
14764     return list;
14765 
14766   c = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE);
14767 
14768   location_t comma = UNKNOWN_LOCATION;
14769   while (c_parser_next_token_is (parser, CPP_NAME))
14770     {
14771       tree kind = c_parser_peek_token (parser)->value;
14772       const char *p = IDENTIFIER_POINTER (kind);
14773       if (strcmp ("simd", p) == 0)
14774 	OMP_CLAUSE_SCHEDULE_SIMD (c) = 1;
14775       else if (strcmp ("monotonic", p) == 0)
14776 	modifiers |= OMP_CLAUSE_SCHEDULE_MONOTONIC;
14777       else if (strcmp ("nonmonotonic", p) == 0)
14778 	modifiers |= OMP_CLAUSE_SCHEDULE_NONMONOTONIC;
14779       else
14780 	break;
14781       comma = UNKNOWN_LOCATION;
14782       c_parser_consume_token (parser);
14783       if (nmodifiers++ == 0
14784 	  && c_parser_next_token_is (parser, CPP_COMMA))
14785 	{
14786 	  comma = c_parser_peek_token (parser)->location;
14787 	  c_parser_consume_token (parser);
14788 	}
14789       else
14790 	{
14791 	  c_parser_require (parser, CPP_COLON, "expected %<:%>");
14792 	  break;
14793 	}
14794     }
14795   if (comma != UNKNOWN_LOCATION)
14796     error_at (comma, "expected %<:%>");
14797 
14798   if ((modifiers & (OMP_CLAUSE_SCHEDULE_MONOTONIC
14799 		    | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
14800       == (OMP_CLAUSE_SCHEDULE_MONOTONIC
14801 	  | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
14802     {
14803       error_at (loc, "both %<monotonic%> and %<nonmonotonic%> modifiers "
14804 		     "specified");
14805       modifiers = 0;
14806     }
14807 
14808   if (c_parser_next_token_is (parser, CPP_NAME))
14809     {
14810       tree kind = c_parser_peek_token (parser)->value;
14811       const char *p = IDENTIFIER_POINTER (kind);
14812 
14813       switch (p[0])
14814 	{
14815 	case 'd':
14816 	  if (strcmp ("dynamic", p) != 0)
14817 	    goto invalid_kind;
14818 	  OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
14819 	  break;
14820 
14821         case 'g':
14822 	  if (strcmp ("guided", p) != 0)
14823 	    goto invalid_kind;
14824 	  OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
14825 	  break;
14826 
14827 	case 'r':
14828 	  if (strcmp ("runtime", p) != 0)
14829 	    goto invalid_kind;
14830 	  OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
14831 	  break;
14832 
14833 	default:
14834 	  goto invalid_kind;
14835 	}
14836     }
14837   else if (c_parser_next_token_is_keyword (parser, RID_STATIC))
14838     OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
14839   else if (c_parser_next_token_is_keyword (parser, RID_AUTO))
14840     OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
14841   else
14842     goto invalid_kind;
14843 
14844   c_parser_consume_token (parser);
14845   if (c_parser_next_token_is (parser, CPP_COMMA))
14846     {
14847       location_t here;
14848       c_parser_consume_token (parser);
14849 
14850       here = c_parser_peek_token (parser)->location;
14851       c_expr expr = c_parser_expr_no_commas (parser, NULL);
14852       expr = convert_lvalue_to_rvalue (here, expr, false, true);
14853       t = expr.value;
14854       t = c_fully_fold (t, false, NULL);
14855 
14856       if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
14857 	error_at (here, "schedule %<runtime%> does not take "
14858 		  "a %<chunk_size%> parameter");
14859       else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO)
14860 	error_at (here,
14861 		  "schedule %<auto%> does not take "
14862 		  "a %<chunk_size%> parameter");
14863       else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE)
14864 	{
14865 	  /* Attempt to statically determine when the number isn't
14866 	     positive.  */
14867 	  tree s = fold_build2_loc (loc, LE_EXPR, boolean_type_node, t,
14868 				    build_int_cst (TREE_TYPE (t), 0));
14869 	  protected_set_expr_location (s, loc);
14870 	  if (s == boolean_true_node)
14871 	    {
14872 	      warning_at (loc, 0,
14873 			  "chunk size value must be positive");
14874 	      t = integer_one_node;
14875 	    }
14876 	  OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
14877 	}
14878       else
14879 	c_parser_error (parser, "expected integer expression");
14880 
14881       parens.skip_until_found_close (parser);
14882     }
14883   else
14884     c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
14885 			       "expected %<,%> or %<)%>");
14886 
14887   OMP_CLAUSE_SCHEDULE_KIND (c)
14888     = (enum omp_clause_schedule_kind)
14889       (OMP_CLAUSE_SCHEDULE_KIND (c) | modifiers);
14890 
14891   check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule");
14892   OMP_CLAUSE_CHAIN (c) = list;
14893   return c;
14894 
14895  invalid_kind:
14896   c_parser_error (parser, "invalid schedule kind");
14897   c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
14898   return list;
14899 }
14900 
14901 /* OpenMP 2.5:
14902    shared ( variable-list ) */
14903 
14904 static tree
c_parser_omp_clause_shared(c_parser * parser,tree list)14905 c_parser_omp_clause_shared (c_parser *parser, tree list)
14906 {
14907   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_SHARED, list);
14908 }
14909 
14910 /* OpenMP 3.0:
14911    untied */
14912 
14913 static tree
c_parser_omp_clause_untied(c_parser * parser ATTRIBUTE_UNUSED,tree list)14914 c_parser_omp_clause_untied (c_parser *parser ATTRIBUTE_UNUSED, tree list)
14915 {
14916   tree c;
14917 
14918   /* FIXME: Should we allow duplicates?  */
14919   check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied");
14920 
14921   c = build_omp_clause (c_parser_peek_token (parser)->location,
14922 			OMP_CLAUSE_UNTIED);
14923   OMP_CLAUSE_CHAIN (c) = list;
14924 
14925   return c;
14926 }
14927 
14928 /* OpenMP 4.0:
14929    inbranch
14930    notinbranch */
14931 
14932 static tree
c_parser_omp_clause_branch(c_parser * parser ATTRIBUTE_UNUSED,enum omp_clause_code code,tree list)14933 c_parser_omp_clause_branch (c_parser *parser ATTRIBUTE_UNUSED,
14934 			    enum omp_clause_code code, tree list)
14935 {
14936   check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14937 
14938   tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
14939   OMP_CLAUSE_CHAIN (c) = list;
14940 
14941   return c;
14942 }
14943 
14944 /* OpenMP 4.0:
14945    parallel
14946    for
14947    sections
14948    taskgroup */
14949 
14950 static tree
c_parser_omp_clause_cancelkind(c_parser * parser ATTRIBUTE_UNUSED,enum omp_clause_code code,tree list)14951 c_parser_omp_clause_cancelkind (c_parser *parser ATTRIBUTE_UNUSED,
14952 				enum omp_clause_code code, tree list)
14953 {
14954   tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
14955   OMP_CLAUSE_CHAIN (c) = list;
14956 
14957   return c;
14958 }
14959 
14960 /* OpenMP 4.5:
14961    nogroup */
14962 
14963 static tree
c_parser_omp_clause_nogroup(c_parser * parser ATTRIBUTE_UNUSED,tree list)14964 c_parser_omp_clause_nogroup (c_parser *parser ATTRIBUTE_UNUSED, tree list)
14965 {
14966   check_no_duplicate_clause (list, OMP_CLAUSE_NOGROUP, "nogroup");
14967   tree c = build_omp_clause (c_parser_peek_token (parser)->location,
14968 			     OMP_CLAUSE_NOGROUP);
14969   OMP_CLAUSE_CHAIN (c) = list;
14970   return c;
14971 }
14972 
14973 /* OpenMP 4.5:
14974    simd
14975    threads */
14976 
14977 static tree
c_parser_omp_clause_orderedkind(c_parser * parser ATTRIBUTE_UNUSED,enum omp_clause_code code,tree list)14978 c_parser_omp_clause_orderedkind (c_parser *parser ATTRIBUTE_UNUSED,
14979 				 enum omp_clause_code code, tree list)
14980 {
14981   check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14982   tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
14983   OMP_CLAUSE_CHAIN (c) = list;
14984   return c;
14985 }
14986 
14987 /* OpenMP 4.0:
14988    num_teams ( expression ) */
14989 
14990 static tree
c_parser_omp_clause_num_teams(c_parser * parser,tree list)14991 c_parser_omp_clause_num_teams (c_parser *parser, tree list)
14992 {
14993   location_t num_teams_loc = c_parser_peek_token (parser)->location;
14994   matching_parens parens;
14995   if (parens.require_open (parser))
14996     {
14997       location_t expr_loc = c_parser_peek_token (parser)->location;
14998       c_expr expr = c_parser_expr_no_commas (parser, NULL);
14999       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15000       tree c, t = expr.value;
15001       t = c_fully_fold (t, false, NULL);
15002 
15003       parens.skip_until_found_close (parser);
15004 
15005       if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
15006 	{
15007 	  c_parser_error (parser, "expected integer expression");
15008 	  return list;
15009 	}
15010 
15011       /* Attempt to statically determine when the number isn't positive.  */
15012       c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
15013 			   build_int_cst (TREE_TYPE (t), 0));
15014       protected_set_expr_location (c, expr_loc);
15015       if (c == boolean_true_node)
15016 	{
15017 	  warning_at (expr_loc, 0, "%<num_teams%> value must be positive");
15018 	  t = integer_one_node;
15019 	}
15020 
15021       check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TEAMS, "num_teams");
15022 
15023       c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
15024       OMP_CLAUSE_NUM_TEAMS_EXPR (c) = t;
15025       OMP_CLAUSE_CHAIN (c) = list;
15026       list = c;
15027     }
15028 
15029   return list;
15030 }
15031 
15032 /* OpenMP 4.0:
15033    thread_limit ( expression ) */
15034 
15035 static tree
c_parser_omp_clause_thread_limit(c_parser * parser,tree list)15036 c_parser_omp_clause_thread_limit (c_parser *parser, tree list)
15037 {
15038   location_t num_thread_limit_loc = c_parser_peek_token (parser)->location;
15039   matching_parens parens;
15040   if (parens.require_open (parser))
15041     {
15042       location_t expr_loc = c_parser_peek_token (parser)->location;
15043       c_expr expr = c_parser_expr_no_commas (parser, NULL);
15044       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15045       tree c, t = expr.value;
15046       t = c_fully_fold (t, false, NULL);
15047 
15048       parens.skip_until_found_close (parser);
15049 
15050       if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
15051 	{
15052 	  c_parser_error (parser, "expected integer expression");
15053 	  return list;
15054 	}
15055 
15056       /* Attempt to statically determine when the number isn't positive.  */
15057       c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
15058 			   build_int_cst (TREE_TYPE (t), 0));
15059       protected_set_expr_location (c, expr_loc);
15060       if (c == boolean_true_node)
15061 	{
15062 	  warning_at (expr_loc, 0, "%<thread_limit%> value must be positive");
15063 	  t = integer_one_node;
15064 	}
15065 
15066       check_no_duplicate_clause (list, OMP_CLAUSE_THREAD_LIMIT,
15067 				 "thread_limit");
15068 
15069       c = build_omp_clause (num_thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
15070       OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
15071       OMP_CLAUSE_CHAIN (c) = list;
15072       list = c;
15073     }
15074 
15075   return list;
15076 }
15077 
15078 /* OpenMP 4.0:
15079    aligned ( variable-list )
15080    aligned ( variable-list : constant-expression ) */
15081 
15082 static tree
c_parser_omp_clause_aligned(c_parser * parser,tree list)15083 c_parser_omp_clause_aligned (c_parser *parser, tree list)
15084 {
15085   location_t clause_loc = c_parser_peek_token (parser)->location;
15086   tree nl, c;
15087 
15088   matching_parens parens;
15089   if (!parens.require_open (parser))
15090     return list;
15091 
15092   nl = c_parser_omp_variable_list (parser, clause_loc,
15093 				   OMP_CLAUSE_ALIGNED, list);
15094 
15095   if (c_parser_next_token_is (parser, CPP_COLON))
15096     {
15097       c_parser_consume_token (parser);
15098       location_t expr_loc = c_parser_peek_token (parser)->location;
15099       c_expr expr = c_parser_expr_no_commas (parser, NULL);
15100       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15101       tree alignment = expr.value;
15102       alignment = c_fully_fold (alignment, false, NULL);
15103       if (TREE_CODE (alignment) != INTEGER_CST
15104 	  || !INTEGRAL_TYPE_P (TREE_TYPE (alignment))
15105 	  || tree_int_cst_sgn (alignment) != 1)
15106 	{
15107 	  error_at (clause_loc, "%<aligned%> clause alignment expression must "
15108 				"be positive constant integer expression");
15109 	  alignment = NULL_TREE;
15110 	}
15111 
15112       for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15113 	OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = alignment;
15114     }
15115 
15116   parens.skip_until_found_close (parser);
15117   return nl;
15118 }
15119 
15120 /* OpenMP 5.0:
15121    allocate ( variable-list )
15122    allocate ( expression : variable-list ) */
15123 
15124 static tree
c_parser_omp_clause_allocate(c_parser * parser,tree list)15125 c_parser_omp_clause_allocate (c_parser *parser, tree list)
15126 {
15127   location_t clause_loc = c_parser_peek_token (parser)->location;
15128   tree nl, c;
15129   tree allocator = NULL_TREE;
15130 
15131   matching_parens parens;
15132   if (!parens.require_open (parser))
15133     return list;
15134 
15135   if ((c_parser_next_token_is_not (parser, CPP_NAME)
15136        && c_parser_next_token_is_not (parser, CPP_KEYWORD))
15137       || (c_parser_peek_2nd_token (parser)->type != CPP_COMMA
15138 	  && c_parser_peek_2nd_token (parser)->type != CPP_CLOSE_PAREN))
15139     {
15140       location_t expr_loc = c_parser_peek_token (parser)->location;
15141       c_expr expr = c_parser_expr_no_commas (parser, NULL);
15142       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15143       allocator = expr.value;
15144       allocator = c_fully_fold (allocator, false, NULL);
15145       tree orig_type
15146 	= expr.original_type ? expr.original_type : TREE_TYPE (allocator);
15147       orig_type = TYPE_MAIN_VARIANT (orig_type);
15148       if (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
15149 	  || TREE_CODE (orig_type) != ENUMERAL_TYPE
15150 	  || TYPE_NAME (orig_type) != get_identifier ("omp_allocator_handle_t"))
15151         {
15152           error_at (clause_loc, "%<allocate%> clause allocator expression "
15153 				"has type %qT rather than "
15154 				"%<omp_allocator_handle_t%>",
15155 				TREE_TYPE (allocator));
15156           allocator = NULL_TREE;
15157         }
15158       if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15159 	{
15160 	  parens.skip_until_found_close (parser);
15161 	  return list;
15162 	}
15163     }
15164 
15165   nl = c_parser_omp_variable_list (parser, clause_loc,
15166 				   OMP_CLAUSE_ALLOCATE, list);
15167 
15168   if (allocator)
15169     for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15170       OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
15171 
15172   parens.skip_until_found_close (parser);
15173   return nl;
15174 }
15175 
15176 /* OpenMP 4.0:
15177    linear ( variable-list )
15178    linear ( variable-list : expression )
15179 
15180    OpenMP 4.5:
15181    linear ( modifier ( variable-list ) )
15182    linear ( modifier ( variable-list ) : expression ) */
15183 
15184 static tree
c_parser_omp_clause_linear(c_parser * parser,tree list)15185 c_parser_omp_clause_linear (c_parser *parser, tree list)
15186 {
15187   location_t clause_loc = c_parser_peek_token (parser)->location;
15188   tree nl, c, step;
15189   enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
15190 
15191   matching_parens parens;
15192   if (!parens.require_open (parser))
15193     return list;
15194 
15195   if (c_parser_next_token_is (parser, CPP_NAME))
15196     {
15197       c_token *tok = c_parser_peek_token (parser);
15198       const char *p = IDENTIFIER_POINTER (tok->value);
15199       if (strcmp ("val", p) == 0)
15200 	kind = OMP_CLAUSE_LINEAR_VAL;
15201       if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN)
15202 	kind = OMP_CLAUSE_LINEAR_DEFAULT;
15203       if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
15204 	{
15205 	  c_parser_consume_token (parser);
15206 	  c_parser_consume_token (parser);
15207 	}
15208     }
15209 
15210   nl = c_parser_omp_variable_list (parser, clause_loc,
15211 				   OMP_CLAUSE_LINEAR, list);
15212 
15213   if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
15214     parens.skip_until_found_close (parser);
15215 
15216   if (c_parser_next_token_is (parser, CPP_COLON))
15217     {
15218       c_parser_consume_token (parser);
15219       location_t expr_loc = c_parser_peek_token (parser)->location;
15220       c_expr expr = c_parser_expr_no_commas (parser, NULL);
15221       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15222       step = expr.value;
15223       step = c_fully_fold (step, false, NULL);
15224       if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
15225 	{
15226 	  error_at (clause_loc, "%<linear%> clause step expression must "
15227 				"be integral");
15228 	  step = integer_one_node;
15229 	}
15230 
15231     }
15232   else
15233     step = integer_one_node;
15234 
15235   for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15236     {
15237       OMP_CLAUSE_LINEAR_STEP (c) = step;
15238       OMP_CLAUSE_LINEAR_KIND (c) = kind;
15239     }
15240 
15241   parens.skip_until_found_close (parser);
15242   return nl;
15243 }
15244 
15245 /* OpenMP 5.0:
15246    nontemporal ( variable-list ) */
15247 
15248 static tree
c_parser_omp_clause_nontemporal(c_parser * parser,tree list)15249 c_parser_omp_clause_nontemporal (c_parser *parser, tree list)
15250 {
15251   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_NONTEMPORAL, list);
15252 }
15253 
15254 /* OpenMP 4.0:
15255    safelen ( constant-expression ) */
15256 
15257 static tree
c_parser_omp_clause_safelen(c_parser * parser,tree list)15258 c_parser_omp_clause_safelen (c_parser *parser, tree list)
15259 {
15260   location_t clause_loc = c_parser_peek_token (parser)->location;
15261   tree c, t;
15262 
15263   matching_parens parens;
15264   if (!parens.require_open (parser))
15265     return list;
15266 
15267   location_t expr_loc = c_parser_peek_token (parser)->location;
15268   c_expr expr = c_parser_expr_no_commas (parser, NULL);
15269   expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15270   t = expr.value;
15271   t = c_fully_fold (t, false, NULL);
15272   if (TREE_CODE (t) != INTEGER_CST
15273       || !INTEGRAL_TYPE_P (TREE_TYPE (t))
15274       || tree_int_cst_sgn (t) != 1)
15275     {
15276       error_at (clause_loc, "%<safelen%> clause expression must "
15277 			    "be positive constant integer expression");
15278       t = NULL_TREE;
15279     }
15280 
15281   parens.skip_until_found_close (parser);
15282   if (t == NULL_TREE || t == error_mark_node)
15283     return list;
15284 
15285   check_no_duplicate_clause (list, OMP_CLAUSE_SAFELEN, "safelen");
15286 
15287   c = build_omp_clause (clause_loc, OMP_CLAUSE_SAFELEN);
15288   OMP_CLAUSE_SAFELEN_EXPR (c) = t;
15289   OMP_CLAUSE_CHAIN (c) = list;
15290   return c;
15291 }
15292 
15293 /* OpenMP 4.0:
15294    simdlen ( constant-expression ) */
15295 
15296 static tree
c_parser_omp_clause_simdlen(c_parser * parser,tree list)15297 c_parser_omp_clause_simdlen (c_parser *parser, tree list)
15298 {
15299   location_t clause_loc = c_parser_peek_token (parser)->location;
15300   tree c, t;
15301 
15302   matching_parens parens;
15303   if (!parens.require_open (parser))
15304     return list;
15305 
15306   location_t expr_loc = c_parser_peek_token (parser)->location;
15307   c_expr expr = c_parser_expr_no_commas (parser, NULL);
15308   expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15309   t = expr.value;
15310   t = c_fully_fold (t, false, NULL);
15311   if (TREE_CODE (t) != INTEGER_CST
15312       || !INTEGRAL_TYPE_P (TREE_TYPE (t))
15313       || tree_int_cst_sgn (t) != 1)
15314     {
15315       error_at (clause_loc, "%<simdlen%> clause expression must "
15316 			    "be positive constant integer expression");
15317       t = NULL_TREE;
15318     }
15319 
15320   parens.skip_until_found_close (parser);
15321   if (t == NULL_TREE || t == error_mark_node)
15322     return list;
15323 
15324   check_no_duplicate_clause (list, OMP_CLAUSE_SIMDLEN, "simdlen");
15325 
15326   c = build_omp_clause (clause_loc, OMP_CLAUSE_SIMDLEN);
15327   OMP_CLAUSE_SIMDLEN_EXPR (c) = t;
15328   OMP_CLAUSE_CHAIN (c) = list;
15329   return c;
15330 }
15331 
15332 /* OpenMP 4.5:
15333    vec:
15334      identifier [+/- integer]
15335      vec , identifier [+/- integer]
15336 */
15337 
15338 static tree
c_parser_omp_clause_depend_sink(c_parser * parser,location_t clause_loc,tree list)15339 c_parser_omp_clause_depend_sink (c_parser *parser, location_t clause_loc,
15340 				 tree list)
15341 {
15342   tree vec = NULL;
15343   if (c_parser_next_token_is_not (parser, CPP_NAME)
15344       || c_parser_peek_token (parser)->id_kind != C_ID_ID)
15345     {
15346       c_parser_error (parser, "expected identifier");
15347       return list;
15348     }
15349 
15350   while (c_parser_next_token_is (parser, CPP_NAME)
15351 	 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
15352     {
15353       tree t = lookup_name (c_parser_peek_token (parser)->value);
15354       tree addend = NULL;
15355 
15356       if (t == NULL_TREE)
15357 	{
15358 	  undeclared_variable (c_parser_peek_token (parser)->location,
15359 			       c_parser_peek_token (parser)->value);
15360 	  t = error_mark_node;
15361 	}
15362 
15363       c_parser_consume_token (parser);
15364 
15365       bool neg = false;
15366       if (c_parser_next_token_is (parser, CPP_MINUS))
15367 	neg = true;
15368       else if (!c_parser_next_token_is (parser, CPP_PLUS))
15369 	{
15370 	  addend = integer_zero_node;
15371 	  neg = false;
15372 	  goto add_to_vector;
15373 	}
15374       c_parser_consume_token (parser);
15375 
15376       if (c_parser_next_token_is_not (parser, CPP_NUMBER))
15377 	{
15378 	  c_parser_error (parser, "expected integer");
15379 	  return list;
15380 	}
15381 
15382       addend = c_parser_peek_token (parser)->value;
15383       if (TREE_CODE (addend) != INTEGER_CST)
15384 	{
15385 	  c_parser_error (parser, "expected integer");
15386 	  return list;
15387 	}
15388       c_parser_consume_token (parser);
15389 
15390     add_to_vector:
15391       if (t != error_mark_node)
15392 	{
15393 	  vec = tree_cons (addend, t, vec);
15394 	  if (neg)
15395 	    OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec) = 1;
15396 	}
15397 
15398       if (c_parser_next_token_is_not (parser, CPP_COMMA))
15399 	break;
15400 
15401       c_parser_consume_token (parser);
15402     }
15403 
15404   if (vec == NULL_TREE)
15405     return list;
15406 
15407   tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
15408   OMP_CLAUSE_DEPEND_KIND (u) = OMP_CLAUSE_DEPEND_SINK;
15409   OMP_CLAUSE_DECL (u) = nreverse (vec);
15410   OMP_CLAUSE_CHAIN (u) = list;
15411   return u;
15412 }
15413 
15414 /* OpenMP 5.0:
15415    iterators ( iterators-definition )
15416 
15417    iterators-definition:
15418      iterator-specifier
15419      iterator-specifier , iterators-definition
15420 
15421    iterator-specifier:
15422      identifier = range-specification
15423      iterator-type identifier = range-specification
15424 
15425    range-specification:
15426      begin : end
15427      begin : end : step  */
15428 
15429 static tree
c_parser_omp_iterators(c_parser * parser)15430 c_parser_omp_iterators (c_parser *parser)
15431 {
15432   tree ret = NULL_TREE, *last = &ret;
15433   c_parser_consume_token (parser);
15434 
15435   push_scope ();
15436 
15437   matching_parens parens;
15438   if (!parens.require_open (parser))
15439     return error_mark_node;
15440 
15441   do
15442     {
15443       tree iter_type = NULL_TREE, type_expr = NULL_TREE;
15444       if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
15445 	{
15446 	  struct c_type_name *type = c_parser_type_name (parser);
15447 	  if (type != NULL)
15448 	    iter_type = groktypename (type, &type_expr, NULL);
15449 	}
15450       if (iter_type == NULL_TREE)
15451 	iter_type = integer_type_node;
15452 
15453       location_t loc = c_parser_peek_token (parser)->location;
15454       if (!c_parser_next_token_is (parser, CPP_NAME))
15455 	{
15456 	  c_parser_error (parser, "expected identifier");
15457 	  break;
15458 	}
15459 
15460       tree id = c_parser_peek_token (parser)->value;
15461       c_parser_consume_token (parser);
15462 
15463       if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
15464 	break;
15465 
15466       location_t eloc = c_parser_peek_token (parser)->location;
15467       c_expr expr = c_parser_expr_no_commas (parser, NULL);
15468       expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
15469       tree begin = expr.value;
15470 
15471       if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15472 	break;
15473 
15474       eloc = c_parser_peek_token (parser)->location;
15475       expr = c_parser_expr_no_commas (parser, NULL);
15476       expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
15477       tree end = expr.value;
15478 
15479       tree step = integer_one_node;
15480       if (c_parser_next_token_is (parser, CPP_COLON))
15481 	{
15482 	  c_parser_consume_token (parser);
15483 	  eloc = c_parser_peek_token (parser)->location;
15484 	  expr = c_parser_expr_no_commas (parser, NULL);
15485 	  expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
15486 	  step = expr.value;
15487 	}
15488 
15489       tree iter_var = build_decl (loc, VAR_DECL, id, iter_type);
15490       DECL_ARTIFICIAL (iter_var) = 1;
15491       DECL_CONTEXT (iter_var) = current_function_decl;
15492       pushdecl (iter_var);
15493 
15494       *last = make_tree_vec (6);
15495       TREE_VEC_ELT (*last, 0) = iter_var;
15496       TREE_VEC_ELT (*last, 1) = begin;
15497       TREE_VEC_ELT (*last, 2) = end;
15498       TREE_VEC_ELT (*last, 3) = step;
15499       last = &TREE_CHAIN (*last);
15500 
15501       if (c_parser_next_token_is (parser, CPP_COMMA))
15502 	{
15503 	  c_parser_consume_token (parser);
15504 	  continue;
15505 	}
15506       break;
15507     }
15508   while (1);
15509 
15510   parens.skip_until_found_close (parser);
15511   return ret ? ret : error_mark_node;
15512 }
15513 
15514 /* OpenMP 4.0:
15515    depend ( depend-kind: variable-list )
15516 
15517    depend-kind:
15518      in | out | inout
15519 
15520    OpenMP 4.5:
15521    depend ( source )
15522 
15523    depend ( sink  : vec )
15524 
15525    OpenMP 5.0:
15526    depend ( depend-modifier , depend-kind: variable-list )
15527 
15528    depend-kind:
15529      in | out | inout | mutexinoutset | depobj
15530 
15531    depend-modifier:
15532      iterator ( iterators-definition )  */
15533 
15534 static tree
c_parser_omp_clause_depend(c_parser * parser,tree list)15535 c_parser_omp_clause_depend (c_parser *parser, tree list)
15536 {
15537   location_t clause_loc = c_parser_peek_token (parser)->location;
15538   enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_LAST;
15539   tree nl, c, iterators = NULL_TREE;
15540 
15541   matching_parens parens;
15542   if (!parens.require_open (parser))
15543     return list;
15544 
15545   do
15546     {
15547       if (c_parser_next_token_is_not (parser, CPP_NAME))
15548 	goto invalid_kind;
15549 
15550       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15551       if (strcmp ("iterator", p) == 0 && iterators == NULL_TREE)
15552 	{
15553 	  iterators = c_parser_omp_iterators (parser);
15554 	  c_parser_require (parser, CPP_COMMA, "expected %<,%>");
15555 	  continue;
15556 	}
15557       if (strcmp ("in", p) == 0)
15558 	kind = OMP_CLAUSE_DEPEND_IN;
15559       else if (strcmp ("inout", p) == 0)
15560 	kind = OMP_CLAUSE_DEPEND_INOUT;
15561       else if (strcmp ("mutexinoutset", p) == 0)
15562 	kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
15563       else if (strcmp ("out", p) == 0)
15564 	kind = OMP_CLAUSE_DEPEND_OUT;
15565       else if (strcmp ("depobj", p) == 0)
15566 	kind = OMP_CLAUSE_DEPEND_DEPOBJ;
15567       else if (strcmp ("sink", p) == 0)
15568 	kind = OMP_CLAUSE_DEPEND_SINK;
15569       else if (strcmp ("source", p) == 0)
15570 	kind = OMP_CLAUSE_DEPEND_SOURCE;
15571       else
15572 	goto invalid_kind;
15573       break;
15574     }
15575   while (1);
15576 
15577   c_parser_consume_token (parser);
15578 
15579   if (iterators
15580       && (kind == OMP_CLAUSE_DEPEND_SOURCE || kind == OMP_CLAUSE_DEPEND_SINK))
15581     {
15582       pop_scope ();
15583       error_at (clause_loc, "%<iterator%> modifier incompatible with %qs",
15584 		kind == OMP_CLAUSE_DEPEND_SOURCE ? "source" : "sink");
15585       iterators = NULL_TREE;
15586     }
15587 
15588   if (kind == OMP_CLAUSE_DEPEND_SOURCE)
15589     {
15590       c = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
15591       OMP_CLAUSE_DEPEND_KIND (c) = kind;
15592       OMP_CLAUSE_DECL (c) = NULL_TREE;
15593       OMP_CLAUSE_CHAIN (c) = list;
15594       parens.skip_until_found_close (parser);
15595       return c;
15596     }
15597 
15598   if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15599     goto resync_fail;
15600 
15601   if (kind == OMP_CLAUSE_DEPEND_SINK)
15602     nl = c_parser_omp_clause_depend_sink (parser, clause_loc, list);
15603   else
15604     {
15605       nl = c_parser_omp_variable_list (parser, clause_loc,
15606 				       OMP_CLAUSE_DEPEND, list);
15607 
15608       if (iterators)
15609 	{
15610 	  tree block = pop_scope ();
15611 	  if (iterators == error_mark_node)
15612 	    iterators = NULL_TREE;
15613 	  else
15614 	    TREE_VEC_ELT (iterators, 5) = block;
15615 	}
15616 
15617       for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15618 	{
15619 	  OMP_CLAUSE_DEPEND_KIND (c) = kind;
15620 	  if (iterators)
15621 	    OMP_CLAUSE_DECL (c)
15622 	      = build_tree_list (iterators, OMP_CLAUSE_DECL (c));
15623 	}
15624     }
15625 
15626   parens.skip_until_found_close (parser);
15627   return nl;
15628 
15629  invalid_kind:
15630   c_parser_error (parser, "invalid depend kind");
15631  resync_fail:
15632   parens.skip_until_found_close (parser);
15633   if (iterators)
15634     pop_scope ();
15635   return list;
15636 }
15637 
15638 /* OpenMP 4.0:
15639    map ( map-kind: variable-list )
15640    map ( variable-list )
15641 
15642    map-kind:
15643      alloc | to | from | tofrom
15644 
15645    OpenMP 4.5:
15646    map-kind:
15647      alloc | to | from | tofrom | release | delete
15648 
15649    map ( always [,] map-kind: variable-list ) */
15650 
15651 static tree
c_parser_omp_clause_map(c_parser * parser,tree list)15652 c_parser_omp_clause_map (c_parser *parser, tree list)
15653 {
15654   location_t clause_loc = c_parser_peek_token (parser)->location;
15655   enum gomp_map_kind kind = GOMP_MAP_TOFROM;
15656   int always = 0;
15657   enum c_id_kind always_id_kind = C_ID_NONE;
15658   location_t always_loc = UNKNOWN_LOCATION;
15659   tree always_id = NULL_TREE;
15660   tree nl, c;
15661 
15662   matching_parens parens;
15663   if (!parens.require_open (parser))
15664     return list;
15665 
15666   if (c_parser_next_token_is (parser, CPP_NAME))
15667     {
15668       c_token *tok = c_parser_peek_token (parser);
15669       const char *p = IDENTIFIER_POINTER (tok->value);
15670       always_id_kind = tok->id_kind;
15671       always_loc = tok->location;
15672       always_id = tok->value;
15673       if (strcmp ("always", p) == 0)
15674 	{
15675 	  c_token *sectok = c_parser_peek_2nd_token (parser);
15676 	  if (sectok->type == CPP_COMMA)
15677 	    {
15678 	      c_parser_consume_token (parser);
15679 	      c_parser_consume_token (parser);
15680 	      always = 2;
15681 	    }
15682 	  else if (sectok->type == CPP_NAME)
15683 	    {
15684 	      p = IDENTIFIER_POINTER (sectok->value);
15685 	      if (strcmp ("alloc", p) == 0
15686 		  || strcmp ("to", p) == 0
15687 		  || strcmp ("from", p) == 0
15688 		  || strcmp ("tofrom", p) == 0
15689 		  || strcmp ("release", p) == 0
15690 		  || strcmp ("delete", p) == 0)
15691 		{
15692 		  c_parser_consume_token (parser);
15693 		  always = 1;
15694 		}
15695 	    }
15696 	}
15697     }
15698 
15699   if (c_parser_next_token_is (parser, CPP_NAME)
15700       && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
15701     {
15702       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15703       if (strcmp ("alloc", p) == 0)
15704 	kind = GOMP_MAP_ALLOC;
15705       else if (strcmp ("to", p) == 0)
15706 	kind = always ? GOMP_MAP_ALWAYS_TO : GOMP_MAP_TO;
15707       else if (strcmp ("from", p) == 0)
15708 	kind = always ? GOMP_MAP_ALWAYS_FROM : GOMP_MAP_FROM;
15709       else if (strcmp ("tofrom", p) == 0)
15710 	kind = always ? GOMP_MAP_ALWAYS_TOFROM : GOMP_MAP_TOFROM;
15711       else if (strcmp ("release", p) == 0)
15712 	kind = GOMP_MAP_RELEASE;
15713       else if (strcmp ("delete", p) == 0)
15714 	kind = GOMP_MAP_DELETE;
15715       else
15716 	{
15717 	  c_parser_error (parser, "invalid map kind");
15718 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
15719 				     "expected %<)%>");
15720 	  return list;
15721 	}
15722       c_parser_consume_token (parser);
15723       c_parser_consume_token (parser);
15724     }
15725   else if (always)
15726     {
15727       if (always_id_kind != C_ID_ID)
15728 	{
15729 	  c_parser_error (parser, "expected identifier");
15730 	  parens.skip_until_found_close (parser);
15731 	  return list;
15732 	}
15733 
15734       tree t = lookup_name (always_id);
15735       if (t == NULL_TREE)
15736 	{
15737 	  undeclared_variable (always_loc, always_id);
15738 	  t = error_mark_node;
15739 	}
15740       if (t != error_mark_node)
15741 	{
15742 	  tree u = build_omp_clause (clause_loc, OMP_CLAUSE_MAP);
15743 	  OMP_CLAUSE_DECL (u) = t;
15744 	  OMP_CLAUSE_CHAIN (u) = list;
15745 	  OMP_CLAUSE_SET_MAP_KIND (u, kind);
15746 	  list = u;
15747 	}
15748       if (always == 1)
15749 	{
15750 	  parens.skip_until_found_close (parser);
15751 	  return list;
15752 	}
15753     }
15754 
15755   nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_MAP, list);
15756 
15757   for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15758     OMP_CLAUSE_SET_MAP_KIND (c, kind);
15759 
15760   parens.skip_until_found_close (parser);
15761   return nl;
15762 }
15763 
15764 /* OpenMP 4.0:
15765    device ( expression ) */
15766 
15767 static tree
c_parser_omp_clause_device(c_parser * parser,tree list)15768 c_parser_omp_clause_device (c_parser *parser, tree list)
15769 {
15770   location_t clause_loc = c_parser_peek_token (parser)->location;
15771   matching_parens parens;
15772   if (parens.require_open (parser))
15773     {
15774       location_t expr_loc = c_parser_peek_token (parser)->location;
15775       c_expr expr = c_parser_expr_no_commas (parser, NULL);
15776       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15777       tree c, t = expr.value;
15778       t = c_fully_fold (t, false, NULL);
15779 
15780       parens.skip_until_found_close (parser);
15781 
15782       if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
15783 	{
15784 	  c_parser_error (parser, "expected integer expression");
15785 	  return list;
15786 	}
15787 
15788       check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE, "device");
15789 
15790       c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE);
15791       OMP_CLAUSE_DEVICE_ID (c) = t;
15792       OMP_CLAUSE_CHAIN (c) = list;
15793       list = c;
15794     }
15795 
15796   return list;
15797 }
15798 
15799 /* OpenMP 4.0:
15800    dist_schedule ( static )
15801    dist_schedule ( static , expression ) */
15802 
15803 static tree
c_parser_omp_clause_dist_schedule(c_parser * parser,tree list)15804 c_parser_omp_clause_dist_schedule (c_parser *parser, tree list)
15805 {
15806   tree c, t = NULL_TREE;
15807   location_t loc = c_parser_peek_token (parser)->location;
15808 
15809   matching_parens parens;
15810   if (!parens.require_open (parser))
15811     return list;
15812 
15813   if (!c_parser_next_token_is_keyword (parser, RID_STATIC))
15814     {
15815       c_parser_error (parser, "invalid dist_schedule kind");
15816       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
15817 				 "expected %<)%>");
15818       return list;
15819     }
15820 
15821   c_parser_consume_token (parser);
15822   if (c_parser_next_token_is (parser, CPP_COMMA))
15823     {
15824       c_parser_consume_token (parser);
15825 
15826       location_t expr_loc = c_parser_peek_token (parser)->location;
15827       c_expr expr = c_parser_expr_no_commas (parser, NULL);
15828       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15829       t = expr.value;
15830       t = c_fully_fold (t, false, NULL);
15831       parens.skip_until_found_close (parser);
15832     }
15833   else
15834     c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
15835 			       "expected %<,%> or %<)%>");
15836 
15837   /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
15838 				"dist_schedule"); */
15839   if (omp_find_clause (list, OMP_CLAUSE_DIST_SCHEDULE))
15840     warning_at (loc, 0, "too many %qs clauses", "dist_schedule");
15841   if (t == error_mark_node)
15842     return list;
15843 
15844   c = build_omp_clause (loc, OMP_CLAUSE_DIST_SCHEDULE);
15845   OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t;
15846   OMP_CLAUSE_CHAIN (c) = list;
15847   return c;
15848 }
15849 
15850 /* OpenMP 4.0:
15851    proc_bind ( proc-bind-kind )
15852 
15853    proc-bind-kind:
15854      master | close | spread  */
15855 
15856 static tree
c_parser_omp_clause_proc_bind(c_parser * parser,tree list)15857 c_parser_omp_clause_proc_bind (c_parser *parser, tree list)
15858 {
15859   location_t clause_loc = c_parser_peek_token (parser)->location;
15860   enum omp_clause_proc_bind_kind kind;
15861   tree c;
15862 
15863   matching_parens parens;
15864   if (!parens.require_open (parser))
15865     return list;
15866 
15867   if (c_parser_next_token_is (parser, CPP_NAME))
15868     {
15869       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15870       if (strcmp ("master", p) == 0)
15871 	kind = OMP_CLAUSE_PROC_BIND_MASTER;
15872       else if (strcmp ("close", p) == 0)
15873 	kind = OMP_CLAUSE_PROC_BIND_CLOSE;
15874       else if (strcmp ("spread", p) == 0)
15875 	kind = OMP_CLAUSE_PROC_BIND_SPREAD;
15876       else
15877 	goto invalid_kind;
15878     }
15879   else
15880     goto invalid_kind;
15881 
15882   check_no_duplicate_clause (list, OMP_CLAUSE_PROC_BIND, "proc_bind");
15883   c_parser_consume_token (parser);
15884   parens.skip_until_found_close (parser);
15885   c = build_omp_clause (clause_loc, OMP_CLAUSE_PROC_BIND);
15886   OMP_CLAUSE_PROC_BIND_KIND (c) = kind;
15887   OMP_CLAUSE_CHAIN (c) = list;
15888   return c;
15889 
15890  invalid_kind:
15891   c_parser_error (parser, "invalid proc_bind kind");
15892   parens.skip_until_found_close (parser);
15893   return list;
15894 }
15895 
15896 /* OpenMP 5.0:
15897    device_type ( host | nohost | any )  */
15898 
15899 static tree
c_parser_omp_clause_device_type(c_parser * parser,tree list)15900 c_parser_omp_clause_device_type (c_parser *parser, tree list)
15901 {
15902   location_t clause_loc = c_parser_peek_token (parser)->location;
15903   enum omp_clause_device_type_kind kind;
15904   tree c;
15905 
15906   matching_parens parens;
15907   if (!parens.require_open (parser))
15908     return list;
15909 
15910   if (c_parser_next_token_is (parser, CPP_NAME))
15911     {
15912       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15913       if (strcmp ("host", p) == 0)
15914 	kind = OMP_CLAUSE_DEVICE_TYPE_HOST;
15915       else if (strcmp ("nohost", p) == 0)
15916 	kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
15917       else if (strcmp ("any", p) == 0)
15918 	kind = OMP_CLAUSE_DEVICE_TYPE_ANY;
15919       else
15920 	goto invalid_kind;
15921     }
15922   else
15923     goto invalid_kind;
15924 
15925   /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE,
15926 				"device_type");  */
15927   c_parser_consume_token (parser);
15928   parens.skip_until_found_close (parser);
15929   c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE_TYPE);
15930   OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind;
15931   OMP_CLAUSE_CHAIN (c) = list;
15932   return c;
15933 
15934  invalid_kind:
15935   c_parser_error (parser, "expected %<host%>, %<nohost%> or %<any%>");
15936   parens.skip_until_found_close (parser);
15937   return list;
15938 }
15939 
15940 /* OpenMP 4.0:
15941    to ( variable-list ) */
15942 
15943 static tree
c_parser_omp_clause_to(c_parser * parser,tree list)15944 c_parser_omp_clause_to (c_parser *parser, tree list)
15945 {
15946   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO, list);
15947 }
15948 
15949 /* OpenMP 4.0:
15950    from ( variable-list ) */
15951 
15952 static tree
c_parser_omp_clause_from(c_parser * parser,tree list)15953 c_parser_omp_clause_from (c_parser *parser, tree list)
15954 {
15955   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FROM, list);
15956 }
15957 
15958 /* OpenMP 4.0:
15959    uniform ( variable-list ) */
15960 
15961 static tree
c_parser_omp_clause_uniform(c_parser * parser,tree list)15962 c_parser_omp_clause_uniform (c_parser *parser, tree list)
15963 {
15964   /* The clauses location.  */
15965   location_t loc = c_parser_peek_token (parser)->location;
15966 
15967   matching_parens parens;
15968   if (parens.require_open (parser))
15969     {
15970       list = c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_UNIFORM,
15971 					 list);
15972       parens.skip_until_found_close (parser);
15973     }
15974   return list;
15975 }
15976 
15977 /* OpenMP 5.0:
15978    detach ( event-handle ) */
15979 
15980 static tree
c_parser_omp_clause_detach(c_parser * parser,tree list)15981 c_parser_omp_clause_detach (c_parser *parser, tree list)
15982 {
15983   matching_parens parens;
15984   location_t clause_loc = c_parser_peek_token (parser)->location;
15985 
15986   if (!parens.require_open (parser))
15987     return list;
15988 
15989   if (c_parser_next_token_is_not (parser, CPP_NAME)
15990       || c_parser_peek_token (parser)->id_kind != C_ID_ID)
15991     {
15992       c_parser_error (parser, "expected identifier");
15993       parens.skip_until_found_close (parser);
15994       return list;
15995     }
15996 
15997   tree t = lookup_name (c_parser_peek_token (parser)->value);
15998   if (t == NULL_TREE)
15999     {
16000       undeclared_variable (c_parser_peek_token (parser)->location,
16001 			   c_parser_peek_token (parser)->value);
16002       parens.skip_until_found_close (parser);
16003       return list;
16004     }
16005   c_parser_consume_token (parser);
16006 
16007   tree type = TYPE_MAIN_VARIANT (TREE_TYPE (t));
16008   if (!INTEGRAL_TYPE_P (type)
16009       || TREE_CODE (type) != ENUMERAL_TYPE
16010       || TYPE_NAME (type) != get_identifier ("omp_event_handle_t"))
16011     {
16012       error_at (clause_loc, "%<detach%> clause event handle "
16013 			    "has type %qT rather than "
16014 			    "%<omp_event_handle_t%>",
16015 			    type);
16016       parens.skip_until_found_close (parser);
16017       return list;
16018     }
16019 
16020   tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DETACH);
16021   OMP_CLAUSE_DECL (u) = t;
16022   OMP_CLAUSE_CHAIN (u) = list;
16023   parens.skip_until_found_close (parser);
16024   return u;
16025 }
16026 
16027 /* Parse all OpenACC clauses.  The set clauses allowed by the directive
16028    is a bitmask in MASK.  Return the list of clauses found.  */
16029 
16030 static tree
16031 c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask,
16032 			   const char *where, bool finish_p = true)
16033 {
16034   tree clauses = NULL;
16035   bool first = true;
16036 
16037   while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
16038     {
16039       location_t here;
16040       pragma_omp_clause c_kind;
16041       const char *c_name;
16042       tree prev = clauses;
16043 
16044       if (!first && c_parser_next_token_is (parser, CPP_COMMA))
16045 	c_parser_consume_token (parser);
16046 
16047       here = c_parser_peek_token (parser)->location;
16048       c_kind = c_parser_omp_clause_name (parser);
16049 
16050       switch (c_kind)
16051 	{
16052 	case PRAGMA_OACC_CLAUSE_ASYNC:
16053 	  clauses = c_parser_oacc_clause_async (parser, clauses);
16054 	  c_name = "async";
16055 	  break;
16056 	case PRAGMA_OACC_CLAUSE_AUTO:
16057 	  clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_AUTO,
16058 						 clauses);
16059 	  c_name = "auto";
16060 	  break;
16061 	case PRAGMA_OACC_CLAUSE_ATTACH:
16062 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16063 	  c_name = "attach";
16064 	  break;
16065 	case PRAGMA_OACC_CLAUSE_COLLAPSE:
16066 	  clauses = c_parser_omp_clause_collapse (parser, clauses);
16067 	  c_name = "collapse";
16068 	  break;
16069 	case PRAGMA_OACC_CLAUSE_COPY:
16070 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16071 	  c_name = "copy";
16072 	  break;
16073 	case PRAGMA_OACC_CLAUSE_COPYIN:
16074 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16075 	  c_name = "copyin";
16076 	  break;
16077 	case PRAGMA_OACC_CLAUSE_COPYOUT:
16078 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16079 	  c_name = "copyout";
16080 	  break;
16081 	case PRAGMA_OACC_CLAUSE_CREATE:
16082 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16083 	  c_name = "create";
16084 	  break;
16085 	case PRAGMA_OACC_CLAUSE_DELETE:
16086 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16087 	  c_name = "delete";
16088 	  break;
16089 	case PRAGMA_OMP_CLAUSE_DEFAULT:
16090 	  clauses = c_parser_omp_clause_default (parser, clauses, true);
16091 	  c_name = "default";
16092 	  break;
16093 	case PRAGMA_OACC_CLAUSE_DETACH:
16094 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16095 	  c_name = "detach";
16096 	  break;
16097 	case PRAGMA_OACC_CLAUSE_DEVICE:
16098 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16099 	  c_name = "device";
16100 	  break;
16101 	case PRAGMA_OACC_CLAUSE_DEVICEPTR:
16102 	  clauses = c_parser_oacc_data_clause_deviceptr (parser, clauses);
16103 	  c_name = "deviceptr";
16104 	  break;
16105 	case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
16106 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16107 	  c_name = "device_resident";
16108 	  break;
16109 	case PRAGMA_OACC_CLAUSE_FINALIZE:
16110 	  clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_FINALIZE,
16111 						 clauses);
16112 	  c_name = "finalize";
16113 	  break;
16114 	case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE:
16115 	  clauses = c_parser_omp_clause_firstprivate (parser, clauses);
16116 	  c_name = "firstprivate";
16117 	  break;
16118 	case PRAGMA_OACC_CLAUSE_GANG:
16119 	  c_name = "gang";
16120 	  clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_GANG,
16121 						c_name, clauses);
16122 	  break;
16123 	case PRAGMA_OACC_CLAUSE_HOST:
16124 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16125 	  c_name = "host";
16126 	  break;
16127 	case PRAGMA_OACC_CLAUSE_IF:
16128 	  clauses = c_parser_omp_clause_if (parser, clauses, false);
16129 	  c_name = "if";
16130 	  break;
16131 	case PRAGMA_OACC_CLAUSE_IF_PRESENT:
16132 	  clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_IF_PRESENT,
16133 						 clauses);
16134 	  c_name = "if_present";
16135 	  break;
16136 	case PRAGMA_OACC_CLAUSE_INDEPENDENT:
16137 	  clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_INDEPENDENT,
16138 						 clauses);
16139 	  c_name = "independent";
16140 	  break;
16141 	case PRAGMA_OACC_CLAUSE_LINK:
16142 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16143 	  c_name = "link";
16144 	  break;
16145 	case PRAGMA_OACC_CLAUSE_NO_CREATE:
16146 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16147 	  c_name = "no_create";
16148 	  break;
16149 	case PRAGMA_OACC_CLAUSE_NUM_GANGS:
16150 	  clauses = c_parser_oacc_single_int_clause (parser,
16151 						     OMP_CLAUSE_NUM_GANGS,
16152 						     clauses);
16153 	  c_name = "num_gangs";
16154 	  break;
16155 	case PRAGMA_OACC_CLAUSE_NUM_WORKERS:
16156 	  clauses = c_parser_oacc_single_int_clause (parser,
16157 						     OMP_CLAUSE_NUM_WORKERS,
16158 						     clauses);
16159 	  c_name = "num_workers";
16160 	  break;
16161 	case PRAGMA_OACC_CLAUSE_PRESENT:
16162 	  clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16163 	  c_name = "present";
16164 	  break;
16165 	case PRAGMA_OACC_CLAUSE_PRIVATE:
16166 	  clauses = c_parser_omp_clause_private (parser, clauses);
16167 	  c_name = "private";
16168 	  break;
16169 	case PRAGMA_OACC_CLAUSE_REDUCTION:
16170 	  clauses
16171 	    = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
16172 					     false, clauses);
16173 	  c_name = "reduction";
16174 	  break;
16175 	case PRAGMA_OACC_CLAUSE_SEQ:
16176 	  clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_SEQ,
16177 						 clauses);
16178 	  c_name = "seq";
16179 	  break;
16180 	case PRAGMA_OACC_CLAUSE_TILE:
16181 	  clauses = c_parser_oacc_clause_tile (parser, clauses);
16182 	  c_name = "tile";
16183 	  break;
16184 	case PRAGMA_OACC_CLAUSE_USE_DEVICE:
16185 	  clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
16186 	  c_name = "use_device";
16187 	  break;
16188 	case PRAGMA_OACC_CLAUSE_VECTOR:
16189 	  c_name = "vector";
16190 	  clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_VECTOR,
16191 						c_name,	clauses);
16192 	  break;
16193 	case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH:
16194 	  clauses = c_parser_oacc_single_int_clause (parser,
16195 						     OMP_CLAUSE_VECTOR_LENGTH,
16196 						     clauses);
16197 	  c_name = "vector_length";
16198 	  break;
16199 	case PRAGMA_OACC_CLAUSE_WAIT:
16200 	  clauses = c_parser_oacc_clause_wait (parser, clauses);
16201 	  c_name = "wait";
16202 	  break;
16203 	case PRAGMA_OACC_CLAUSE_WORKER:
16204 	  c_name = "worker";
16205 	  clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_WORKER,
16206 						c_name, clauses);
16207 	  break;
16208 	default:
16209 	  c_parser_error (parser, "expected %<#pragma acc%> clause");
16210 	  goto saw_error;
16211 	}
16212 
16213       first = false;
16214 
16215       if (((mask >> c_kind) & 1) == 0)
16216 	{
16217 	  /* Remove the invalid clause(s) from the list to avoid
16218 	     confusing the rest of the compiler.  */
16219 	  clauses = prev;
16220 	  error_at (here, "%qs is not valid for %qs", c_name, where);
16221 	}
16222     }
16223 
16224  saw_error:
16225   c_parser_skip_to_pragma_eol (parser);
16226 
16227   if (finish_p)
16228     return c_finish_omp_clauses (clauses, C_ORT_ACC);
16229 
16230   return clauses;
16231 }
16232 
16233 /* Parse all OpenMP clauses.  The set clauses allowed by the directive
16234    is a bitmask in MASK.  Return the list of clauses found.
16235    FINISH_P set if c_finish_omp_clauses should be called.
16236    NESTED non-zero if clauses should be terminated by closing paren instead
16237    of end of pragma.  If it is 2, additionally commas are required in between
16238    the clauses.  */
16239 
16240 static tree
16241 c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
16242 			  const char *where, bool finish_p = true,
16243 			  int nested = 0)
16244 {
16245   tree clauses = NULL;
16246   bool first = true;
16247 
16248   while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
16249     {
16250       location_t here;
16251       pragma_omp_clause c_kind;
16252       const char *c_name;
16253       tree prev = clauses;
16254 
16255       if (nested && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
16256 	break;
16257 
16258       if (!first)
16259 	{
16260 	  if (c_parser_next_token_is (parser, CPP_COMMA))
16261 	    c_parser_consume_token (parser);
16262 	  else if (nested == 2)
16263 	    error_at (c_parser_peek_token (parser)->location,
16264 		      "clauses in %<simd%> trait should be separated "
16265 		      "by %<,%>");
16266 	}
16267 
16268       here = c_parser_peek_token (parser)->location;
16269       c_kind = c_parser_omp_clause_name (parser);
16270 
16271       switch (c_kind)
16272 	{
16273 	case PRAGMA_OMP_CLAUSE_BIND:
16274 	  clauses = c_parser_omp_clause_bind (parser, clauses);
16275 	  c_name = "bind";
16276 	  break;
16277 	case PRAGMA_OMP_CLAUSE_COLLAPSE:
16278 	  clauses = c_parser_omp_clause_collapse (parser, clauses);
16279 	  c_name = "collapse";
16280 	  break;
16281 	case PRAGMA_OMP_CLAUSE_COPYIN:
16282 	  clauses = c_parser_omp_clause_copyin (parser, clauses);
16283 	  c_name = "copyin";
16284 	  break;
16285 	case PRAGMA_OMP_CLAUSE_COPYPRIVATE:
16286 	  clauses = c_parser_omp_clause_copyprivate (parser, clauses);
16287 	  c_name = "copyprivate";
16288 	  break;
16289 	case PRAGMA_OMP_CLAUSE_DEFAULT:
16290 	  clauses = c_parser_omp_clause_default (parser, clauses, false);
16291 	  c_name = "default";
16292 	  break;
16293 	case PRAGMA_OMP_CLAUSE_DETACH:
16294 	  clauses = c_parser_omp_clause_detach (parser, clauses);
16295 	  c_name = "detach";
16296 	  break;
16297 	case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
16298 	  clauses = c_parser_omp_clause_firstprivate (parser, clauses);
16299 	  c_name = "firstprivate";
16300 	  break;
16301 	case PRAGMA_OMP_CLAUSE_FINAL:
16302 	  clauses = c_parser_omp_clause_final (parser, clauses);
16303 	  c_name = "final";
16304 	  break;
16305 	case PRAGMA_OMP_CLAUSE_GRAINSIZE:
16306 	  clauses = c_parser_omp_clause_grainsize (parser, clauses);
16307 	  c_name = "grainsize";
16308 	  break;
16309 	case PRAGMA_OMP_CLAUSE_HINT:
16310 	  clauses = c_parser_omp_clause_hint (parser, clauses);
16311 	  c_name = "hint";
16312 	  break;
16313 	case PRAGMA_OMP_CLAUSE_DEFAULTMAP:
16314 	  clauses = c_parser_omp_clause_defaultmap (parser, clauses);
16315 	  c_name = "defaultmap";
16316 	  break;
16317 	case PRAGMA_OMP_CLAUSE_IF:
16318 	  clauses = c_parser_omp_clause_if (parser, clauses, true);
16319 	  c_name = "if";
16320 	  break;
16321 	case PRAGMA_OMP_CLAUSE_IN_REDUCTION:
16322 	  clauses
16323 	    = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION,
16324 					     true, clauses);
16325 	  c_name = "in_reduction";
16326 	  break;
16327 	case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
16328 	  clauses = c_parser_omp_clause_lastprivate (parser, clauses);
16329 	  c_name = "lastprivate";
16330 	  break;
16331 	case PRAGMA_OMP_CLAUSE_MERGEABLE:
16332 	  clauses = c_parser_omp_clause_mergeable (parser, clauses);
16333 	  c_name = "mergeable";
16334 	  break;
16335 	case PRAGMA_OMP_CLAUSE_NOWAIT:
16336 	  clauses = c_parser_omp_clause_nowait (parser, clauses);
16337 	  c_name = "nowait";
16338 	  break;
16339 	case PRAGMA_OMP_CLAUSE_NUM_TASKS:
16340 	  clauses = c_parser_omp_clause_num_tasks (parser, clauses);
16341 	  c_name = "num_tasks";
16342 	  break;
16343 	case PRAGMA_OMP_CLAUSE_NUM_THREADS:
16344 	  clauses = c_parser_omp_clause_num_threads (parser, clauses);
16345 	  c_name = "num_threads";
16346 	  break;
16347 	case PRAGMA_OMP_CLAUSE_ORDER:
16348 	  clauses = c_parser_omp_clause_order (parser, clauses);
16349 	  c_name = "order";
16350 	  break;
16351 	case PRAGMA_OMP_CLAUSE_ORDERED:
16352 	  clauses = c_parser_omp_clause_ordered (parser, clauses);
16353 	  c_name = "ordered";
16354 	  break;
16355 	case PRAGMA_OMP_CLAUSE_PRIORITY:
16356 	  clauses = c_parser_omp_clause_priority (parser, clauses);
16357 	  c_name = "priority";
16358 	  break;
16359 	case PRAGMA_OMP_CLAUSE_PRIVATE:
16360 	  clauses = c_parser_omp_clause_private (parser, clauses);
16361 	  c_name = "private";
16362 	  break;
16363 	case PRAGMA_OMP_CLAUSE_REDUCTION:
16364 	  clauses
16365 	    = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
16366 					     true, clauses);
16367 	  c_name = "reduction";
16368 	  break;
16369 	case PRAGMA_OMP_CLAUSE_SCHEDULE:
16370 	  clauses = c_parser_omp_clause_schedule (parser, clauses);
16371 	  c_name = "schedule";
16372 	  break;
16373 	case PRAGMA_OMP_CLAUSE_SHARED:
16374 	  clauses = c_parser_omp_clause_shared (parser, clauses);
16375 	  c_name = "shared";
16376 	  break;
16377 	case PRAGMA_OMP_CLAUSE_TASK_REDUCTION:
16378 	  clauses
16379 	    = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_TASK_REDUCTION,
16380 					     true, clauses);
16381 	  c_name = "task_reduction";
16382 	  break;
16383 	case PRAGMA_OMP_CLAUSE_UNTIED:
16384 	  clauses = c_parser_omp_clause_untied (parser, clauses);
16385 	  c_name = "untied";
16386 	  break;
16387 	case PRAGMA_OMP_CLAUSE_INBRANCH:
16388 	  clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_INBRANCH,
16389 						clauses);
16390 	  c_name = "inbranch";
16391 	  break;
16392 	case PRAGMA_OMP_CLAUSE_NONTEMPORAL:
16393 	  clauses = c_parser_omp_clause_nontemporal (parser, clauses);
16394 	  c_name = "nontemporal";
16395 	  break;
16396 	case PRAGMA_OMP_CLAUSE_NOTINBRANCH:
16397 	  clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_NOTINBRANCH,
16398 						clauses);
16399 	  c_name = "notinbranch";
16400 	  break;
16401 	case PRAGMA_OMP_CLAUSE_PARALLEL:
16402 	  clauses
16403 	    = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_PARALLEL,
16404 					      clauses);
16405 	  c_name = "parallel";
16406 	  if (!first)
16407 	    {
16408 	     clause_not_first:
16409 	      error_at (here, "%qs must be the first clause of %qs",
16410 			c_name, where);
16411 	      clauses = prev;
16412 	    }
16413 	  break;
16414 	case PRAGMA_OMP_CLAUSE_FOR:
16415 	  clauses
16416 	    = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_FOR,
16417 					      clauses);
16418 	  c_name = "for";
16419 	  if (!first)
16420 	    goto clause_not_first;
16421 	  break;
16422 	case PRAGMA_OMP_CLAUSE_SECTIONS:
16423 	  clauses
16424 	    = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_SECTIONS,
16425 					      clauses);
16426 	  c_name = "sections";
16427 	  if (!first)
16428 	    goto clause_not_first;
16429 	  break;
16430 	case PRAGMA_OMP_CLAUSE_TASKGROUP:
16431 	  clauses
16432 	    = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_TASKGROUP,
16433 					      clauses);
16434 	  c_name = "taskgroup";
16435 	  if (!first)
16436 	    goto clause_not_first;
16437 	  break;
16438 	case PRAGMA_OMP_CLAUSE_LINK:
16439 	  clauses
16440 	    = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LINK, clauses);
16441 	  c_name = "link";
16442 	  break;
16443 	case PRAGMA_OMP_CLAUSE_TO:
16444 	  if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0)
16445 	    clauses
16446 	      = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO_DECLARE,
16447 					      clauses);
16448 	  else
16449 	    clauses = c_parser_omp_clause_to (parser, clauses);
16450 	  c_name = "to";
16451 	  break;
16452 	case PRAGMA_OMP_CLAUSE_FROM:
16453 	  clauses = c_parser_omp_clause_from (parser, clauses);
16454 	  c_name = "from";
16455 	  break;
16456 	case PRAGMA_OMP_CLAUSE_UNIFORM:
16457 	  clauses = c_parser_omp_clause_uniform (parser, clauses);
16458 	  c_name = "uniform";
16459 	  break;
16460 	case PRAGMA_OMP_CLAUSE_NUM_TEAMS:
16461 	  clauses = c_parser_omp_clause_num_teams (parser, clauses);
16462 	  c_name = "num_teams";
16463 	  break;
16464 	case PRAGMA_OMP_CLAUSE_THREAD_LIMIT:
16465 	  clauses = c_parser_omp_clause_thread_limit (parser, clauses);
16466 	  c_name = "thread_limit";
16467 	  break;
16468 	case PRAGMA_OMP_CLAUSE_ALIGNED:
16469 	  clauses = c_parser_omp_clause_aligned (parser, clauses);
16470 	  c_name = "aligned";
16471 	  break;
16472 	case PRAGMA_OMP_CLAUSE_ALLOCATE:
16473 	  clauses = c_parser_omp_clause_allocate (parser, clauses);
16474 	  c_name = "allocate";
16475 	  break;
16476 	case PRAGMA_OMP_CLAUSE_LINEAR:
16477 	  clauses = c_parser_omp_clause_linear (parser, clauses);
16478 	  c_name = "linear";
16479 	  break;
16480 	case PRAGMA_OMP_CLAUSE_DEPEND:
16481 	  clauses = c_parser_omp_clause_depend (parser, clauses);
16482 	  c_name = "depend";
16483 	  break;
16484 	case PRAGMA_OMP_CLAUSE_MAP:
16485 	  clauses = c_parser_omp_clause_map (parser, clauses);
16486 	  c_name = "map";
16487 	  break;
16488 	case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR:
16489 	  clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
16490 	  c_name = "use_device_ptr";
16491 	  break;
16492 	case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR:
16493 	  clauses = c_parser_omp_clause_use_device_addr (parser, clauses);
16494 	  c_name = "use_device_addr";
16495 	  break;
16496 	case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR:
16497 	  clauses = c_parser_omp_clause_is_device_ptr (parser, clauses);
16498 	  c_name = "is_device_ptr";
16499 	  break;
16500 	case PRAGMA_OMP_CLAUSE_DEVICE:
16501 	  clauses = c_parser_omp_clause_device (parser, clauses);
16502 	  c_name = "device";
16503 	  break;
16504 	case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE:
16505 	  clauses = c_parser_omp_clause_dist_schedule (parser, clauses);
16506 	  c_name = "dist_schedule";
16507 	  break;
16508 	case PRAGMA_OMP_CLAUSE_PROC_BIND:
16509 	  clauses = c_parser_omp_clause_proc_bind (parser, clauses);
16510 	  c_name = "proc_bind";
16511 	  break;
16512 	case PRAGMA_OMP_CLAUSE_DEVICE_TYPE:
16513 	  clauses = c_parser_omp_clause_device_type (parser, clauses);
16514 	  c_name = "device_type";
16515 	  break;
16516 	case PRAGMA_OMP_CLAUSE_SAFELEN:
16517 	  clauses = c_parser_omp_clause_safelen (parser, clauses);
16518 	  c_name = "safelen";
16519 	  break;
16520 	case PRAGMA_OMP_CLAUSE_SIMDLEN:
16521 	  clauses = c_parser_omp_clause_simdlen (parser, clauses);
16522 	  c_name = "simdlen";
16523 	  break;
16524 	case PRAGMA_OMP_CLAUSE_NOGROUP:
16525 	  clauses = c_parser_omp_clause_nogroup (parser, clauses);
16526 	  c_name = "nogroup";
16527 	  break;
16528 	case PRAGMA_OMP_CLAUSE_THREADS:
16529 	  clauses
16530 	    = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_THREADS,
16531 					       clauses);
16532 	  c_name = "threads";
16533 	  break;
16534 	case PRAGMA_OMP_CLAUSE_SIMD:
16535 	  clauses
16536 	    = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_SIMD,
16537 					       clauses);
16538 	  c_name = "simd";
16539 	  break;
16540 	default:
16541 	  c_parser_error (parser, "expected %<#pragma omp%> clause");
16542 	  goto saw_error;
16543 	}
16544 
16545       first = false;
16546 
16547       if (((mask >> c_kind) & 1) == 0)
16548 	{
16549 	  /* Remove the invalid clause(s) from the list to avoid
16550 	     confusing the rest of the compiler.  */
16551 	  clauses = prev;
16552 	  error_at (here, "%qs is not valid for %qs", c_name, where);
16553 	}
16554     }
16555 
16556  saw_error:
16557   if (!nested)
16558     c_parser_skip_to_pragma_eol (parser);
16559 
16560   if (finish_p)
16561     {
16562       if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)) != 0)
16563 	return c_finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD);
16564       return c_finish_omp_clauses (clauses, C_ORT_OMP);
16565     }
16566 
16567   return clauses;
16568 }
16569 
16570 /* OpenACC 2.0, OpenMP 2.5:
16571    structured-block:
16572      statement
16573 
16574    In practice, we're also interested in adding the statement to an
16575    outer node.  So it is convenient if we work around the fact that
16576    c_parser_statement calls add_stmt.  */
16577 
16578 static tree
c_parser_omp_structured_block(c_parser * parser,bool * if_p)16579 c_parser_omp_structured_block (c_parser *parser, bool *if_p)
16580 {
16581   tree stmt = push_stmt_list ();
16582   c_parser_statement (parser, if_p);
16583   return pop_stmt_list (stmt);
16584 }
16585 
16586 /* OpenACC 2.0:
16587    # pragma acc cache (variable-list) new-line
16588 
16589    LOC is the location of the #pragma token.
16590 */
16591 
16592 static tree
c_parser_oacc_cache(location_t loc,c_parser * parser)16593 c_parser_oacc_cache (location_t loc, c_parser *parser)
16594 {
16595   tree stmt, clauses;
16596 
16597   clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE__CACHE_, NULL);
16598   clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
16599 
16600   c_parser_skip_to_pragma_eol (parser);
16601 
16602   stmt = make_node (OACC_CACHE);
16603   TREE_TYPE (stmt) = void_type_node;
16604   OACC_CACHE_CLAUSES (stmt) = clauses;
16605   SET_EXPR_LOCATION (stmt, loc);
16606   add_stmt (stmt);
16607 
16608   return stmt;
16609 }
16610 
16611 /* OpenACC 2.0:
16612    # pragma acc data oacc-data-clause[optseq] new-line
16613      structured-block
16614 
16615    LOC is the location of the #pragma token.
16616 */
16617 
16618 #define OACC_DATA_CLAUSE_MASK						\
16619 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH)		\
16620 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY)		\
16621 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)		\
16622 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)		\
16623 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)		\
16624 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)		\
16625 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)			\
16626 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE)		\
16627 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
16628 
16629 static tree
c_parser_oacc_data(location_t loc,c_parser * parser,bool * if_p)16630 c_parser_oacc_data (location_t loc, c_parser *parser, bool *if_p)
16631 {
16632   tree stmt, clauses, block;
16633 
16634   clauses = c_parser_oacc_all_clauses (parser, OACC_DATA_CLAUSE_MASK,
16635 				       "#pragma acc data");
16636 
16637   block = c_begin_omp_parallel ();
16638   add_stmt (c_parser_omp_structured_block (parser, if_p));
16639 
16640   stmt = c_finish_oacc_data (loc, clauses, block);
16641 
16642   return stmt;
16643 }
16644 
16645 /* OpenACC 2.0:
16646    # pragma acc declare oacc-data-clause[optseq] new-line
16647 */
16648 
16649 #define OACC_DECLARE_CLAUSE_MASK					\
16650 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY)		\
16651 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)		\
16652 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)		\
16653 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)		\
16654 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)		\
16655 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT)	\
16656 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK)		\
16657 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
16658 
16659 static void
c_parser_oacc_declare(c_parser * parser)16660 c_parser_oacc_declare (c_parser *parser)
16661 {
16662   location_t pragma_loc = c_parser_peek_token (parser)->location;
16663   tree clauses, stmt, t, decl;
16664 
16665   bool error = false;
16666 
16667   c_parser_consume_pragma (parser);
16668 
16669   clauses = c_parser_oacc_all_clauses (parser, OACC_DECLARE_CLAUSE_MASK,
16670 				       "#pragma acc declare");
16671   if (!clauses)
16672     {
16673       error_at (pragma_loc,
16674 		"no valid clauses specified in %<#pragma acc declare%>");
16675       return;
16676     }
16677 
16678   for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
16679     {
16680       location_t loc = OMP_CLAUSE_LOCATION (t);
16681       decl = OMP_CLAUSE_DECL (t);
16682       if (!DECL_P (decl))
16683 	{
16684 	  error_at (loc, "array section in %<#pragma acc declare%>");
16685 	  error = true;
16686 	  continue;
16687 	}
16688 
16689       switch (OMP_CLAUSE_MAP_KIND (t))
16690 	{
16691 	case GOMP_MAP_FIRSTPRIVATE_POINTER:
16692 	case GOMP_MAP_ALLOC:
16693 	case GOMP_MAP_TO:
16694 	case GOMP_MAP_FORCE_DEVICEPTR:
16695 	case GOMP_MAP_DEVICE_RESIDENT:
16696 	  break;
16697 
16698 	case GOMP_MAP_LINK:
16699 	  if (!global_bindings_p ()
16700 	      && (TREE_STATIC (decl)
16701 	       || !DECL_EXTERNAL (decl)))
16702 	    {
16703 	      error_at (loc,
16704 			"%qD must be a global variable in "
16705 			"%<#pragma acc declare link%>",
16706 			decl);
16707 	      error = true;
16708 	      continue;
16709 	    }
16710 	  break;
16711 
16712 	default:
16713 	  if (global_bindings_p ())
16714 	    {
16715 	      error_at (loc, "invalid OpenACC clause at file scope");
16716 	      error = true;
16717 	      continue;
16718 	    }
16719 	  if (DECL_EXTERNAL (decl))
16720 	    {
16721 	      error_at (loc,
16722 			"invalid use of %<extern%> variable %qD "
16723 			"in %<#pragma acc declare%>", decl);
16724 	      error = true;
16725 	      continue;
16726 	    }
16727 	  else if (TREE_PUBLIC (decl))
16728 	    {
16729 	      error_at (loc,
16730 			"invalid use of %<global%> variable %qD "
16731 			"in %<#pragma acc declare%>", decl);
16732 	      error = true;
16733 	      continue;
16734 	    }
16735 	  break;
16736 	}
16737 
16738       if (!c_check_in_current_scope (decl))
16739 	{
16740 	  error_at (loc,
16741 		    "%qD must be a variable declared in the same scope as "
16742 		    "%<#pragma acc declare%>", decl);
16743 	  error = true;
16744 	  continue;
16745 	}
16746 
16747       if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl))
16748 	  || lookup_attribute ("omp declare target link",
16749 			       DECL_ATTRIBUTES (decl)))
16750 	{
16751 	  error_at (loc, "variable %qD used more than once with "
16752 		    "%<#pragma acc declare%>", decl);
16753 	  error = true;
16754 	  continue;
16755 	}
16756 
16757       if (!error)
16758 	{
16759 	  tree id;
16760 
16761 	  if (OMP_CLAUSE_MAP_KIND (t) == GOMP_MAP_LINK)
16762 	    id = get_identifier ("omp declare target link");
16763 	  else
16764 	    id = get_identifier ("omp declare target");
16765 
16766 	  DECL_ATTRIBUTES (decl)
16767 			   = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
16768 
16769 	  if (global_bindings_p ())
16770 	    {
16771 	      symtab_node *node = symtab_node::get (decl);
16772 	      if (node != NULL)
16773 		{
16774 		  node->offloadable = 1;
16775 		  if (ENABLE_OFFLOADING)
16776 		    {
16777 		      g->have_offload = true;
16778 		      if (is_a <varpool_node *> (node))
16779 			vec_safe_push (offload_vars, decl);
16780 		    }
16781 		}
16782 	    }
16783 	}
16784     }
16785 
16786   if (error || global_bindings_p ())
16787     return;
16788 
16789   stmt = make_node (OACC_DECLARE);
16790   TREE_TYPE (stmt) = void_type_node;
16791   OACC_DECLARE_CLAUSES (stmt) = clauses;
16792   SET_EXPR_LOCATION (stmt, pragma_loc);
16793 
16794   add_stmt (stmt);
16795 
16796   return;
16797 }
16798 
16799 /* OpenACC 2.0:
16800    # pragma acc enter data oacc-enter-data-clause[optseq] new-line
16801 
16802    or
16803 
16804    # pragma acc exit data oacc-exit-data-clause[optseq] new-line
16805 
16806 
16807    LOC is the location of the #pragma token.
16808 */
16809 
16810 #define OACC_ENTER_DATA_CLAUSE_MASK					\
16811 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)			\
16812 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)		\
16813 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH)		\
16814 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)		\
16815 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)		\
16816 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16817 
16818 #define OACC_EXIT_DATA_CLAUSE_MASK					\
16819 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)			\
16820 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)		\
16821 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)		\
16822 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) 		\
16823 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) 		\
16824 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) 		\
16825 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16826 
16827 static void
c_parser_oacc_enter_exit_data(c_parser * parser,bool enter)16828 c_parser_oacc_enter_exit_data (c_parser *parser, bool enter)
16829 {
16830   location_t loc = c_parser_peek_token (parser)->location;
16831   tree clauses, stmt;
16832   const char *p = "";
16833 
16834   c_parser_consume_pragma (parser);
16835 
16836   if (c_parser_next_token_is (parser, CPP_NAME))
16837     {
16838       p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16839       c_parser_consume_token (parser);
16840     }
16841 
16842   if (strcmp (p, "data") != 0)
16843     {
16844       error_at (loc, "expected %<data%> after %<#pragma acc %s%>",
16845 		enter ? "enter" : "exit");
16846       parser->error = true;
16847       c_parser_skip_to_pragma_eol (parser);
16848       return;
16849     }
16850 
16851   if (enter)
16852     clauses = c_parser_oacc_all_clauses (parser, OACC_ENTER_DATA_CLAUSE_MASK,
16853 					 "#pragma acc enter data");
16854   else
16855     clauses = c_parser_oacc_all_clauses (parser, OACC_EXIT_DATA_CLAUSE_MASK,
16856 					 "#pragma acc exit data");
16857 
16858   if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
16859     {
16860       error_at (loc, "%<#pragma acc %s data%> has no data movement clause",
16861 		enter ? "enter" : "exit");
16862       return;
16863     }
16864 
16865   stmt = enter ? make_node (OACC_ENTER_DATA) : make_node (OACC_EXIT_DATA);
16866   TREE_TYPE (stmt) = void_type_node;
16867   OMP_STANDALONE_CLAUSES (stmt) = clauses;
16868   SET_EXPR_LOCATION (stmt, loc);
16869   add_stmt (stmt);
16870 }
16871 
16872 
16873 /* OpenACC 2.0:
16874    # pragma acc host_data oacc-data-clause[optseq] new-line
16875      structured-block
16876 */
16877 
16878 #define OACC_HOST_DATA_CLAUSE_MASK					\
16879 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE)          \
16880 	 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)                  \
16881 	 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
16882 
16883 static tree
c_parser_oacc_host_data(location_t loc,c_parser * parser,bool * if_p)16884 c_parser_oacc_host_data (location_t loc, c_parser *parser, bool *if_p)
16885 {
16886   tree stmt, clauses, block;
16887 
16888   clauses = c_parser_oacc_all_clauses (parser, OACC_HOST_DATA_CLAUSE_MASK,
16889 				       "#pragma acc host_data");
16890 
16891   block = c_begin_omp_parallel ();
16892   add_stmt (c_parser_omp_structured_block (parser, if_p));
16893   stmt = c_finish_oacc_host_data (loc, clauses, block);
16894   return stmt;
16895 }
16896 
16897 
16898 /* OpenACC 2.0:
16899 
16900    # pragma acc loop oacc-loop-clause[optseq] new-line
16901      structured-block
16902 
16903    LOC is the location of the #pragma token.
16904 */
16905 
16906 #define OACC_LOOP_CLAUSE_MASK						\
16907 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE)		\
16908 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE)		\
16909 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION)		\
16910 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG)		\
16911 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER)		\
16912 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR)		\
16913 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO)		\
16914 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) 	\
16915 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ)			\
16916 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
16917 static tree
c_parser_oacc_loop(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)16918 c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name,
16919 		    omp_clause_mask mask, tree *cclauses, bool *if_p)
16920 {
16921   bool is_parallel = ((mask >> PRAGMA_OACC_CLAUSE_REDUCTION) & 1) == 1;
16922 
16923   strcat (p_name, " loop");
16924   mask |= OACC_LOOP_CLAUSE_MASK;
16925 
16926   tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name,
16927 					    cclauses == NULL);
16928   if (cclauses)
16929     {
16930       clauses = c_oacc_split_loop_clauses (clauses, cclauses, is_parallel);
16931       if (*cclauses)
16932 	*cclauses = c_finish_omp_clauses (*cclauses, C_ORT_ACC);
16933       if (clauses)
16934 	clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
16935     }
16936 
16937   tree block = c_begin_compound_stmt (true);
16938   tree stmt = c_parser_omp_for_loop (loc, parser, OACC_LOOP, clauses, NULL,
16939 				     if_p);
16940   block = c_end_compound_stmt (loc, block, true);
16941   add_stmt (block);
16942 
16943   return stmt;
16944 }
16945 
16946 /* OpenACC 2.0:
16947    # pragma acc kernels oacc-kernels-clause[optseq] new-line
16948      structured-block
16949 
16950    or
16951 
16952    # pragma acc parallel oacc-parallel-clause[optseq] new-line
16953      structured-block
16954 
16955    OpenACC 2.6:
16956 
16957    # pragma acc serial oacc-serial-clause[optseq] new-line
16958      structured-block
16959 
16960    LOC is the location of the #pragma token.
16961 */
16962 
16963 #define OACC_KERNELS_CLAUSE_MASK					\
16964 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)		\
16965 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH)		\
16966 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY)		\
16967 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)		\
16968 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)		\
16969 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)		\
16970 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT)		\
16971 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)		\
16972 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)			\
16973 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE)		\
16974 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS)		\
16975 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS)		\
16976 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT)		\
16977 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH)	\
16978 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16979 
16980 #define OACC_PARALLEL_CLAUSE_MASK					\
16981 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)		\
16982 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH)		\
16983 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY)		\
16984 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)		\
16985 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)		\
16986 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)		\
16987 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT)		\
16988 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)		\
16989 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)			\
16990 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE)		\
16991 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE)		\
16992 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE)	\
16993 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS)		\
16994 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS)		\
16995 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT)		\
16996 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION)		\
16997 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH)	\
16998 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16999 
17000 #define OACC_SERIAL_CLAUSE_MASK					\
17001 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)		\
17002 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH)		\
17003 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY)		\
17004 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)		\
17005 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)		\
17006 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)		\
17007 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT)		\
17008 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)		\
17009 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)			\
17010 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE)		\
17011 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE)		\
17012 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE)	\
17013 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT)		\
17014 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION)		\
17015 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17016 
17017 static tree
c_parser_oacc_compute(location_t loc,c_parser * parser,enum pragma_kind p_kind,char * p_name,bool * if_p)17018 c_parser_oacc_compute (location_t loc, c_parser *parser,
17019 		       enum pragma_kind p_kind, char *p_name, bool *if_p)
17020 {
17021   omp_clause_mask mask;
17022   enum tree_code code;
17023   switch (p_kind)
17024     {
17025     case PRAGMA_OACC_KERNELS:
17026       strcat (p_name, " kernels");
17027       mask = OACC_KERNELS_CLAUSE_MASK;
17028       code = OACC_KERNELS;
17029       break;
17030     case PRAGMA_OACC_PARALLEL:
17031       strcat (p_name, " parallel");
17032       mask = OACC_PARALLEL_CLAUSE_MASK;
17033       code = OACC_PARALLEL;
17034       break;
17035     case PRAGMA_OACC_SERIAL:
17036       strcat (p_name, " serial");
17037       mask = OACC_SERIAL_CLAUSE_MASK;
17038       code = OACC_SERIAL;
17039       break;
17040     default:
17041       gcc_unreachable ();
17042     }
17043 
17044   if (c_parser_next_token_is (parser, CPP_NAME))
17045     {
17046       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17047       if (strcmp (p, "loop") == 0)
17048 	{
17049 	  c_parser_consume_token (parser);
17050 	  tree block = c_begin_omp_parallel ();
17051 	  tree clauses;
17052 	  c_parser_oacc_loop (loc, parser, p_name, mask, &clauses, if_p);
17053 	  return c_finish_omp_construct (loc, code, block, clauses);
17054 	}
17055     }
17056 
17057   tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name);
17058 
17059   tree block = c_begin_omp_parallel ();
17060   add_stmt (c_parser_omp_structured_block (parser, if_p));
17061 
17062   return c_finish_omp_construct (loc, code, block, clauses);
17063 }
17064 
17065 /* OpenACC 2.0:
17066    # pragma acc routine oacc-routine-clause[optseq] new-line
17067      function-definition
17068 
17069    # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
17070 */
17071 
17072 #define OACC_ROUTINE_CLAUSE_MASK					\
17073 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG)		\
17074 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER)		\
17075 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR)		\
17076 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) )
17077 
17078 /* Parse an OpenACC routine directive.  For named directives, we apply
17079    immediately to the named function.  For unnamed ones we then parse
17080    a declaration or definition, which must be for a function.  */
17081 
17082 static void
c_parser_oacc_routine(c_parser * parser,enum pragma_context context)17083 c_parser_oacc_routine (c_parser *parser, enum pragma_context context)
17084 {
17085   gcc_checking_assert (context == pragma_external);
17086 
17087   oacc_routine_data data;
17088   data.error_seen = false;
17089   data.fndecl_seen = false;
17090   data.loc = c_parser_peek_token (parser)->location;
17091 
17092   c_parser_consume_pragma (parser);
17093 
17094   /* Look for optional '( name )'.  */
17095   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
17096     {
17097       c_parser_consume_token (parser); /* '(' */
17098 
17099       tree decl = NULL_TREE;
17100       c_token *name_token = c_parser_peek_token (parser);
17101       location_t name_loc = name_token->location;
17102       if (name_token->type == CPP_NAME
17103 	  && (name_token->id_kind == C_ID_ID
17104 	      || name_token->id_kind == C_ID_TYPENAME))
17105 	{
17106 	  decl = lookup_name (name_token->value);
17107 	  if (!decl)
17108 	    error_at (name_loc,
17109 		      "%qE has not been declared", name_token->value);
17110 	  c_parser_consume_token (parser);
17111 	}
17112       else
17113 	c_parser_error (parser, "expected function name");
17114 
17115       if (!decl
17116 	  || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
17117 	{
17118 	  c_parser_skip_to_pragma_eol (parser, false);
17119 	  return;
17120 	}
17121 
17122       data.clauses
17123 	= c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
17124 				     "#pragma acc routine");
17125       /* The clauses are in reverse order; fix that to make later diagnostic
17126 	 emission easier.  */
17127       data.clauses = nreverse (data.clauses);
17128 
17129       if (TREE_CODE (decl) != FUNCTION_DECL)
17130 	{
17131 	  error_at (name_loc, "%qD does not refer to a function", decl);
17132 	  return;
17133 	}
17134 
17135       c_finish_oacc_routine (&data, decl, false);
17136     }
17137   else /* No optional '( name )'.  */
17138     {
17139       data.clauses
17140 	= c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
17141 				     "#pragma acc routine");
17142       /* The clauses are in reverse order; fix that to make later diagnostic
17143 	 emission easier.  */
17144       data.clauses = nreverse (data.clauses);
17145 
17146       /* Emit a helpful diagnostic if there's another pragma following this
17147 	 one.  Also don't allow a static assertion declaration, as in the
17148 	 following we'll just parse a *single* "declaration or function
17149 	 definition", and the static assertion counts an one.  */
17150       if (c_parser_next_token_is (parser, CPP_PRAGMA)
17151 	  || c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
17152 	{
17153 	  error_at (data.loc,
17154 		    "%<#pragma acc routine%> not immediately followed by"
17155 		    " function declaration or definition");
17156 	  /* ..., and then just keep going.  */
17157 	  return;
17158 	}
17159 
17160       /* We only have to consider the pragma_external case here.  */
17161       if (c_parser_next_token_is (parser, CPP_KEYWORD)
17162 	  && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
17163 	{
17164 	  int ext = disable_extension_diagnostics ();
17165 	  do
17166 	    c_parser_consume_token (parser);
17167 	  while (c_parser_next_token_is (parser, CPP_KEYWORD)
17168 		 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
17169 	  c_parser_declaration_or_fndef (parser, true, true, true, false, true,
17170 					 NULL, vNULL, false, NULL, &data);
17171 	  restore_extension_diagnostics (ext);
17172 	}
17173       else
17174 	c_parser_declaration_or_fndef (parser, true, true, true, false, true,
17175 				       NULL, vNULL, false, NULL, &data);
17176     }
17177 }
17178 
17179 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
17180    IS_DEFN is true if we're applying it to the definition.  */
17181 
17182 static void
c_finish_oacc_routine(struct oacc_routine_data * data,tree fndecl,bool is_defn)17183 c_finish_oacc_routine (struct oacc_routine_data *data, tree fndecl,
17184 		       bool is_defn)
17185 {
17186   /* Keep going if we're in error reporting mode.  */
17187   if (data->error_seen
17188       || fndecl == error_mark_node)
17189     return;
17190 
17191   if (data->fndecl_seen)
17192     {
17193       error_at (data->loc,
17194 		"%<#pragma acc routine%> not immediately followed by"
17195 		" a single function declaration or definition");
17196       data->error_seen = true;
17197       return;
17198     }
17199   if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
17200     {
17201       error_at (data->loc,
17202 		"%<#pragma acc routine%> not immediately followed by"
17203 		" function declaration or definition");
17204       data->error_seen = true;
17205       return;
17206     }
17207 
17208   int compatible
17209     = oacc_verify_routine_clauses (fndecl, &data->clauses, data->loc,
17210 				   "#pragma acc routine");
17211   if (compatible < 0)
17212     {
17213       data->error_seen = true;
17214       return;
17215     }
17216   if (compatible > 0)
17217     {
17218     }
17219   else
17220     {
17221       if (TREE_USED (fndecl) || (!is_defn && DECL_SAVED_TREE (fndecl)))
17222 	{
17223 	  error_at (data->loc,
17224 		    TREE_USED (fndecl)
17225 		    ? G_("%<#pragma acc routine%> must be applied before use")
17226 		    : G_("%<#pragma acc routine%> must be applied before"
17227 			 " definition"));
17228 	  data->error_seen = true;
17229 	  return;
17230 	}
17231 
17232       /* Set the routine's level of parallelism.  */
17233       tree dims = oacc_build_routine_dims (data->clauses);
17234       oacc_replace_fn_attrib (fndecl, dims);
17235 
17236       /* Add an "omp declare target" attribute.  */
17237       DECL_ATTRIBUTES (fndecl)
17238 	= tree_cons (get_identifier ("omp declare target"),
17239 		     data->clauses, DECL_ATTRIBUTES (fndecl));
17240     }
17241 
17242   /* Remember that we've used this "#pragma acc routine".  */
17243   data->fndecl_seen = true;
17244 }
17245 
17246 /* OpenACC 2.0:
17247    # pragma acc update oacc-update-clause[optseq] new-line
17248 */
17249 
17250 #define OACC_UPDATE_CLAUSE_MASK						\
17251 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)		\
17252 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE)		\
17253 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST)		\
17254 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)			\
17255 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT)		\
17256 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17257 
17258 static void
c_parser_oacc_update(c_parser * parser)17259 c_parser_oacc_update (c_parser *parser)
17260 {
17261   location_t loc = c_parser_peek_token (parser)->location;
17262 
17263   c_parser_consume_pragma (parser);
17264 
17265   tree clauses = c_parser_oacc_all_clauses (parser, OACC_UPDATE_CLAUSE_MASK,
17266 					    "#pragma acc update");
17267   if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
17268     {
17269       error_at (loc,
17270 		"%<#pragma acc update%> must contain at least one "
17271 		"%<device%> or %<host%> or %<self%> clause");
17272       return;
17273     }
17274 
17275   if (parser->error)
17276     return;
17277 
17278   tree stmt = make_node (OACC_UPDATE);
17279   TREE_TYPE (stmt) = void_type_node;
17280   OACC_UPDATE_CLAUSES (stmt) = clauses;
17281   SET_EXPR_LOCATION (stmt, loc);
17282   add_stmt (stmt);
17283 }
17284 
17285 /* OpenACC 2.0:
17286    # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
17287 
17288    LOC is the location of the #pragma token.
17289 */
17290 
17291 #define OACC_WAIT_CLAUSE_MASK						\
17292 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
17293 
17294 static tree
c_parser_oacc_wait(location_t loc,c_parser * parser,char * p_name)17295 c_parser_oacc_wait (location_t loc, c_parser *parser, char *p_name)
17296 {
17297   tree clauses, list = NULL_TREE, stmt = NULL_TREE;
17298 
17299   if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
17300     list = c_parser_oacc_wait_list (parser, loc, list);
17301 
17302   strcpy (p_name, " wait");
17303   clauses = c_parser_oacc_all_clauses (parser, OACC_WAIT_CLAUSE_MASK, p_name);
17304   stmt = c_finish_oacc_wait (loc, list, clauses);
17305   add_stmt (stmt);
17306 
17307   return stmt;
17308 }
17309 
17310 /* OpenMP 5.0:
17311    # pragma omp allocate (list)  [allocator(allocator)]  */
17312 
17313 static void
c_parser_omp_allocate(location_t loc,c_parser * parser)17314 c_parser_omp_allocate (location_t loc, c_parser *parser)
17315 {
17316   tree allocator = NULL_TREE;
17317   tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ALLOCATE, NULL_TREE);
17318   if (c_parser_next_token_is (parser, CPP_NAME))
17319     {
17320       matching_parens parens;
17321       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17322       c_parser_consume_token (parser);
17323       if (strcmp ("allocator", p) != 0)
17324 	error_at (c_parser_peek_token (parser)->location,
17325 		  "expected %<allocator%>");
17326       else if (parens.require_open (parser))
17327 	{
17328 	  location_t expr_loc = c_parser_peek_token (parser)->location;
17329 	  c_expr expr = c_parser_expr_no_commas (parser, NULL);
17330 	  expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
17331 	  allocator = expr.value;
17332 	  allocator = c_fully_fold (allocator, false, NULL);
17333 	  tree orig_type
17334 	    = expr.original_type ? expr.original_type : TREE_TYPE (allocator);
17335 	  orig_type = TYPE_MAIN_VARIANT (orig_type);
17336 	  if (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
17337 	      || TREE_CODE (orig_type) != ENUMERAL_TYPE
17338 	      || TYPE_NAME (orig_type)
17339 		 != get_identifier ("omp_allocator_handle_t"))
17340 	    {
17341 	      error_at (expr_loc, "%<allocator%> clause allocator expression "
17342 				"has type %qT rather than "
17343 				"%<omp_allocator_handle_t%>",
17344 				TREE_TYPE (allocator));
17345 	      allocator = NULL_TREE;
17346 	    }
17347 	  parens.skip_until_found_close (parser);
17348 	}
17349     }
17350   c_parser_skip_to_pragma_eol (parser);
17351 
17352   if (allocator)
17353     for (tree c = nl; c != NULL_TREE; c = OMP_CLAUSE_CHAIN (c))
17354       OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
17355 
17356   sorry_at (loc, "%<#pragma omp allocate%> not yet supported");
17357 }
17358 
17359 /* OpenMP 2.5:
17360    # pragma omp atomic new-line
17361      expression-stmt
17362 
17363    expression-stmt:
17364      x binop= expr | x++ | ++x | x-- | --x
17365    binop:
17366      +, *, -, /, &, ^, |, <<, >>
17367 
17368   where x is an lvalue expression with scalar type.
17369 
17370    OpenMP 3.1:
17371    # pragma omp atomic new-line
17372      update-stmt
17373 
17374    # pragma omp atomic read new-line
17375      read-stmt
17376 
17377    # pragma omp atomic write new-line
17378      write-stmt
17379 
17380    # pragma omp atomic update new-line
17381      update-stmt
17382 
17383    # pragma omp atomic capture new-line
17384      capture-stmt
17385 
17386    # pragma omp atomic capture new-line
17387      capture-block
17388 
17389    read-stmt:
17390      v = x
17391    write-stmt:
17392      x = expr
17393    update-stmt:
17394      expression-stmt | x = x binop expr
17395    capture-stmt:
17396      v = expression-stmt
17397    capture-block:
17398      { v = x; update-stmt; } | { update-stmt; v = x; }
17399 
17400    OpenMP 4.0:
17401    update-stmt:
17402      expression-stmt | x = x binop expr | x = expr binop x
17403    capture-stmt:
17404      v = update-stmt
17405    capture-block:
17406      { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
17407 
17408   where x and v are lvalue expressions with scalar type.
17409 
17410   LOC is the location of the #pragma token.  */
17411 
17412 static void
c_parser_omp_atomic(location_t loc,c_parser * parser,bool openacc)17413 c_parser_omp_atomic (location_t loc, c_parser *parser, bool openacc)
17414 {
17415   tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE;
17416   tree lhs1 = NULL_TREE, rhs1 = NULL_TREE;
17417   tree stmt, orig_lhs, unfolded_lhs = NULL_TREE, unfolded_lhs1 = NULL_TREE;
17418   enum tree_code code = ERROR_MARK, opcode = NOP_EXPR;
17419   enum omp_memory_order memory_order = OMP_MEMORY_ORDER_UNSPECIFIED;
17420   struct c_expr expr;
17421   location_t eloc;
17422   bool structured_block = false;
17423   bool swapped = false;
17424   bool non_lvalue_p;
17425   bool first = true;
17426   tree clauses = NULL_TREE;
17427 
17428   while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
17429     {
17430       if (!first && c_parser_next_token_is (parser, CPP_COMMA))
17431 	c_parser_consume_token (parser);
17432 
17433       first = false;
17434 
17435       if (c_parser_next_token_is (parser, CPP_NAME))
17436 	{
17437 	  const char *p
17438 	    = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17439 	  location_t cloc = c_parser_peek_token (parser)->location;
17440 	  enum tree_code new_code = ERROR_MARK;
17441 	  enum omp_memory_order new_memory_order
17442 	    = OMP_MEMORY_ORDER_UNSPECIFIED;
17443 
17444 	  if (!strcmp (p, "read"))
17445 	    new_code = OMP_ATOMIC_READ;
17446 	  else if (!strcmp (p, "write"))
17447 	    new_code = NOP_EXPR;
17448 	  else if (!strcmp (p, "update"))
17449 	    new_code = OMP_ATOMIC;
17450 	  else if (!strcmp (p, "capture"))
17451 	    new_code = OMP_ATOMIC_CAPTURE_NEW;
17452 	  else if (openacc)
17453 	    {
17454 	      p = NULL;
17455 	      error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
17456 			      "or %<capture%> clause");
17457 	    }
17458 	  else if (!strcmp (p, "seq_cst"))
17459 	    new_memory_order = OMP_MEMORY_ORDER_SEQ_CST;
17460 	  else if (!strcmp (p, "acq_rel"))
17461 	    new_memory_order = OMP_MEMORY_ORDER_ACQ_REL;
17462 	  else if (!strcmp (p, "release"))
17463 	    new_memory_order = OMP_MEMORY_ORDER_RELEASE;
17464 	  else if (!strcmp (p, "acquire"))
17465 	    new_memory_order = OMP_MEMORY_ORDER_ACQUIRE;
17466 	  else if (!strcmp (p, "relaxed"))
17467 	    new_memory_order = OMP_MEMORY_ORDER_RELAXED;
17468 	  else if (!strcmp (p, "hint"))
17469 	    {
17470 	      c_parser_consume_token (parser);
17471 	      clauses = c_parser_omp_clause_hint (parser, clauses);
17472 	      continue;
17473 	    }
17474 	  else
17475 	    {
17476 	      p = NULL;
17477 	      error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
17478 			      "%<capture%>, %<seq_cst%>, %<acq_rel%>, "
17479 			      "%<release%>, %<relaxed%> or %<hint%> clause");
17480 	    }
17481 	  if (p)
17482 	    {
17483 	      if (new_code != ERROR_MARK)
17484 		{
17485 		  /* OpenACC permits 'update capture'.  */
17486 		  if (openacc
17487 		      && code == OMP_ATOMIC
17488 		      && new_code == OMP_ATOMIC_CAPTURE_NEW)
17489 		    code = new_code;
17490 		  else if (code != ERROR_MARK)
17491 		    error_at (cloc, "too many atomic clauses");
17492 		  else
17493 		    code = new_code;
17494 		}
17495 	      else if (new_memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
17496 		{
17497 		  if (memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
17498 		    error_at (cloc, "too many memory order clauses");
17499 		  else
17500 		    memory_order = new_memory_order;
17501 		}
17502 	      c_parser_consume_token (parser);
17503 	      continue;
17504 	    }
17505 	}
17506       break;
17507     }
17508   c_parser_skip_to_pragma_eol (parser);
17509 
17510   if (code == ERROR_MARK)
17511     code = OMP_ATOMIC;
17512   if (openacc)
17513     memory_order = OMP_MEMORY_ORDER_RELAXED;
17514   else if (memory_order == OMP_MEMORY_ORDER_UNSPECIFIED)
17515     {
17516       omp_requires_mask
17517 	= (enum omp_requires) (omp_requires_mask
17518 			       | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED);
17519       switch ((enum omp_memory_order)
17520 	      (omp_requires_mask & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER))
17521 	{
17522 	case OMP_MEMORY_ORDER_UNSPECIFIED:
17523 	case OMP_MEMORY_ORDER_RELAXED:
17524 	  memory_order = OMP_MEMORY_ORDER_RELAXED;
17525 	  break;
17526 	case OMP_MEMORY_ORDER_SEQ_CST:
17527 	  memory_order = OMP_MEMORY_ORDER_SEQ_CST;
17528 	  break;
17529 	case OMP_MEMORY_ORDER_ACQ_REL:
17530 	  switch (code)
17531 	    {
17532 	    case OMP_ATOMIC_READ:
17533 	      memory_order = OMP_MEMORY_ORDER_ACQUIRE;
17534 	      break;
17535 	    case NOP_EXPR: /* atomic write */
17536 	    case OMP_ATOMIC:
17537 	      memory_order = OMP_MEMORY_ORDER_RELEASE;
17538 	      break;
17539 	    default:
17540 	      memory_order = OMP_MEMORY_ORDER_ACQ_REL;
17541 	      break;
17542 	    }
17543 	  break;
17544 	default:
17545 	  gcc_unreachable ();
17546 	}
17547     }
17548   else
17549     switch (code)
17550       {
17551       case OMP_ATOMIC_READ:
17552 	if (memory_order == OMP_MEMORY_ORDER_ACQ_REL
17553 	    || memory_order == OMP_MEMORY_ORDER_RELEASE)
17554 	  {
17555 	    error_at (loc, "%<#pragma omp atomic read%> incompatible with "
17556 			   "%<acq_rel%> or %<release%> clauses");
17557 	    memory_order = OMP_MEMORY_ORDER_SEQ_CST;
17558 	  }
17559 	break;
17560       case NOP_EXPR: /* atomic write */
17561 	if (memory_order == OMP_MEMORY_ORDER_ACQ_REL
17562 	    || memory_order == OMP_MEMORY_ORDER_ACQUIRE)
17563 	  {
17564 	    error_at (loc, "%<#pragma omp atomic write%> incompatible with "
17565 			   "%<acq_rel%> or %<acquire%> clauses");
17566 	    memory_order = OMP_MEMORY_ORDER_SEQ_CST;
17567 	  }
17568 	break;
17569       case OMP_ATOMIC:
17570      /* case OMP_ATOMIC_CAPTURE_NEW: - or update to OpenMP 5.1 */
17571 	if (memory_order == OMP_MEMORY_ORDER_ACQ_REL
17572 	    || memory_order == OMP_MEMORY_ORDER_ACQUIRE)
17573 	  {
17574 	    error_at (loc, "%<#pragma omp atomic update%> incompatible with "
17575 			   "%<acq_rel%> or %<acquire%> clauses");
17576 	    memory_order = OMP_MEMORY_ORDER_SEQ_CST;
17577 	  }
17578 	break;
17579       default:
17580 	break;
17581       }
17582 
17583   switch (code)
17584     {
17585     case OMP_ATOMIC_READ:
17586     case NOP_EXPR: /* atomic write */
17587       v = c_parser_cast_expression (parser, NULL).value;
17588       non_lvalue_p = !lvalue_p (v);
17589       v = c_fully_fold (v, false, NULL, true);
17590       if (v == error_mark_node)
17591 	goto saw_error;
17592       if (non_lvalue_p)
17593 	v = non_lvalue (v);
17594       loc = c_parser_peek_token (parser)->location;
17595       if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
17596 	goto saw_error;
17597       if (code == NOP_EXPR)
17598 	{
17599 	  lhs = c_parser_expression (parser).value;
17600 	  lhs = c_fully_fold (lhs, false, NULL);
17601 	  if (lhs == error_mark_node)
17602 	    goto saw_error;
17603 	}
17604       else
17605 	{
17606 	  lhs = c_parser_cast_expression (parser, NULL).value;
17607 	  non_lvalue_p = !lvalue_p (lhs);
17608 	  lhs = c_fully_fold (lhs, false, NULL, true);
17609 	  if (lhs == error_mark_node)
17610 	    goto saw_error;
17611 	  if (non_lvalue_p)
17612 	    lhs = non_lvalue (lhs);
17613 	}
17614       if (code == NOP_EXPR)
17615 	{
17616 	  /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
17617 	     opcode.  */
17618 	  code = OMP_ATOMIC;
17619 	  rhs = lhs;
17620 	  lhs = v;
17621 	  v = NULL_TREE;
17622 	}
17623       goto done;
17624     case OMP_ATOMIC_CAPTURE_NEW:
17625       if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
17626 	{
17627 	  c_parser_consume_token (parser);
17628 	  structured_block = true;
17629 	}
17630       else
17631 	{
17632 	  v = c_parser_cast_expression (parser, NULL).value;
17633 	  non_lvalue_p = !lvalue_p (v);
17634 	  v = c_fully_fold (v, false, NULL, true);
17635 	  if (v == error_mark_node)
17636 	    goto saw_error;
17637 	  if (non_lvalue_p)
17638 	    v = non_lvalue (v);
17639 	  if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
17640 	    goto saw_error;
17641 	}
17642       break;
17643     default:
17644       break;
17645     }
17646 
17647   /* For structured_block case we don't know yet whether
17648      old or new x should be captured.  */
17649 restart:
17650   eloc = c_parser_peek_token (parser)->location;
17651   expr = c_parser_cast_expression (parser, NULL);
17652   lhs = expr.value;
17653   expr = default_function_array_conversion (eloc, expr);
17654   unfolded_lhs = expr.value;
17655   lhs = c_fully_fold (lhs, false, NULL, true);
17656   orig_lhs = lhs;
17657   switch (TREE_CODE (lhs))
17658     {
17659     case ERROR_MARK:
17660     saw_error:
17661       c_parser_skip_to_end_of_block_or_statement (parser);
17662       if (structured_block)
17663 	{
17664 	  if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
17665 	    c_parser_consume_token (parser);
17666 	  else if (code == OMP_ATOMIC_CAPTURE_NEW)
17667 	    {
17668 	      c_parser_skip_to_end_of_block_or_statement (parser);
17669 	      if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
17670 		c_parser_consume_token (parser);
17671 	    }
17672 	}
17673       return;
17674 
17675     case POSTINCREMENT_EXPR:
17676       if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
17677 	code = OMP_ATOMIC_CAPTURE_OLD;
17678       /* FALLTHROUGH */
17679     case PREINCREMENT_EXPR:
17680       lhs = TREE_OPERAND (lhs, 0);
17681       unfolded_lhs = NULL_TREE;
17682       opcode = PLUS_EXPR;
17683       rhs = integer_one_node;
17684       break;
17685 
17686     case POSTDECREMENT_EXPR:
17687       if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
17688 	code = OMP_ATOMIC_CAPTURE_OLD;
17689       /* FALLTHROUGH */
17690     case PREDECREMENT_EXPR:
17691       lhs = TREE_OPERAND (lhs, 0);
17692       unfolded_lhs = NULL_TREE;
17693       opcode = MINUS_EXPR;
17694       rhs = integer_one_node;
17695       break;
17696 
17697     case COMPOUND_EXPR:
17698       if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR
17699 	  && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR
17700 	  && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR
17701 	  && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0)
17702 	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
17703 					      (TREE_OPERAND (lhs, 1), 0), 0)))
17704 	     == BOOLEAN_TYPE)
17705 	/* Undo effects of boolean_increment for post {in,de}crement.  */
17706 	lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
17707       /* FALLTHRU */
17708     case MODIFY_EXPR:
17709       if (TREE_CODE (lhs) == MODIFY_EXPR
17710 	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) == BOOLEAN_TYPE)
17711 	{
17712 	  /* Undo effects of boolean_increment.  */
17713 	  if (integer_onep (TREE_OPERAND (lhs, 1)))
17714 	    {
17715 	      /* This is pre or post increment.  */
17716 	      rhs = TREE_OPERAND (lhs, 1);
17717 	      lhs = TREE_OPERAND (lhs, 0);
17718 	      unfolded_lhs = NULL_TREE;
17719 	      opcode = NOP_EXPR;
17720 	      if (code == OMP_ATOMIC_CAPTURE_NEW
17721 		  && !structured_block
17722 		  && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
17723 		code = OMP_ATOMIC_CAPTURE_OLD;
17724 	      break;
17725 	    }
17726 	  if (TREE_CODE (TREE_OPERAND (lhs, 1)) == TRUTH_NOT_EXPR
17727 	      && TREE_OPERAND (lhs, 0)
17728 		 == TREE_OPERAND (TREE_OPERAND (lhs, 1), 0))
17729 	    {
17730 	      /* This is pre or post decrement.  */
17731 	      rhs = TREE_OPERAND (lhs, 1);
17732 	      lhs = TREE_OPERAND (lhs, 0);
17733 	      unfolded_lhs = NULL_TREE;
17734 	      opcode = NOP_EXPR;
17735 	      if (code == OMP_ATOMIC_CAPTURE_NEW
17736 		  && !structured_block
17737 		  && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
17738 		code = OMP_ATOMIC_CAPTURE_OLD;
17739 	      break;
17740 	    }
17741 	}
17742       /* FALLTHRU */
17743     default:
17744       if (!lvalue_p (unfolded_lhs))
17745 	lhs = non_lvalue (lhs);
17746       switch (c_parser_peek_token (parser)->type)
17747 	{
17748 	case CPP_MULT_EQ:
17749 	  opcode = MULT_EXPR;
17750 	  break;
17751 	case CPP_DIV_EQ:
17752 	  opcode = TRUNC_DIV_EXPR;
17753 	  break;
17754 	case CPP_PLUS_EQ:
17755 	  opcode = PLUS_EXPR;
17756 	  break;
17757 	case CPP_MINUS_EQ:
17758 	  opcode = MINUS_EXPR;
17759 	  break;
17760 	case CPP_LSHIFT_EQ:
17761 	  opcode = LSHIFT_EXPR;
17762 	  break;
17763 	case CPP_RSHIFT_EQ:
17764 	  opcode = RSHIFT_EXPR;
17765 	  break;
17766 	case CPP_AND_EQ:
17767 	  opcode = BIT_AND_EXPR;
17768 	  break;
17769 	case CPP_OR_EQ:
17770 	  opcode = BIT_IOR_EXPR;
17771 	  break;
17772 	case CPP_XOR_EQ:
17773 	  opcode = BIT_XOR_EXPR;
17774 	  break;
17775 	case CPP_EQ:
17776 	  c_parser_consume_token (parser);
17777 	  eloc = c_parser_peek_token (parser)->location;
17778 	  expr = c_parser_expr_no_commas (parser, NULL, unfolded_lhs);
17779 	  rhs1 = expr.value;
17780 	  switch (TREE_CODE (rhs1))
17781 	    {
17782 	    case MULT_EXPR:
17783 	    case TRUNC_DIV_EXPR:
17784 	    case RDIV_EXPR:
17785 	    case PLUS_EXPR:
17786 	    case MINUS_EXPR:
17787 	    case LSHIFT_EXPR:
17788 	    case RSHIFT_EXPR:
17789 	    case BIT_AND_EXPR:
17790 	    case BIT_IOR_EXPR:
17791 	    case BIT_XOR_EXPR:
17792 	      if (c_tree_equal (TREE_OPERAND (rhs1, 0), unfolded_lhs))
17793 		{
17794 		  opcode = TREE_CODE (rhs1);
17795 		  rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
17796 				      true);
17797 		  rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
17798 				       true);
17799 		  goto stmt_done;
17800 		}
17801 	      if (c_tree_equal (TREE_OPERAND (rhs1, 1), unfolded_lhs))
17802 		{
17803 		  opcode = TREE_CODE (rhs1);
17804 		  rhs = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
17805 				      true);
17806 		  rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
17807 				       true);
17808 		  swapped = !commutative_tree_code (opcode);
17809 		  goto stmt_done;
17810 		}
17811 	      break;
17812 	    case ERROR_MARK:
17813 	      goto saw_error;
17814 	    default:
17815 	      break;
17816 	    }
17817 	  if (c_parser_peek_token (parser)->type == CPP_SEMICOLON)
17818 	    {
17819 	      if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
17820 		{
17821 		  code = OMP_ATOMIC_CAPTURE_OLD;
17822 		  v = lhs;
17823 		  lhs = NULL_TREE;
17824 		  expr = default_function_array_read_conversion (eloc, expr);
17825 		  unfolded_lhs1 = expr.value;
17826 		  lhs1 = c_fully_fold (unfolded_lhs1, false, NULL, true);
17827 		  rhs1 = NULL_TREE;
17828 		  c_parser_consume_token (parser);
17829 		  goto restart;
17830 		}
17831 	      if (structured_block)
17832 		{
17833 		  opcode = NOP_EXPR;
17834 		  expr = default_function_array_read_conversion (eloc, expr);
17835 		  rhs = c_fully_fold (expr.value, false, NULL, true);
17836 		  rhs1 = NULL_TREE;
17837 		  goto stmt_done;
17838 		}
17839 	    }
17840 	  c_parser_error (parser, "invalid form of %<#pragma omp atomic%>");
17841 	  goto saw_error;
17842 	default:
17843 	  c_parser_error (parser,
17844 			  "invalid operator for %<#pragma omp atomic%>");
17845 	  goto saw_error;
17846 	}
17847 
17848       /* Arrange to pass the location of the assignment operator to
17849 	 c_finish_omp_atomic.  */
17850       loc = c_parser_peek_token (parser)->location;
17851       c_parser_consume_token (parser);
17852       eloc = c_parser_peek_token (parser)->location;
17853       expr = c_parser_expression (parser);
17854       expr = default_function_array_read_conversion (eloc, expr);
17855       rhs = expr.value;
17856       rhs = c_fully_fold (rhs, false, NULL, true);
17857       break;
17858     }
17859 stmt_done:
17860   if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
17861     {
17862       if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
17863 	goto saw_error;
17864       v = c_parser_cast_expression (parser, NULL).value;
17865       non_lvalue_p = !lvalue_p (v);
17866       v = c_fully_fold (v, false, NULL, true);
17867       if (v == error_mark_node)
17868 	goto saw_error;
17869       if (non_lvalue_p)
17870 	v = non_lvalue (v);
17871       if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
17872 	goto saw_error;
17873       eloc = c_parser_peek_token (parser)->location;
17874       expr = c_parser_cast_expression (parser, NULL);
17875       lhs1 = expr.value;
17876       expr = default_function_array_read_conversion (eloc, expr);
17877       unfolded_lhs1 = expr.value;
17878       lhs1 = c_fully_fold (lhs1, false, NULL, true);
17879       if (lhs1 == error_mark_node)
17880 	goto saw_error;
17881       if (!lvalue_p (unfolded_lhs1))
17882 	lhs1 = non_lvalue (lhs1);
17883     }
17884   if (structured_block)
17885     {
17886       c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
17887       c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>");
17888     }
17889 done:
17890   if (unfolded_lhs && unfolded_lhs1
17891       && !c_tree_equal (unfolded_lhs, unfolded_lhs1))
17892     {
17893       error ("%<#pragma omp atomic capture%> uses two different "
17894 	     "expressions for memory");
17895       stmt = error_mark_node;
17896     }
17897   else
17898     stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs, v, lhs1, rhs1,
17899 				swapped, memory_order);
17900   if (stmt != error_mark_node)
17901     add_stmt (stmt);
17902 
17903   if (!structured_block)
17904     c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
17905 }
17906 
17907 
17908 /* OpenMP 2.5:
17909    # pragma omp barrier new-line
17910 */
17911 
17912 static void
c_parser_omp_barrier(c_parser * parser)17913 c_parser_omp_barrier (c_parser *parser)
17914 {
17915   location_t loc = c_parser_peek_token (parser)->location;
17916   c_parser_consume_pragma (parser);
17917   c_parser_skip_to_pragma_eol (parser);
17918 
17919   c_finish_omp_barrier (loc);
17920 }
17921 
17922 /* OpenMP 2.5:
17923    # pragma omp critical [(name)] new-line
17924      structured-block
17925 
17926    OpenMP 4.5:
17927    # pragma omp critical [(name) [hint(expression)]] new-line
17928 
17929   LOC is the location of the #pragma itself.  */
17930 
17931 #define OMP_CRITICAL_CLAUSE_MASK		\
17932 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
17933 
17934 static tree
c_parser_omp_critical(location_t loc,c_parser * parser,bool * if_p)17935 c_parser_omp_critical (location_t loc, c_parser *parser, bool *if_p)
17936 {
17937   tree stmt, name = NULL_TREE, clauses = NULL_TREE;
17938 
17939   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
17940     {
17941       c_parser_consume_token (parser);
17942       if (c_parser_next_token_is (parser, CPP_NAME))
17943 	{
17944 	  name = c_parser_peek_token (parser)->value;
17945 	  c_parser_consume_token (parser);
17946 	  c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
17947 	}
17948       else
17949 	c_parser_error (parser, "expected identifier");
17950 
17951       if (c_parser_next_token_is (parser, CPP_COMMA)
17952 	  && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
17953 	c_parser_consume_token (parser);
17954     }
17955   clauses = c_parser_omp_all_clauses (parser, OMP_CRITICAL_CLAUSE_MASK,
17956 				      "#pragma omp critical");
17957   stmt = c_parser_omp_structured_block (parser, if_p);
17958   return c_finish_omp_critical (loc, stmt, name, clauses);
17959 }
17960 
17961 /* OpenMP 5.0:
17962    # pragma omp depobj ( depobj ) depobj-clause new-line
17963 
17964    depobj-clause:
17965      depend (dependence-type : locator)
17966      destroy
17967      update (dependence-type)
17968 
17969    dependence-type:
17970      in
17971      out
17972      inout
17973      mutexinout  */
17974 
17975 static void
c_parser_omp_depobj(c_parser * parser)17976 c_parser_omp_depobj (c_parser *parser)
17977 {
17978   location_t loc = c_parser_peek_token (parser)->location;
17979   c_parser_consume_pragma (parser);
17980   matching_parens parens;
17981   if (!parens.require_open (parser))
17982     {
17983       c_parser_skip_to_pragma_eol (parser);
17984       return;
17985     }
17986 
17987   tree depobj = c_parser_expr_no_commas (parser, NULL).value;
17988   if (depobj != error_mark_node)
17989     {
17990       if (!lvalue_p (depobj))
17991 	{
17992 	  error_at (EXPR_LOC_OR_LOC (depobj, loc),
17993 		    "%<depobj%> expression is not lvalue expression");
17994 	  depobj = error_mark_node;
17995 	}
17996       else
17997 	{
17998 	  tree addr = build_unary_op (EXPR_LOC_OR_LOC (depobj, loc), ADDR_EXPR,
17999 				      depobj, false);
18000 	  if (addr == error_mark_node)
18001 	    depobj = error_mark_node;
18002 	  else
18003 	    depobj = build_indirect_ref (EXPR_LOC_OR_LOC (depobj, loc),
18004 					 addr, RO_UNARY_STAR);
18005 	}
18006     }
18007 
18008   parens.skip_until_found_close (parser);
18009   tree clause = NULL_TREE;
18010   enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_SOURCE;
18011   location_t c_loc = c_parser_peek_token (parser)->location;
18012   if (c_parser_next_token_is (parser, CPP_NAME))
18013     {
18014       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18015 
18016       c_parser_consume_token (parser);
18017       if (!strcmp ("depend", p))
18018 	{
18019 	  clause = c_parser_omp_clause_depend (parser, NULL_TREE);
18020 	  clause = c_finish_omp_clauses (clause, C_ORT_OMP);
18021 	  if (!clause)
18022 	    clause = error_mark_node;
18023 	}
18024       else if (!strcmp ("destroy", p))
18025 	kind = OMP_CLAUSE_DEPEND_LAST;
18026       else if (!strcmp ("update", p))
18027 	{
18028 	  matching_parens c_parens;
18029 	  if (c_parens.require_open (parser))
18030 	    {
18031 	      location_t c2_loc = c_parser_peek_token (parser)->location;
18032 	      if (c_parser_next_token_is (parser, CPP_NAME))
18033 		{
18034 		  const char *p2
18035 		    = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18036 
18037 		  c_parser_consume_token (parser);
18038 		  if (!strcmp ("in", p2))
18039 		    kind = OMP_CLAUSE_DEPEND_IN;
18040 		  else if (!strcmp ("out", p2))
18041 		    kind = OMP_CLAUSE_DEPEND_OUT;
18042 		  else if (!strcmp ("inout", p2))
18043 		    kind = OMP_CLAUSE_DEPEND_INOUT;
18044 		  else if (!strcmp ("mutexinoutset", p2))
18045 		    kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
18046 		}
18047 	      if (kind == OMP_CLAUSE_DEPEND_SOURCE)
18048 		{
18049 		  clause = error_mark_node;
18050 		  error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%> or "
18051 				    "%<mutexinoutset%>");
18052 		}
18053 	      c_parens.skip_until_found_close (parser);
18054 	    }
18055 	  else
18056 	    clause = error_mark_node;
18057 	}
18058     }
18059   if (!clause && kind == OMP_CLAUSE_DEPEND_SOURCE)
18060     {
18061       clause = error_mark_node;
18062       error_at (c_loc, "expected %<depend%>, %<destroy%> or %<update%> clause");
18063     }
18064   c_parser_skip_to_pragma_eol (parser);
18065 
18066   c_finish_omp_depobj (loc, depobj, kind, clause);
18067 }
18068 
18069 
18070 /* OpenMP 2.5:
18071    # pragma omp flush flush-vars[opt] new-line
18072 
18073    flush-vars:
18074      ( variable-list )
18075 
18076    OpenMP 5.0:
18077    # pragma omp flush memory-order-clause new-line  */
18078 
18079 static void
c_parser_omp_flush(c_parser * parser)18080 c_parser_omp_flush (c_parser *parser)
18081 {
18082   location_t loc = c_parser_peek_token (parser)->location;
18083   c_parser_consume_pragma (parser);
18084   enum memmodel mo = MEMMODEL_LAST;
18085   if (c_parser_next_token_is (parser, CPP_NAME))
18086     {
18087       const char *p
18088 	= IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18089 
18090       if (!strcmp (p, "acq_rel"))
18091 	mo = MEMMODEL_ACQ_REL;
18092       else if (!strcmp (p, "release"))
18093 	mo = MEMMODEL_RELEASE;
18094       else if (!strcmp (p, "acquire"))
18095 	mo = MEMMODEL_ACQUIRE;
18096       else
18097 	error_at (c_parser_peek_token (parser)->location,
18098 		  "expected %<acq_rel%>, %<release%> or %<acquire%>");
18099       c_parser_consume_token (parser);
18100     }
18101   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
18102     {
18103       if (mo != MEMMODEL_LAST)
18104 	error_at (c_parser_peek_token (parser)->location,
18105 		  "%<flush%> list specified together with memory order "
18106 		  "clause");
18107       c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
18108     }
18109   else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
18110     c_parser_error (parser, "expected %<(%> or end of line");
18111   c_parser_skip_to_pragma_eol (parser);
18112 
18113   c_finish_omp_flush (loc, mo);
18114 }
18115 
18116 /* OpenMP 5.0:
18117 
18118    scan-loop-body:
18119      { structured-block scan-directive structured-block }  */
18120 
18121 static void
c_parser_omp_scan_loop_body(c_parser * parser,bool open_brace_parsed)18122 c_parser_omp_scan_loop_body (c_parser *parser, bool open_brace_parsed)
18123 {
18124   tree substmt;
18125   location_t loc;
18126   tree clauses = NULL_TREE;
18127 
18128   loc = c_parser_peek_token (parser)->location;
18129   if (!open_brace_parsed
18130       && !c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
18131     {
18132       /* Avoid skipping until the end of the block.  */
18133       parser->error = false;
18134       return;
18135     }
18136 
18137   substmt = c_parser_omp_structured_block (parser, NULL);
18138   substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE);
18139   SET_EXPR_LOCATION (substmt, loc);
18140   add_stmt (substmt);
18141 
18142   loc = c_parser_peek_token (parser)->location;
18143   if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SCAN)
18144     {
18145       enum omp_clause_code clause = OMP_CLAUSE_ERROR;
18146 
18147       c_parser_consume_pragma (parser);
18148 
18149       if (c_parser_next_token_is (parser, CPP_NAME))
18150 	{
18151 	  const char *p
18152 	    = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18153 	  if (strcmp (p, "inclusive") == 0)
18154 	    clause = OMP_CLAUSE_INCLUSIVE;
18155 	  else if (strcmp (p, "exclusive") == 0)
18156 	    clause = OMP_CLAUSE_EXCLUSIVE;
18157 	}
18158       if (clause != OMP_CLAUSE_ERROR)
18159 	{
18160 	  c_parser_consume_token (parser);
18161 	  clauses = c_parser_omp_var_list_parens (parser, clause, NULL_TREE);
18162 	}
18163       else
18164 	c_parser_error (parser, "expected %<inclusive%> or "
18165 				"%<exclusive%> clause");
18166       c_parser_skip_to_pragma_eol (parser);
18167     }
18168   else
18169     error ("expected %<#pragma omp scan%>");
18170 
18171   clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
18172   substmt = c_parser_omp_structured_block (parser, NULL);
18173   substmt = build2 (OMP_SCAN, void_type_node, substmt, clauses);
18174   SET_EXPR_LOCATION (substmt, loc);
18175   add_stmt (substmt);
18176 
18177   c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
18178 			     "expected %<}%>");
18179 }
18180 
18181 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
18182    The real trick here is to determine the loop control variable early
18183    so that we can push a new decl if necessary to make it private.
18184    LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
18185    respectively.  */
18186 
18187 static tree
c_parser_omp_for_loop(location_t loc,c_parser * parser,enum tree_code code,tree clauses,tree * cclauses,bool * if_p)18188 c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
18189 		       tree clauses, tree *cclauses, bool *if_p)
18190 {
18191   tree decl, cond, incr, body, init, stmt, cl;
18192   unsigned char save_in_statement;
18193   tree declv, condv, incrv, initv, ret = NULL_TREE;
18194   tree pre_body = NULL_TREE, this_pre_body;
18195   tree ordered_cl = NULL_TREE;
18196   bool fail = false, open_brace_parsed = false;
18197   int i, collapse = 1, ordered = 0, count, nbraces = 0;
18198   location_t for_loc;
18199   bool tiling = false;
18200   bool inscan = false;
18201   vec<tree, va_gc> *for_block = make_tree_vector ();
18202 
18203   for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
18204     if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
18205       collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl));
18206     else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_TILE)
18207       {
18208 	tiling = true;
18209 	collapse = list_length (OMP_CLAUSE_TILE_LIST (cl));
18210       }
18211     else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED
18212 	     && OMP_CLAUSE_ORDERED_EXPR (cl))
18213       {
18214 	ordered_cl = cl;
18215 	ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
18216       }
18217     else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_REDUCTION
18218 	     && OMP_CLAUSE_REDUCTION_INSCAN (cl)
18219 	     && (code == OMP_SIMD || code == OMP_FOR))
18220       inscan = true;
18221 
18222   if (ordered && ordered < collapse)
18223     {
18224       error_at (OMP_CLAUSE_LOCATION (ordered_cl),
18225 		"%<ordered%> clause parameter is less than %<collapse%>");
18226       OMP_CLAUSE_ORDERED_EXPR (ordered_cl)
18227 	= build_int_cst (NULL_TREE, collapse);
18228       ordered = collapse;
18229     }
18230   if (ordered)
18231     {
18232       for (tree *pc = &clauses; *pc; )
18233 	if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LINEAR)
18234 	  {
18235 	    error_at (OMP_CLAUSE_LOCATION (*pc),
18236 		      "%<linear%> clause may not be specified together "
18237 		      "with %<ordered%> clause with a parameter");
18238 	    *pc = OMP_CLAUSE_CHAIN (*pc);
18239 	  }
18240 	else
18241 	  pc = &OMP_CLAUSE_CHAIN (*pc);
18242     }
18243 
18244   gcc_assert (tiling || (collapse >= 1 && ordered >= 0));
18245   count = ordered ? ordered : collapse;
18246 
18247   declv = make_tree_vec (count);
18248   initv = make_tree_vec (count);
18249   condv = make_tree_vec (count);
18250   incrv = make_tree_vec (count);
18251 
18252   if (!c_parser_next_token_is_keyword (parser, RID_FOR))
18253     {
18254       c_parser_error (parser, "for statement expected");
18255       return NULL;
18256     }
18257   for_loc = c_parser_peek_token (parser)->location;
18258   c_parser_consume_token (parser);
18259 
18260   /* Forbid break/continue in the loop initializer, condition, and
18261      increment expressions.  */
18262   save_in_statement = in_statement;
18263   in_statement = IN_OMP_BLOCK;
18264 
18265   for (i = 0; i < count; i++)
18266     {
18267       int bracecount = 0;
18268 
18269       matching_parens parens;
18270       if (!parens.require_open (parser))
18271 	goto pop_scopes;
18272 
18273       /* Parse the initialization declaration or expression.  */
18274       if (c_parser_next_tokens_start_declaration (parser))
18275 	{
18276 	  if (i > 0)
18277 	    vec_safe_push (for_block, c_begin_compound_stmt (true));
18278 	  this_pre_body = push_stmt_list ();
18279 	  c_in_omp_for = true;
18280 	  c_parser_declaration_or_fndef (parser, true, true, true, true, true,
18281 					 NULL, vNULL);
18282 	  c_in_omp_for = false;
18283 	  if (this_pre_body)
18284 	    {
18285 	      this_pre_body = pop_stmt_list (this_pre_body);
18286 	      if (pre_body)
18287 		{
18288 		  tree t = pre_body;
18289 		  pre_body = push_stmt_list ();
18290 		  add_stmt (t);
18291 		  add_stmt (this_pre_body);
18292 		  pre_body = pop_stmt_list (pre_body);
18293 		}
18294 	      else
18295 		pre_body = this_pre_body;
18296 	    }
18297 	  decl = check_for_loop_decls (for_loc, flag_isoc99);
18298 	  if (decl == NULL)
18299 	    goto error_init;
18300 	  if (DECL_INITIAL (decl) == error_mark_node)
18301 	    decl = error_mark_node;
18302 	  init = decl;
18303 	}
18304       else if (c_parser_next_token_is (parser, CPP_NAME)
18305 	       && c_parser_peek_2nd_token (parser)->type == CPP_EQ)
18306 	{
18307 	  struct c_expr decl_exp;
18308 	  struct c_expr init_exp;
18309 	  location_t init_loc;
18310 
18311 	  decl_exp = c_parser_postfix_expression (parser);
18312 	  decl = decl_exp.value;
18313 
18314 	  c_parser_require (parser, CPP_EQ, "expected %<=%>");
18315 
18316 	  init_loc = c_parser_peek_token (parser)->location;
18317 	  init_exp = c_parser_expr_no_commas (parser, NULL);
18318 	  init_exp = default_function_array_read_conversion (init_loc,
18319 							     init_exp);
18320 	  c_in_omp_for = true;
18321 	  init = build_modify_expr (init_loc, decl, decl_exp.original_type,
18322 				    NOP_EXPR, init_loc, init_exp.value,
18323 				    init_exp.original_type);
18324 	  c_in_omp_for = false;
18325 	  init = c_process_expr_stmt (init_loc, init);
18326 
18327 	  c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
18328 	}
18329       else
18330 	{
18331 	error_init:
18332 	  c_parser_error (parser,
18333 			  "expected iteration declaration or initialization");
18334 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
18335 				     "expected %<)%>");
18336 	  fail = true;
18337 	  goto parse_next;
18338 	}
18339 
18340       /* Parse the loop condition.  */
18341       cond = NULL_TREE;
18342       if (c_parser_next_token_is_not (parser, CPP_SEMICOLON))
18343 	{
18344 	  location_t cond_loc = c_parser_peek_token (parser)->location;
18345 	  c_in_omp_for = true;
18346 	  struct c_expr cond_expr
18347 	    = c_parser_binary_expression (parser, NULL, NULL_TREE);
18348           c_in_omp_for = false;
18349 
18350 	  cond = cond_expr.value;
18351 	  cond = c_objc_common_truthvalue_conversion (cond_loc, cond);
18352 	  switch (cond_expr.original_code)
18353 	    {
18354 	    case GT_EXPR:
18355 	    case GE_EXPR:
18356 	    case LT_EXPR:
18357 	    case LE_EXPR:
18358 	      break;
18359 	    case NE_EXPR:
18360 	      if (code != OACC_LOOP)
18361 		break;
18362 	      /* FALLTHRU.  */
18363 	    default:
18364 	      /* Can't be cond = error_mark_node, because we want to preserve
18365 		 the location until c_finish_omp_for.  */
18366 	      cond = build1 (NOP_EXPR, boolean_type_node, error_mark_node);
18367 	      break;
18368 	    }
18369 	  protected_set_expr_location (cond, cond_loc);
18370 	}
18371       c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
18372 
18373       /* Parse the increment expression.  */
18374       incr = NULL_TREE;
18375       if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
18376 	{
18377 	  location_t incr_loc = c_parser_peek_token (parser)->location;
18378 
18379 	  incr = c_process_expr_stmt (incr_loc,
18380 				      c_parser_expression (parser).value);
18381 	}
18382       parens.skip_until_found_close (parser);
18383 
18384       if (decl == NULL || decl == error_mark_node || init == error_mark_node)
18385 	fail = true;
18386       else
18387 	{
18388 	  TREE_VEC_ELT (declv, i) = decl;
18389 	  TREE_VEC_ELT (initv, i) = init;
18390 	  TREE_VEC_ELT (condv, i) = cond;
18391 	  TREE_VEC_ELT (incrv, i) = incr;
18392 	}
18393 
18394     parse_next:
18395       if (i == count - 1)
18396 	break;
18397 
18398       /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
18399 	 in between the collapsed for loops to be still considered perfectly
18400 	 nested.  Hopefully the final version clarifies this.
18401 	 For now handle (multiple) {'s and empty statements.  */
18402       do
18403 	{
18404 	  if (c_parser_next_token_is_keyword (parser, RID_FOR))
18405 	    {
18406 	      c_parser_consume_token (parser);
18407 	      break;
18408 	    }
18409 	  else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
18410 	    {
18411 	      c_parser_consume_token (parser);
18412 	      bracecount++;
18413 	    }
18414 	  else if (bracecount
18415 		   && c_parser_next_token_is (parser, CPP_SEMICOLON))
18416 	    c_parser_consume_token (parser);
18417 	  else
18418 	    {
18419 	      c_parser_error (parser, "not enough perfectly nested loops");
18420 	      if (bracecount)
18421 		{
18422 		  open_brace_parsed = true;
18423 		  bracecount--;
18424 		}
18425 	      fail = true;
18426 	      count = 0;
18427 	      break;
18428 	    }
18429 	}
18430       while (1);
18431 
18432       nbraces += bracecount;
18433     }
18434 
18435   if (nbraces)
18436     if_p = NULL;
18437 
18438   in_statement = IN_OMP_FOR;
18439   body = push_stmt_list ();
18440 
18441   if (inscan)
18442     c_parser_omp_scan_loop_body (parser, open_brace_parsed);
18443   else if (open_brace_parsed)
18444     {
18445       location_t here = c_parser_peek_token (parser)->location;
18446       stmt = c_begin_compound_stmt (true);
18447       c_parser_compound_statement_nostart (parser);
18448       add_stmt (c_end_compound_stmt (here, stmt, true));
18449     }
18450   else
18451     add_stmt (c_parser_c99_block_statement (parser, if_p));
18452 
18453   body = pop_stmt_list (body);
18454   in_statement = save_in_statement;
18455 
18456   while (nbraces)
18457     {
18458       if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18459 	{
18460 	  c_parser_consume_token (parser);
18461 	  nbraces--;
18462 	}
18463       else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
18464 	c_parser_consume_token (parser);
18465       else
18466 	{
18467 	  c_parser_error (parser, "collapsed loops not perfectly nested");
18468 	  while (nbraces)
18469 	    {
18470 	      location_t here = c_parser_peek_token (parser)->location;
18471 	      stmt = c_begin_compound_stmt (true);
18472 	      add_stmt (body);
18473 	      c_parser_compound_statement_nostart (parser);
18474 	      body = c_end_compound_stmt (here, stmt, true);
18475 	      nbraces--;
18476 	    }
18477 	  goto pop_scopes;
18478 	}
18479     }
18480 
18481   /* Only bother calling c_finish_omp_for if we haven't already generated
18482      an error from the initialization parsing.  */
18483   if (!fail)
18484     {
18485       c_in_omp_for = true;
18486       stmt = c_finish_omp_for (loc, code, declv, NULL, initv, condv,
18487 			       incrv, body, pre_body, true);
18488       c_in_omp_for = false;
18489 
18490       /* Check for iterators appearing in lb, b or incr expressions.  */
18491       if (stmt && !c_omp_check_loop_iv (stmt, declv, NULL))
18492 	stmt = NULL_TREE;
18493 
18494       if (stmt)
18495 	{
18496 	  add_stmt (stmt);
18497 
18498 	  for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (stmt)); i++)
18499 	    {
18500 	      tree init = TREE_VEC_ELT (OMP_FOR_INIT (stmt), i);
18501 	      gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
18502 	      tree decl = TREE_OPERAND (init, 0);
18503 	      tree cond = TREE_VEC_ELT (OMP_FOR_COND (stmt), i);
18504 	      gcc_assert (COMPARISON_CLASS_P (cond));
18505 	      gcc_assert (TREE_OPERAND (cond, 0) == decl);
18506 
18507 	      tree op0 = TREE_OPERAND (init, 1);
18508 	      if (!OMP_FOR_NON_RECTANGULAR (stmt)
18509 		  || TREE_CODE (op0) != TREE_VEC)
18510 		TREE_OPERAND (init, 1) = c_fully_fold (op0, false, NULL);
18511 	      else
18512 		{
18513 		  TREE_VEC_ELT (op0, 1)
18514 		    = c_fully_fold (TREE_VEC_ELT (op0, 1), false, NULL);
18515 		  TREE_VEC_ELT (op0, 2)
18516 		    = c_fully_fold (TREE_VEC_ELT (op0, 2), false, NULL);
18517 		}
18518 
18519 	      tree op1 = TREE_OPERAND (cond, 1);
18520 	      if (!OMP_FOR_NON_RECTANGULAR (stmt)
18521 		  || TREE_CODE (op1) != TREE_VEC)
18522 		TREE_OPERAND (cond, 1) = c_fully_fold (op1, false, NULL);
18523 	      else
18524 		{
18525 		  TREE_VEC_ELT (op1, 1)
18526 		    = c_fully_fold (TREE_VEC_ELT (op1, 1), false, NULL);
18527 		  TREE_VEC_ELT (op1, 2)
18528 		    = c_fully_fold (TREE_VEC_ELT (op1, 2), false, NULL);
18529 		}
18530 	    }
18531 
18532 	  if (cclauses != NULL
18533 	      && cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL)
18534 	    {
18535 	      tree *c;
18536 	      for (c = &cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; *c ; )
18537 		if (OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_FIRSTPRIVATE
18538 		    && OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_LASTPRIVATE)
18539 		  c = &OMP_CLAUSE_CHAIN (*c);
18540 		else
18541 		  {
18542 		    for (i = 0; i < count; i++)
18543 		      if (TREE_VEC_ELT (declv, i) == OMP_CLAUSE_DECL (*c))
18544 			break;
18545 		    if (i == count)
18546 		      c = &OMP_CLAUSE_CHAIN (*c);
18547 		    else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE)
18548 		      {
18549 			error_at (loc,
18550 				  "iteration variable %qD should not be firstprivate",
18551 				  OMP_CLAUSE_DECL (*c));
18552 			*c = OMP_CLAUSE_CHAIN (*c);
18553 		      }
18554 		    else
18555 		      {
18556 			/* Move lastprivate (decl) clause to OMP_FOR_CLAUSES.  */
18557 			tree l = *c;
18558 			*c = OMP_CLAUSE_CHAIN (*c);
18559 			if (code == OMP_SIMD)
18560 			  {
18561 			    OMP_CLAUSE_CHAIN (l)
18562 			      = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
18563 			    cclauses[C_OMP_CLAUSE_SPLIT_FOR] = l;
18564 			  }
18565 			else
18566 			  {
18567 			    OMP_CLAUSE_CHAIN (l) = clauses;
18568 			    clauses = l;
18569 			  }
18570 		      }
18571 		  }
18572 	    }
18573 	  OMP_FOR_CLAUSES (stmt) = clauses;
18574 	}
18575       ret = stmt;
18576     }
18577 pop_scopes:
18578   while (!for_block->is_empty ())
18579     {
18580       /* FIXME diagnostics: LOC below should be the actual location of
18581 	 this particular for block.  We need to build a list of
18582 	 locations to go along with FOR_BLOCK.  */
18583       stmt = c_end_compound_stmt (loc, for_block->pop (), true);
18584       add_stmt (stmt);
18585     }
18586   release_tree_vector (for_block);
18587   return ret;
18588 }
18589 
18590 /* Helper function for OpenMP parsing, split clauses and call
18591    finish_omp_clauses on each of the set of clauses afterwards.  */
18592 
18593 static void
omp_split_clauses(location_t loc,enum tree_code code,omp_clause_mask mask,tree clauses,tree * cclauses)18594 omp_split_clauses (location_t loc, enum tree_code code,
18595 		   omp_clause_mask mask, tree clauses, tree *cclauses)
18596 {
18597   int i;
18598   c_omp_split_clauses (loc, code, mask, clauses, cclauses);
18599   for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
18600     if (cclauses[i])
18601       cclauses[i] = c_finish_omp_clauses (cclauses[i], C_ORT_OMP);
18602 }
18603 
18604 /* OpenMP 5.0:
18605    #pragma omp loop loop-clause[optseq] new-line
18606      for-loop
18607 
18608    LOC is the location of the #pragma token.
18609 */
18610 
18611 #define OMP_LOOP_CLAUSE_MASK					\
18612 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
18613 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)	\
18614 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)	\
18615 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)	\
18616 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND)		\
18617 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
18618 
18619 static tree
c_parser_omp_loop(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)18620 c_parser_omp_loop (location_t loc, c_parser *parser,
18621 		   char *p_name, omp_clause_mask mask, tree *cclauses,
18622 		   bool *if_p)
18623 {
18624   tree block, clauses, ret;
18625 
18626   strcat (p_name, " loop");
18627   mask |= OMP_LOOP_CLAUSE_MASK;
18628 
18629   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
18630   if (cclauses)
18631     {
18632       omp_split_clauses (loc, OMP_LOOP, mask, clauses, cclauses);
18633       clauses = cclauses[C_OMP_CLAUSE_SPLIT_LOOP];
18634     }
18635 
18636   block = c_begin_compound_stmt (true);
18637   ret = c_parser_omp_for_loop (loc, parser, OMP_LOOP, clauses, cclauses, if_p);
18638   block = c_end_compound_stmt (loc, block, true);
18639   add_stmt (block);
18640 
18641   return ret;
18642 }
18643 
18644 /* OpenMP 4.0:
18645    #pragma omp simd simd-clause[optseq] new-line
18646      for-loop
18647 
18648    LOC is the location of the #pragma token.
18649 */
18650 
18651 #define OMP_SIMD_CLAUSE_MASK					\
18652 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN)	\
18653 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN)	\
18654 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR)	\
18655 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED)	\
18656 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
18657 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)	\
18658 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)	\
18659 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)	\
18660 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
18661 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL)	\
18662 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
18663 
18664 static tree
c_parser_omp_simd(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)18665 c_parser_omp_simd (location_t loc, c_parser *parser,
18666 		   char *p_name, omp_clause_mask mask, tree *cclauses,
18667 		   bool *if_p)
18668 {
18669   tree block, clauses, ret;
18670 
18671   strcat (p_name, " simd");
18672   mask |= OMP_SIMD_CLAUSE_MASK;
18673 
18674   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
18675   if (cclauses)
18676     {
18677       omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses);
18678       clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
18679       tree c = omp_find_clause (cclauses[C_OMP_CLAUSE_SPLIT_FOR],
18680 				OMP_CLAUSE_ORDERED);
18681       if (c && OMP_CLAUSE_ORDERED_EXPR (c))
18682 	{
18683 	  error_at (OMP_CLAUSE_LOCATION (c),
18684 		    "%<ordered%> clause with parameter may not be specified "
18685 		    "on %qs construct", p_name);
18686 	  OMP_CLAUSE_ORDERED_EXPR (c) = NULL_TREE;
18687 	}
18688     }
18689 
18690   block = c_begin_compound_stmt (true);
18691   ret = c_parser_omp_for_loop (loc, parser, OMP_SIMD, clauses, cclauses, if_p);
18692   block = c_end_compound_stmt (loc, block, true);
18693   add_stmt (block);
18694 
18695   return ret;
18696 }
18697 
18698 /* OpenMP 2.5:
18699    #pragma omp for for-clause[optseq] new-line
18700      for-loop
18701 
18702    OpenMP 4.0:
18703    #pragma omp for simd for-simd-clause[optseq] new-line
18704      for-loop
18705 
18706    LOC is the location of the #pragma token.
18707 */
18708 
18709 #define OMP_FOR_CLAUSE_MASK					\
18710 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
18711 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
18712 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)	\
18713 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR)	\
18714 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)	\
18715 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED)	\
18716 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)	\
18717 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)	\
18718 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT)	\
18719 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)	\
18720 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
18721 
18722 static tree
c_parser_omp_for(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)18723 c_parser_omp_for (location_t loc, c_parser *parser,
18724 		  char *p_name, omp_clause_mask mask, tree *cclauses,
18725 		  bool *if_p)
18726 {
18727   tree block, clauses, ret;
18728 
18729   strcat (p_name, " for");
18730   mask |= OMP_FOR_CLAUSE_MASK;
18731   /* parallel for{, simd} disallows nowait clause, but for
18732      target {teams distribute ,}parallel for{, simd} it should be accepted.  */
18733   if (cclauses && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0)
18734     mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
18735   /* Composite distribute parallel for{, simd} disallows ordered clause.  */
18736   if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
18737     mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED);
18738 
18739   if (c_parser_next_token_is (parser, CPP_NAME))
18740     {
18741       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18742 
18743       if (strcmp (p, "simd") == 0)
18744 	{
18745 	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18746 	  if (cclauses == NULL)
18747 	    cclauses = cclauses_buf;
18748 
18749 	  c_parser_consume_token (parser);
18750 	  if (!flag_openmp)  /* flag_openmp_simd  */
18751 	    return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
18752 				      if_p);
18753 	  block = c_begin_compound_stmt (true);
18754 	  ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
18755 	  block = c_end_compound_stmt (loc, block, true);
18756 	  if (ret == NULL_TREE)
18757 	    return ret;
18758 	  ret = make_node (OMP_FOR);
18759 	  TREE_TYPE (ret) = void_type_node;
18760 	  OMP_FOR_BODY (ret) = block;
18761 	  OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
18762 	  SET_EXPR_LOCATION (ret, loc);
18763 	  add_stmt (ret);
18764 	  return ret;
18765 	}
18766     }
18767   if (!flag_openmp)  /* flag_openmp_simd  */
18768     {
18769       c_parser_skip_to_pragma_eol (parser, false);
18770       return NULL_TREE;
18771     }
18772 
18773   /* Composite distribute parallel for disallows linear clause.  */
18774   if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
18775     mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR);
18776 
18777   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
18778   if (cclauses)
18779     {
18780       omp_split_clauses (loc, OMP_FOR, mask, clauses, cclauses);
18781       clauses = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
18782     }
18783 
18784   block = c_begin_compound_stmt (true);
18785   ret = c_parser_omp_for_loop (loc, parser, OMP_FOR, clauses, cclauses, if_p);
18786   block = c_end_compound_stmt (loc, block, true);
18787   add_stmt (block);
18788 
18789   return ret;
18790 }
18791 
18792 static tree c_parser_omp_taskloop (location_t, c_parser *, char *,
18793 				   omp_clause_mask, tree *, bool *);
18794 
18795 /* OpenMP 2.5:
18796    # pragma omp master new-line
18797      structured-block
18798 
18799    LOC is the location of the #pragma token.
18800 */
18801 
18802 static tree
c_parser_omp_master(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)18803 c_parser_omp_master (location_t loc, c_parser *parser,
18804 		     char *p_name, omp_clause_mask mask, tree *cclauses,
18805 		     bool *if_p)
18806 {
18807   tree block, clauses, ret;
18808 
18809   strcat (p_name, " master");
18810 
18811   if (c_parser_next_token_is (parser, CPP_NAME))
18812     {
18813       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18814 
18815       if (strcmp (p, "taskloop") == 0)
18816 	{
18817 	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18818 	  if (cclauses == NULL)
18819 	    cclauses = cclauses_buf;
18820 
18821 	  c_parser_consume_token (parser);
18822 	  if (!flag_openmp)  /* flag_openmp_simd  */
18823 	    return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
18824 					  if_p);
18825 	  block = c_begin_compound_stmt (true);
18826 	  ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
18827 				       if_p);
18828 	  block = c_end_compound_stmt (loc, block, true);
18829 	  if (ret == NULL_TREE)
18830 	    return ret;
18831 	  ret = c_finish_omp_master (loc, block);
18832 	  return ret;
18833 	}
18834     }
18835   if (!flag_openmp)  /* flag_openmp_simd  */
18836     {
18837       c_parser_skip_to_pragma_eol (parser, false);
18838       return NULL_TREE;
18839     }
18840 
18841   if (cclauses)
18842     {
18843       clauses = c_parser_omp_all_clauses (parser, mask, p_name, false);
18844       omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses);
18845     }
18846   else
18847     c_parser_skip_to_pragma_eol (parser);
18848 
18849   return c_finish_omp_master (loc, c_parser_omp_structured_block (parser,
18850 								  if_p));
18851 }
18852 
18853 /* OpenMP 2.5:
18854    # pragma omp ordered new-line
18855      structured-block
18856 
18857    OpenMP 4.5:
18858    # pragma omp ordered ordered-clauses new-line
18859      structured-block
18860 
18861    # pragma omp ordered depend-clauses new-line  */
18862 
18863 #define OMP_ORDERED_CLAUSE_MASK					\
18864 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS)	\
18865 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
18866 
18867 #define OMP_ORDERED_DEPEND_CLAUSE_MASK				\
18868 	(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
18869 
18870 static bool
c_parser_omp_ordered(c_parser * parser,enum pragma_context context,bool * if_p)18871 c_parser_omp_ordered (c_parser *parser, enum pragma_context context,
18872 		      bool *if_p)
18873 {
18874   location_t loc = c_parser_peek_token (parser)->location;
18875   c_parser_consume_pragma (parser);
18876 
18877   if (context != pragma_stmt && context != pragma_compound)
18878     {
18879       c_parser_error (parser, "expected declaration specifiers");
18880       c_parser_skip_to_pragma_eol (parser, false);
18881       return false;
18882     }
18883 
18884   if (c_parser_next_token_is (parser, CPP_NAME))
18885     {
18886       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18887 
18888       if (!strcmp ("depend", p))
18889 	{
18890 	  if (!flag_openmp)	/* flag_openmp_simd  */
18891 	    {
18892 	      c_parser_skip_to_pragma_eol (parser, false);
18893 	      return false;
18894 	    }
18895 	  if (context == pragma_stmt)
18896 	    {
18897 	      error_at (loc,
18898 			"%<#pragma omp ordered%> with %<depend%> clause may "
18899 			"only be used in compound statements");
18900 	      c_parser_skip_to_pragma_eol (parser, false);
18901 	      return false;
18902 	    }
18903 
18904 	  tree clauses
18905 	    = c_parser_omp_all_clauses (parser,
18906 					OMP_ORDERED_DEPEND_CLAUSE_MASK,
18907 					"#pragma omp ordered");
18908 	  c_finish_omp_ordered (loc, clauses, NULL_TREE);
18909 	  return false;
18910 	}
18911     }
18912 
18913   tree clauses = c_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK,
18914 					   "#pragma omp ordered");
18915 
18916   if (!flag_openmp	/* flag_openmp_simd  */
18917       && omp_find_clause (clauses, OMP_CLAUSE_SIMD) == NULL_TREE)
18918     return false;
18919 
18920   c_finish_omp_ordered (loc, clauses,
18921 			c_parser_omp_structured_block (parser, if_p));
18922   return true;
18923 }
18924 
18925 /* OpenMP 2.5:
18926 
18927    section-scope:
18928      { section-sequence }
18929 
18930    section-sequence:
18931      section-directive[opt] structured-block
18932      section-sequence section-directive structured-block
18933 
18934     SECTIONS_LOC is the location of the #pragma omp sections.  */
18935 
18936 static tree
c_parser_omp_sections_scope(location_t sections_loc,c_parser * parser)18937 c_parser_omp_sections_scope (location_t sections_loc, c_parser *parser)
18938 {
18939   tree stmt, substmt;
18940   bool error_suppress = false;
18941   location_t loc;
18942 
18943   loc = c_parser_peek_token (parser)->location;
18944   if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
18945     {
18946       /* Avoid skipping until the end of the block.  */
18947       parser->error = false;
18948       return NULL_TREE;
18949     }
18950 
18951   stmt = push_stmt_list ();
18952 
18953   if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION)
18954     {
18955       substmt = c_parser_omp_structured_block (parser, NULL);
18956       substmt = build1 (OMP_SECTION, void_type_node, substmt);
18957       SET_EXPR_LOCATION (substmt, loc);
18958       add_stmt (substmt);
18959     }
18960 
18961   while (1)
18962     {
18963       if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18964 	break;
18965       if (c_parser_next_token_is (parser, CPP_EOF))
18966 	break;
18967 
18968       loc = c_parser_peek_token (parser)->location;
18969       if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION)
18970 	{
18971 	  c_parser_consume_pragma (parser);
18972 	  c_parser_skip_to_pragma_eol (parser);
18973 	  error_suppress = false;
18974 	}
18975       else if (!error_suppress)
18976 	{
18977 	  error_at (loc, "expected %<#pragma omp section%> or %<}%>");
18978 	  error_suppress = true;
18979 	}
18980 
18981       substmt = c_parser_omp_structured_block (parser, NULL);
18982       substmt = build1 (OMP_SECTION, void_type_node, substmt);
18983       SET_EXPR_LOCATION (substmt, loc);
18984       add_stmt (substmt);
18985     }
18986   c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
18987 			     "expected %<#pragma omp section%> or %<}%>");
18988 
18989   substmt = pop_stmt_list (stmt);
18990 
18991   stmt = make_node (OMP_SECTIONS);
18992   SET_EXPR_LOCATION (stmt, sections_loc);
18993   TREE_TYPE (stmt) = void_type_node;
18994   OMP_SECTIONS_BODY (stmt) = substmt;
18995 
18996   return add_stmt (stmt);
18997 }
18998 
18999 /* OpenMP 2.5:
19000    # pragma omp sections sections-clause[optseq] newline
19001      sections-scope
19002 
19003    LOC is the location of the #pragma token.
19004 */
19005 
19006 #define OMP_SECTIONS_CLAUSE_MASK				\
19007 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
19008 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
19009 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)	\
19010 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)	\
19011 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)	\
19012 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19013 
19014 static tree
c_parser_omp_sections(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses)19015 c_parser_omp_sections (location_t loc, c_parser *parser,
19016 		       char *p_name, omp_clause_mask mask, tree *cclauses)
19017 {
19018   tree block, clauses, ret;
19019 
19020   strcat (p_name, " sections");
19021   mask |= OMP_SECTIONS_CLAUSE_MASK;
19022   if (cclauses)
19023     mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
19024 
19025   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19026   if (cclauses)
19027     {
19028       omp_split_clauses (loc, OMP_SECTIONS, mask, clauses, cclauses);
19029       clauses = cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS];
19030     }
19031 
19032   block = c_begin_compound_stmt (true);
19033   ret = c_parser_omp_sections_scope (loc, parser);
19034   if (ret)
19035     OMP_SECTIONS_CLAUSES (ret) = clauses;
19036   block = c_end_compound_stmt (loc, block, true);
19037   add_stmt (block);
19038 
19039   return ret;
19040 }
19041 
19042 /* OpenMP 2.5:
19043    # pragma omp parallel parallel-clause[optseq] new-line
19044      structured-block
19045    # pragma omp parallel for parallel-for-clause[optseq] new-line
19046      structured-block
19047    # pragma omp parallel sections parallel-sections-clause[optseq] new-line
19048      structured-block
19049 
19050    OpenMP 4.0:
19051    # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
19052      structured-block
19053 
19054    LOC is the location of the #pragma token.
19055 */
19056 
19057 #define OMP_PARALLEL_CLAUSE_MASK				\
19058 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
19059 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
19060 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
19061 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT)	\
19062 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED)	\
19063 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN)	\
19064 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)	\
19065 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)	\
19066 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)	\
19067 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
19068 
19069 static tree
c_parser_omp_parallel(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)19070 c_parser_omp_parallel (location_t loc, c_parser *parser,
19071 		       char *p_name, omp_clause_mask mask, tree *cclauses,
19072 		       bool *if_p)
19073 {
19074   tree stmt, clauses, block;
19075 
19076   strcat (p_name, " parallel");
19077   mask |= OMP_PARALLEL_CLAUSE_MASK;
19078   /* #pragma omp target parallel{, for, for simd} disallow copyin clause.  */
19079   if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0
19080       && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
19081     mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN);
19082 
19083   if (c_parser_next_token_is_keyword (parser, RID_FOR))
19084     {
19085       tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19086       if (cclauses == NULL)
19087 	cclauses = cclauses_buf;
19088 
19089       c_parser_consume_token (parser);
19090       if (!flag_openmp)  /* flag_openmp_simd  */
19091 	return c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
19092       block = c_begin_omp_parallel ();
19093       tree ret = c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
19094       stmt
19095 	= c_finish_omp_parallel (loc, cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
19096 				 block);
19097       if (ret == NULL_TREE)
19098 	return ret;
19099       OMP_PARALLEL_COMBINED (stmt) = 1;
19100       return stmt;
19101     }
19102   /* When combined with distribute, parallel has to be followed by for.
19103      #pragma omp target parallel is allowed though.  */
19104   else if (cclauses
19105 	   && (mask & (OMP_CLAUSE_MASK_1
19106 		       << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
19107     {
19108       error_at (loc, "expected %<for%> after %qs", p_name);
19109       c_parser_skip_to_pragma_eol (parser);
19110       return NULL_TREE;
19111     }
19112   else if (c_parser_next_token_is (parser, CPP_NAME))
19113     {
19114       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19115       if (cclauses == NULL && strcmp (p, "master") == 0)
19116 	{
19117 	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19118 	  cclauses = cclauses_buf;
19119 
19120 	  c_parser_consume_token (parser);
19121 	  if (!flag_openmp)  /* flag_openmp_simd  */
19122 	    return c_parser_omp_master (loc, parser, p_name, mask, cclauses,
19123 					if_p);
19124 	  block = c_begin_omp_parallel ();
19125 	  tree ret = c_parser_omp_master (loc, parser, p_name, mask, cclauses,
19126 					  if_p);
19127 	  stmt = c_finish_omp_parallel (loc,
19128 					cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
19129 					block);
19130 	  if (ret == NULL)
19131 	    return ret;
19132 	  OMP_PARALLEL_COMBINED (stmt) = 1;
19133 	  return stmt;
19134 	}
19135       else if (strcmp (p, "loop") == 0)
19136 	{
19137 	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19138 	  if (cclauses == NULL)
19139 	    cclauses = cclauses_buf;
19140 
19141 	  c_parser_consume_token (parser);
19142 	  if (!flag_openmp)  /* flag_openmp_simd  */
19143 	    return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
19144 				      if_p);
19145 	  block = c_begin_omp_parallel ();
19146 	  tree ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
19147 					if_p);
19148 	  stmt
19149 	    = c_finish_omp_parallel (loc,
19150 				     cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
19151 				     block);
19152 	  if (ret == NULL_TREE)
19153 	    return ret;
19154 	  OMP_PARALLEL_COMBINED (stmt) = 1;
19155 	  return stmt;
19156 	}
19157       else if (!flag_openmp)  /* flag_openmp_simd  */
19158 	{
19159 	  c_parser_skip_to_pragma_eol (parser, false);
19160 	  return NULL_TREE;
19161 	}
19162       else if (cclauses == NULL && strcmp (p, "sections") == 0)
19163 	{
19164 	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19165 	  cclauses = cclauses_buf;
19166 
19167 	  c_parser_consume_token (parser);
19168 	  block = c_begin_omp_parallel ();
19169 	  c_parser_omp_sections (loc, parser, p_name, mask, cclauses);
19170 	  stmt = c_finish_omp_parallel (loc,
19171 					cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
19172 					block);
19173 	  OMP_PARALLEL_COMBINED (stmt) = 1;
19174 	  return stmt;
19175 	}
19176     }
19177   else if (!flag_openmp)  /* flag_openmp_simd  */
19178     {
19179       c_parser_skip_to_pragma_eol (parser, false);
19180       return NULL_TREE;
19181     }
19182 
19183   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19184   if (cclauses)
19185     {
19186       omp_split_clauses (loc, OMP_PARALLEL, mask, clauses, cclauses);
19187       clauses = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
19188     }
19189 
19190   block = c_begin_omp_parallel ();
19191   c_parser_statement (parser, if_p);
19192   stmt = c_finish_omp_parallel (loc, clauses, block);
19193 
19194   return stmt;
19195 }
19196 
19197 /* OpenMP 2.5:
19198    # pragma omp single single-clause[optseq] new-line
19199      structured-block
19200 
19201    LOC is the location of the #pragma.
19202 */
19203 
19204 #define OMP_SINGLE_CLAUSE_MASK					\
19205 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
19206 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
19207 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE)	\
19208 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)	\
19209 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19210 
19211 static tree
c_parser_omp_single(location_t loc,c_parser * parser,bool * if_p)19212 c_parser_omp_single (location_t loc, c_parser *parser, bool *if_p)
19213 {
19214   tree stmt = make_node (OMP_SINGLE);
19215   SET_EXPR_LOCATION (stmt, loc);
19216   TREE_TYPE (stmt) = void_type_node;
19217 
19218   OMP_SINGLE_CLAUSES (stmt)
19219     = c_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK,
19220 				"#pragma omp single");
19221   OMP_SINGLE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
19222 
19223   return add_stmt (stmt);
19224 }
19225 
19226 /* OpenMP 3.0:
19227    # pragma omp task task-clause[optseq] new-line
19228 
19229    LOC is the location of the #pragma.
19230 */
19231 
19232 #define OMP_TASK_CLAUSE_MASK					\
19233 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
19234 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED)	\
19235 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT)	\
19236 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
19237 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
19238 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED)	\
19239 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL)	\
19240 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE)	\
19241 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)	\
19242 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY)	\
19243 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)	\
19244 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION)	\
19245 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH))
19246 
19247 static tree
c_parser_omp_task(location_t loc,c_parser * parser,bool * if_p)19248 c_parser_omp_task (location_t loc, c_parser *parser, bool *if_p)
19249 {
19250   tree clauses, block;
19251 
19252   clauses = c_parser_omp_all_clauses (parser, OMP_TASK_CLAUSE_MASK,
19253 				      "#pragma omp task");
19254 
19255   block = c_begin_omp_task ();
19256   c_parser_statement (parser, if_p);
19257   return c_finish_omp_task (loc, clauses, block);
19258 }
19259 
19260 /* OpenMP 3.0:
19261    # pragma omp taskwait new-line
19262 
19263    OpenMP 5.0:
19264    # pragma omp taskwait taskwait-clause[optseq] new-line
19265 */
19266 
19267 #define OMP_TASKWAIT_CLAUSE_MASK					\
19268 	(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
19269 
19270 static void
c_parser_omp_taskwait(c_parser * parser)19271 c_parser_omp_taskwait (c_parser *parser)
19272 {
19273   location_t loc = c_parser_peek_token (parser)->location;
19274   c_parser_consume_pragma (parser);
19275 
19276   tree clauses
19277     = c_parser_omp_all_clauses (parser, OMP_TASKWAIT_CLAUSE_MASK,
19278 				"#pragma omp taskwait");
19279 
19280   if (clauses)
19281     {
19282       tree stmt = make_node (OMP_TASK);
19283       TREE_TYPE (stmt) = void_node;
19284       OMP_TASK_CLAUSES (stmt) = clauses;
19285       OMP_TASK_BODY (stmt) = NULL_TREE;
19286       SET_EXPR_LOCATION (stmt, loc);
19287       add_stmt (stmt);
19288     }
19289   else
19290     c_finish_omp_taskwait (loc);
19291 }
19292 
19293 /* OpenMP 3.1:
19294    # pragma omp taskyield new-line
19295 */
19296 
19297 static void
c_parser_omp_taskyield(c_parser * parser)19298 c_parser_omp_taskyield (c_parser *parser)
19299 {
19300   location_t loc = c_parser_peek_token (parser)->location;
19301   c_parser_consume_pragma (parser);
19302   c_parser_skip_to_pragma_eol (parser);
19303 
19304   c_finish_omp_taskyield (loc);
19305 }
19306 
19307 /* OpenMP 4.0:
19308    # pragma omp taskgroup new-line
19309 
19310    OpenMP 5.0:
19311    # pragma omp taskgroup taskgroup-clause[optseq] new-line
19312 */
19313 
19314 #define OMP_TASKGROUP_CLAUSE_MASK				\
19315 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)	\
19316 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
19317 
19318 static tree
c_parser_omp_taskgroup(location_t loc,c_parser * parser,bool * if_p)19319 c_parser_omp_taskgroup (location_t loc, c_parser *parser, bool *if_p)
19320 {
19321   tree clauses = c_parser_omp_all_clauses (parser, OMP_TASKGROUP_CLAUSE_MASK,
19322 					   "#pragma omp taskgroup");
19323 
19324   tree body = c_parser_omp_structured_block (parser, if_p);
19325   return c_finish_omp_taskgroup (loc, body, clauses);
19326 }
19327 
19328 /* OpenMP 4.0:
19329    # pragma omp cancel cancel-clause[optseq] new-line
19330 
19331    LOC is the location of the #pragma.
19332 */
19333 
19334 #define OMP_CANCEL_CLAUSE_MASK					\
19335 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL)	\
19336 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR)		\
19337 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS)	\
19338 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP)	\
19339 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
19340 
19341 static void
c_parser_omp_cancel(c_parser * parser)19342 c_parser_omp_cancel (c_parser *parser)
19343 {
19344   location_t loc = c_parser_peek_token (parser)->location;
19345 
19346   c_parser_consume_pragma (parser);
19347   tree clauses = c_parser_omp_all_clauses (parser, OMP_CANCEL_CLAUSE_MASK,
19348 					   "#pragma omp cancel");
19349 
19350   c_finish_omp_cancel (loc, clauses);
19351 }
19352 
19353 /* OpenMP 4.0:
19354    # pragma omp cancellation point cancelpt-clause[optseq] new-line
19355 
19356    LOC is the location of the #pragma.
19357 */
19358 
19359 #define OMP_CANCELLATION_POINT_CLAUSE_MASK			\
19360 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL)	\
19361 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR)		\
19362 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS)	\
19363 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
19364 
19365 static void
c_parser_omp_cancellation_point(c_parser * parser,enum pragma_context context)19366 c_parser_omp_cancellation_point (c_parser *parser, enum pragma_context context)
19367 {
19368   location_t loc = c_parser_peek_token (parser)->location;
19369   tree clauses;
19370   bool point_seen = false;
19371 
19372   c_parser_consume_pragma (parser);
19373   if (c_parser_next_token_is (parser, CPP_NAME))
19374     {
19375       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19376       if (strcmp (p, "point") == 0)
19377 	{
19378 	  c_parser_consume_token (parser);
19379 	  point_seen = true;
19380 	}
19381     }
19382   if (!point_seen)
19383     {
19384       c_parser_error (parser, "expected %<point%>");
19385       c_parser_skip_to_pragma_eol (parser);
19386       return;
19387     }
19388 
19389   if (context != pragma_compound)
19390     {
19391       if (context == pragma_stmt)
19392 	error_at (loc,
19393 		  "%<#pragma %s%> may only be used in compound statements",
19394 		  "omp cancellation point");
19395       else
19396 	c_parser_error (parser, "expected declaration specifiers");
19397       c_parser_skip_to_pragma_eol (parser, false);
19398       return;
19399     }
19400 
19401   clauses
19402     = c_parser_omp_all_clauses (parser, OMP_CANCELLATION_POINT_CLAUSE_MASK,
19403 				"#pragma omp cancellation point");
19404 
19405   c_finish_omp_cancellation_point (loc, clauses);
19406 }
19407 
19408 /* OpenMP 4.0:
19409    #pragma omp distribute distribute-clause[optseq] new-line
19410      for-loop  */
19411 
19412 #define OMP_DISTRIBUTE_CLAUSE_MASK				\
19413 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
19414 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
19415 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)	\
19416 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
19417 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)	\
19418 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE))
19419 
19420 static tree
c_parser_omp_distribute(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)19421 c_parser_omp_distribute (location_t loc, c_parser *parser,
19422 			 char *p_name, omp_clause_mask mask, tree *cclauses,
19423 			 bool *if_p)
19424 {
19425   tree clauses, block, ret;
19426 
19427   strcat (p_name, " distribute");
19428   mask |= OMP_DISTRIBUTE_CLAUSE_MASK;
19429 
19430   if (c_parser_next_token_is (parser, CPP_NAME))
19431     {
19432       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19433       bool simd = false;
19434       bool parallel = false;
19435 
19436       if (strcmp (p, "simd") == 0)
19437 	simd = true;
19438       else
19439 	parallel = strcmp (p, "parallel") == 0;
19440       if (parallel || simd)
19441 	{
19442 	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19443 	  if (cclauses == NULL)
19444 	    cclauses = cclauses_buf;
19445 	  c_parser_consume_token (parser);
19446 	  if (!flag_openmp)  /* flag_openmp_simd  */
19447 	    {
19448 	      if (simd)
19449 		return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
19450 					  if_p);
19451 	      else
19452 		return c_parser_omp_parallel (loc, parser, p_name, mask,
19453 					      cclauses, if_p);
19454 	    }
19455 	  block = c_begin_compound_stmt (true);
19456 	  if (simd)
19457 	    ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
19458 				     if_p);
19459 	  else
19460 	    ret = c_parser_omp_parallel (loc, parser, p_name, mask, cclauses,
19461 					 if_p);
19462 	  block = c_end_compound_stmt (loc, block, true);
19463 	  if (ret == NULL)
19464 	    return ret;
19465 	  ret = make_node (OMP_DISTRIBUTE);
19466 	  TREE_TYPE (ret) = void_type_node;
19467 	  OMP_FOR_BODY (ret) = block;
19468 	  OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
19469 	  SET_EXPR_LOCATION (ret, loc);
19470 	  add_stmt (ret);
19471 	  return ret;
19472 	}
19473     }
19474   if (!flag_openmp)  /* flag_openmp_simd  */
19475     {
19476       c_parser_skip_to_pragma_eol (parser, false);
19477       return NULL_TREE;
19478     }
19479 
19480   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19481   if (cclauses)
19482     {
19483       omp_split_clauses (loc, OMP_DISTRIBUTE, mask, clauses, cclauses);
19484       clauses = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
19485     }
19486 
19487   block = c_begin_compound_stmt (true);
19488   ret = c_parser_omp_for_loop (loc, parser, OMP_DISTRIBUTE, clauses, NULL,
19489 			       if_p);
19490   block = c_end_compound_stmt (loc, block, true);
19491   add_stmt (block);
19492 
19493   return ret;
19494 }
19495 
19496 /* OpenMP 4.0:
19497    # pragma omp teams teams-clause[optseq] new-line
19498      structured-block  */
19499 
19500 #define OMP_TEAMS_CLAUSE_MASK					\
19501 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
19502 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
19503 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED)	\
19504 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)	\
19505 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS)	\
19506 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT)	\
19507 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)	\
19508 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
19509 
19510 static tree
c_parser_omp_teams(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)19511 c_parser_omp_teams (location_t loc, c_parser *parser,
19512 		    char *p_name, omp_clause_mask mask, tree *cclauses,
19513 		    bool *if_p)
19514 {
19515   tree clauses, block, ret;
19516 
19517   strcat (p_name, " teams");
19518   mask |= OMP_TEAMS_CLAUSE_MASK;
19519 
19520   if (c_parser_next_token_is (parser, CPP_NAME))
19521     {
19522       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19523       if (strcmp (p, "distribute") == 0)
19524 	{
19525 	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19526 	  if (cclauses == NULL)
19527 	    cclauses = cclauses_buf;
19528 
19529 	  c_parser_consume_token (parser);
19530 	  if (!flag_openmp)  /* flag_openmp_simd  */
19531 	    return c_parser_omp_distribute (loc, parser, p_name, mask,
19532 					    cclauses, if_p);
19533 	  block = c_begin_omp_parallel ();
19534 	  ret = c_parser_omp_distribute (loc, parser, p_name, mask, cclauses,
19535 					 if_p);
19536 	  block = c_end_compound_stmt (loc, block, true);
19537 	  if (ret == NULL)
19538 	    return ret;
19539 	  clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
19540 	  ret = make_node (OMP_TEAMS);
19541 	  TREE_TYPE (ret) = void_type_node;
19542 	  OMP_TEAMS_CLAUSES (ret) = clauses;
19543 	  OMP_TEAMS_BODY (ret) = block;
19544 	  OMP_TEAMS_COMBINED (ret) = 1;
19545 	  SET_EXPR_LOCATION (ret, loc);
19546 	  return add_stmt (ret);
19547 	}
19548       else if (strcmp (p, "loop") == 0)
19549 	{
19550 	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19551 	  if (cclauses == NULL)
19552 	    cclauses = cclauses_buf;
19553 
19554 	  c_parser_consume_token (parser);
19555 	  if (!flag_openmp)  /* flag_openmp_simd  */
19556 	    return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
19557 				      if_p);
19558 	  block = c_begin_omp_parallel ();
19559 	  ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses, if_p);
19560 	  block = c_end_compound_stmt (loc, block, true);
19561 	  if (ret == NULL)
19562 	    return ret;
19563 	  clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
19564 	  ret = make_node (OMP_TEAMS);
19565 	  TREE_TYPE (ret) = void_type_node;
19566 	  OMP_TEAMS_CLAUSES (ret) = clauses;
19567 	  OMP_TEAMS_BODY (ret) = block;
19568 	  OMP_TEAMS_COMBINED (ret) = 1;
19569 	  SET_EXPR_LOCATION (ret, loc);
19570 	  return add_stmt (ret);
19571 	}
19572     }
19573   if (!flag_openmp)  /* flag_openmp_simd  */
19574     {
19575       c_parser_skip_to_pragma_eol (parser, false);
19576       return NULL_TREE;
19577     }
19578 
19579   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19580   if (cclauses)
19581     {
19582       omp_split_clauses (loc, OMP_TEAMS, mask, clauses, cclauses);
19583       clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
19584     }
19585 
19586   tree stmt = make_node (OMP_TEAMS);
19587   TREE_TYPE (stmt) = void_type_node;
19588   OMP_TEAMS_CLAUSES (stmt) = clauses;
19589   block = c_begin_omp_parallel ();
19590   add_stmt (c_parser_omp_structured_block (parser, if_p));
19591   OMP_TEAMS_BODY (stmt) = c_end_compound_stmt (loc, block, true);
19592   SET_EXPR_LOCATION (stmt, loc);
19593 
19594   return add_stmt (stmt);
19595 }
19596 
19597 /* OpenMP 4.0:
19598    # pragma omp target data target-data-clause[optseq] new-line
19599      structured-block  */
19600 
19601 #define OMP_TARGET_DATA_CLAUSE_MASK				\
19602 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE)	\
19603 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)		\
19604 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
19605 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
19606 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
19607 
19608 static tree
c_parser_omp_target_data(location_t loc,c_parser * parser,bool * if_p)19609 c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p)
19610 {
19611   tree clauses
19612     = c_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
19613 				"#pragma omp target data");
19614   c_omp_adjust_map_clauses (clauses, false);
19615   int map_seen = 0;
19616   for (tree *pc = &clauses; *pc;)
19617     {
19618       if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
19619 	switch (OMP_CLAUSE_MAP_KIND (*pc))
19620 	  {
19621 	  case GOMP_MAP_TO:
19622 	  case GOMP_MAP_ALWAYS_TO:
19623 	  case GOMP_MAP_FROM:
19624 	  case GOMP_MAP_ALWAYS_FROM:
19625 	  case GOMP_MAP_TOFROM:
19626 	  case GOMP_MAP_ALWAYS_TOFROM:
19627 	  case GOMP_MAP_ALLOC:
19628 	    map_seen = 3;
19629 	    break;
19630 	  case GOMP_MAP_FIRSTPRIVATE_POINTER:
19631 	  case GOMP_MAP_ALWAYS_POINTER:
19632 	  case GOMP_MAP_ATTACH_DETACH:
19633 	    break;
19634 	  default:
19635 	    map_seen |= 1;
19636 	    error_at (OMP_CLAUSE_LOCATION (*pc),
19637 		      "%<#pragma omp target data%> with map-type other "
19638 		      "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
19639 		      "on %<map%> clause");
19640 	    *pc = OMP_CLAUSE_CHAIN (*pc);
19641 	    continue;
19642 	  }
19643       else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
19644 	       || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
19645 	map_seen = 3;
19646       pc = &OMP_CLAUSE_CHAIN (*pc);
19647     }
19648 
19649   if (map_seen != 3)
19650     {
19651       if (map_seen == 0)
19652 	error_at (loc,
19653 		  "%<#pragma omp target data%> must contain at least "
19654 		  "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
19655 		  "clause");
19656       return NULL_TREE;
19657     }
19658 
19659   tree stmt = make_node (OMP_TARGET_DATA);
19660   TREE_TYPE (stmt) = void_type_node;
19661   OMP_TARGET_DATA_CLAUSES (stmt) = clauses;
19662   keep_next_level ();
19663   tree block = c_begin_compound_stmt (true);
19664   add_stmt (c_parser_omp_structured_block (parser, if_p));
19665   OMP_TARGET_DATA_BODY (stmt) = c_end_compound_stmt (loc, block, true);
19666 
19667   SET_EXPR_LOCATION (stmt, loc);
19668   return add_stmt (stmt);
19669 }
19670 
19671 /* OpenMP 4.0:
19672    # pragma omp target update target-update-clause[optseq] new-line */
19673 
19674 #define OMP_TARGET_UPDATE_CLAUSE_MASK				\
19675 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM)		\
19676 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO)		\
19677 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE)	\
19678 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
19679 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)	\
19680 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19681 
19682 static bool
c_parser_omp_target_update(location_t loc,c_parser * parser,enum pragma_context context)19683 c_parser_omp_target_update (location_t loc, c_parser *parser,
19684 			    enum pragma_context context)
19685 {
19686   if (context == pragma_stmt)
19687     {
19688       error_at (loc, "%<#pragma %s%> may only be used in compound statements",
19689 		"omp target update");
19690       c_parser_skip_to_pragma_eol (parser, false);
19691       return false;
19692     }
19693 
19694   tree clauses
19695     = c_parser_omp_all_clauses (parser, OMP_TARGET_UPDATE_CLAUSE_MASK,
19696 				"#pragma omp target update");
19697   if (omp_find_clause (clauses, OMP_CLAUSE_TO) == NULL_TREE
19698       && omp_find_clause (clauses, OMP_CLAUSE_FROM) == NULL_TREE)
19699     {
19700       error_at (loc,
19701 		"%<#pragma omp target update%> must contain at least one "
19702 		"%<from%> or %<to%> clauses");
19703       return false;
19704     }
19705 
19706   tree stmt = make_node (OMP_TARGET_UPDATE);
19707   TREE_TYPE (stmt) = void_type_node;
19708   OMP_TARGET_UPDATE_CLAUSES (stmt) = clauses;
19709   SET_EXPR_LOCATION (stmt, loc);
19710   add_stmt (stmt);
19711   return false;
19712 }
19713 
19714 /* OpenMP 4.5:
19715    # pragma omp target enter data target-data-clause[optseq] new-line  */
19716 
19717 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK			\
19718 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE)	\
19719 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)		\
19720 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
19721 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)	\
19722 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19723 
19724 static tree
c_parser_omp_target_enter_data(location_t loc,c_parser * parser,enum pragma_context context)19725 c_parser_omp_target_enter_data (location_t loc, c_parser *parser,
19726 				enum pragma_context context)
19727 {
19728   bool data_seen = false;
19729   if (c_parser_next_token_is (parser, CPP_NAME))
19730     {
19731       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19732       if (strcmp (p, "data") == 0)
19733 	{
19734 	  c_parser_consume_token (parser);
19735 	  data_seen = true;
19736 	}
19737     }
19738   if (!data_seen)
19739     {
19740       c_parser_error (parser, "expected %<data%>");
19741       c_parser_skip_to_pragma_eol (parser);
19742       return NULL_TREE;
19743     }
19744 
19745   if (context == pragma_stmt)
19746     {
19747       error_at (loc, "%<#pragma %s%> may only be used in compound statements",
19748 		"omp target enter data");
19749       c_parser_skip_to_pragma_eol (parser, false);
19750       return NULL_TREE;
19751     }
19752 
19753   tree clauses
19754     = c_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK,
19755 				"#pragma omp target enter data");
19756   c_omp_adjust_map_clauses (clauses, false);
19757   int map_seen = 0;
19758   for (tree *pc = &clauses; *pc;)
19759     {
19760       if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
19761 	switch (OMP_CLAUSE_MAP_KIND (*pc))
19762 	  {
19763 	  case GOMP_MAP_TO:
19764 	  case GOMP_MAP_ALWAYS_TO:
19765 	  case GOMP_MAP_ALLOC:
19766 	    map_seen = 3;
19767 	    break;
19768 	  case GOMP_MAP_FIRSTPRIVATE_POINTER:
19769 	  case GOMP_MAP_ALWAYS_POINTER:
19770 	  case GOMP_MAP_ATTACH_DETACH:
19771 	    break;
19772 	  default:
19773 	    map_seen |= 1;
19774 	    error_at (OMP_CLAUSE_LOCATION (*pc),
19775 		      "%<#pragma omp target enter data%> with map-type other "
19776 		      "than %<to%> or %<alloc%> on %<map%> clause");
19777 	    *pc = OMP_CLAUSE_CHAIN (*pc);
19778 	    continue;
19779 	  }
19780       pc = &OMP_CLAUSE_CHAIN (*pc);
19781     }
19782 
19783   if (map_seen != 3)
19784     {
19785       if (map_seen == 0)
19786 	error_at (loc,
19787 		  "%<#pragma omp target enter data%> must contain at least "
19788 		  "one %<map%> clause");
19789       return NULL_TREE;
19790     }
19791 
19792   tree stmt = make_node (OMP_TARGET_ENTER_DATA);
19793   TREE_TYPE (stmt) = void_type_node;
19794   OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses;
19795   SET_EXPR_LOCATION (stmt, loc);
19796   add_stmt (stmt);
19797   return stmt;
19798 }
19799 
19800 /* OpenMP 4.5:
19801    # pragma omp target exit data target-data-clause[optseq] new-line  */
19802 
19803 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK			\
19804 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE)	\
19805 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)		\
19806 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
19807 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)	\
19808 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
19809 
19810 static tree
c_parser_omp_target_exit_data(location_t loc,c_parser * parser,enum pragma_context context)19811 c_parser_omp_target_exit_data (location_t loc, c_parser *parser,
19812 			       enum pragma_context context)
19813 {
19814   bool data_seen = false;
19815   if (c_parser_next_token_is (parser, CPP_NAME))
19816     {
19817       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19818       if (strcmp (p, "data") == 0)
19819 	{
19820 	  c_parser_consume_token (parser);
19821 	  data_seen = true;
19822 	}
19823     }
19824   if (!data_seen)
19825     {
19826       c_parser_error (parser, "expected %<data%>");
19827       c_parser_skip_to_pragma_eol (parser);
19828       return NULL_TREE;
19829     }
19830 
19831   if (context == pragma_stmt)
19832     {
19833       error_at (loc, "%<#pragma %s%> may only be used in compound statements",
19834 		"omp target exit data");
19835       c_parser_skip_to_pragma_eol (parser, false);
19836       return NULL_TREE;
19837     }
19838 
19839   tree clauses
19840     = c_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK,
19841 				"#pragma omp target exit data");
19842   c_omp_adjust_map_clauses (clauses, false);
19843   int map_seen = 0;
19844   for (tree *pc = &clauses; *pc;)
19845     {
19846       if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
19847 	switch (OMP_CLAUSE_MAP_KIND (*pc))
19848 	  {
19849 	  case GOMP_MAP_FROM:
19850 	  case GOMP_MAP_ALWAYS_FROM:
19851 	  case GOMP_MAP_RELEASE:
19852 	  case GOMP_MAP_DELETE:
19853 	    map_seen = 3;
19854 	    break;
19855 	  case GOMP_MAP_FIRSTPRIVATE_POINTER:
19856 	  case GOMP_MAP_ALWAYS_POINTER:
19857 	  case GOMP_MAP_ATTACH_DETACH:
19858 	    break;
19859 	  default:
19860 	    map_seen |= 1;
19861 	    error_at (OMP_CLAUSE_LOCATION (*pc),
19862 		      "%<#pragma omp target exit data%> with map-type other "
19863 		      "than %<from%>, %<release%> or %<delete%> on %<map%>"
19864 		      " clause");
19865 	    *pc = OMP_CLAUSE_CHAIN (*pc);
19866 	    continue;
19867 	  }
19868       pc = &OMP_CLAUSE_CHAIN (*pc);
19869     }
19870 
19871   if (map_seen != 3)
19872     {
19873       if (map_seen == 0)
19874 	error_at (loc,
19875 		  "%<#pragma omp target exit data%> must contain at least one "
19876 		  "%<map%> clause");
19877       return NULL_TREE;
19878     }
19879 
19880   tree stmt = make_node (OMP_TARGET_EXIT_DATA);
19881   TREE_TYPE (stmt) = void_type_node;
19882   OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses;
19883   SET_EXPR_LOCATION (stmt, loc);
19884   add_stmt (stmt);
19885   return stmt;
19886 }
19887 
19888 /* OpenMP 4.0:
19889    # pragma omp target target-clause[optseq] new-line
19890      structured-block  */
19891 
19892 #define OMP_TARGET_CLAUSE_MASK					\
19893 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE)	\
19894 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)		\
19895 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
19896 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)	\
19897 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT)	\
19898 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
19899 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
19900 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)	\
19901 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP)	\
19902 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR))
19903 
19904 static bool
c_parser_omp_target(c_parser * parser,enum pragma_context context,bool * if_p)19905 c_parser_omp_target (c_parser *parser, enum pragma_context context, bool *if_p)
19906 {
19907   location_t loc = c_parser_peek_token (parser)->location;
19908   c_parser_consume_pragma (parser);
19909   tree *pc = NULL, stmt, block;
19910 
19911   if (context != pragma_stmt && context != pragma_compound)
19912     {
19913       c_parser_error (parser, "expected declaration specifiers");
19914       c_parser_skip_to_pragma_eol (parser);
19915       return false;
19916     }
19917 
19918   if (flag_openmp)
19919     omp_requires_mask
19920       = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
19921 
19922   if (c_parser_next_token_is (parser, CPP_NAME))
19923     {
19924       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19925       enum tree_code ccode = ERROR_MARK;
19926 
19927       if (strcmp (p, "teams") == 0)
19928 	ccode = OMP_TEAMS;
19929       else if (strcmp (p, "parallel") == 0)
19930 	ccode = OMP_PARALLEL;
19931       else if (strcmp (p, "simd") == 0)
19932 	ccode = OMP_SIMD;
19933       if (ccode != ERROR_MARK)
19934 	{
19935 	  tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT];
19936 	  char p_name[sizeof ("#pragma omp target teams distribute "
19937 			      "parallel for simd")];
19938 
19939 	  c_parser_consume_token (parser);
19940 	  strcpy (p_name, "#pragma omp target");
19941 	  if (!flag_openmp)  /* flag_openmp_simd  */
19942 	    {
19943 	      tree stmt;
19944 	      switch (ccode)
19945 		{
19946 		case OMP_TEAMS:
19947 		  stmt = c_parser_omp_teams (loc, parser, p_name,
19948 					     OMP_TARGET_CLAUSE_MASK,
19949 					     cclauses, if_p);
19950 		  break;
19951 		case OMP_PARALLEL:
19952 		  stmt = c_parser_omp_parallel (loc, parser, p_name,
19953 						OMP_TARGET_CLAUSE_MASK,
19954 						cclauses, if_p);
19955 		  break;
19956 		case OMP_SIMD:
19957 		  stmt = c_parser_omp_simd (loc, parser, p_name,
19958 					    OMP_TARGET_CLAUSE_MASK,
19959 					    cclauses, if_p);
19960 		  break;
19961 		default:
19962 		  gcc_unreachable ();
19963 		}
19964 	      return stmt != NULL_TREE;
19965 	    }
19966 	  keep_next_level ();
19967 	  tree block = c_begin_compound_stmt (true), ret;
19968 	  switch (ccode)
19969 	    {
19970 	    case OMP_TEAMS:
19971 	      ret = c_parser_omp_teams (loc, parser, p_name,
19972 					OMP_TARGET_CLAUSE_MASK, cclauses,
19973 					if_p);
19974 	      break;
19975 	    case OMP_PARALLEL:
19976 	      ret = c_parser_omp_parallel (loc, parser, p_name,
19977 					   OMP_TARGET_CLAUSE_MASK, cclauses,
19978 					   if_p);
19979 	      break;
19980 	    case OMP_SIMD:
19981 	      ret = c_parser_omp_simd (loc, parser, p_name,
19982 				       OMP_TARGET_CLAUSE_MASK, cclauses,
19983 				       if_p);
19984 	      break;
19985 	    default:
19986 	      gcc_unreachable ();
19987 	    }
19988 	  block = c_end_compound_stmt (loc, block, true);
19989 	  if (ret == NULL_TREE)
19990 	    return false;
19991 	  if (ccode == OMP_TEAMS)
19992 	    {
19993 	      /* For combined target teams, ensure the num_teams and
19994 		 thread_limit clause expressions are evaluated on the host,
19995 		 before entering the target construct.  */
19996 	      tree c;
19997 	      for (c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
19998 		   c; c = OMP_CLAUSE_CHAIN (c))
19999 		if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
20000 		     || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
20001 		    && TREE_CODE (OMP_CLAUSE_OPERAND (c, 0)) != INTEGER_CST)
20002 		  {
20003 		    tree expr = OMP_CLAUSE_OPERAND (c, 0);
20004 		    tree tmp = create_tmp_var_raw (TREE_TYPE (expr));
20005 		    expr = build4 (TARGET_EXPR, TREE_TYPE (expr), tmp,
20006 				   expr, NULL_TREE, NULL_TREE);
20007 		    add_stmt (expr);
20008 		    OMP_CLAUSE_OPERAND (c, 0) = expr;
20009 		    tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
20010 						OMP_CLAUSE_FIRSTPRIVATE);
20011 		    OMP_CLAUSE_DECL (tc) = tmp;
20012 		    OMP_CLAUSE_CHAIN (tc)
20013 		      = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
20014 		    cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc;
20015 		  }
20016 	    }
20017 	  tree stmt = make_node (OMP_TARGET);
20018 	  TREE_TYPE (stmt) = void_type_node;
20019 	  OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
20020 	  c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
20021 	  OMP_TARGET_BODY (stmt) = block;
20022 	  OMP_TARGET_COMBINED (stmt) = 1;
20023 	  SET_EXPR_LOCATION (stmt, loc);
20024 	  add_stmt (stmt);
20025 	  pc = &OMP_TARGET_CLAUSES (stmt);
20026 	  goto check_clauses;
20027 	}
20028       else if (!flag_openmp)  /* flag_openmp_simd  */
20029 	{
20030 	  c_parser_skip_to_pragma_eol (parser, false);
20031 	  return false;
20032 	}
20033       else if (strcmp (p, "data") == 0)
20034 	{
20035 	  c_parser_consume_token (parser);
20036 	  c_parser_omp_target_data (loc, parser, if_p);
20037 	  return true;
20038 	}
20039       else if (strcmp (p, "enter") == 0)
20040 	{
20041 	  c_parser_consume_token (parser);
20042 	  c_parser_omp_target_enter_data (loc, parser, context);
20043 	  return false;
20044 	}
20045       else if (strcmp (p, "exit") == 0)
20046 	{
20047 	  c_parser_consume_token (parser);
20048 	  c_parser_omp_target_exit_data (loc, parser, context);
20049 	  return false;
20050 	}
20051       else if (strcmp (p, "update") == 0)
20052 	{
20053 	  c_parser_consume_token (parser);
20054 	  return c_parser_omp_target_update (loc, parser, context);
20055 	}
20056     }
20057   if (!flag_openmp) /* flag_openmp_simd  */
20058     {
20059       c_parser_skip_to_pragma_eol (parser, false);
20060       return false;
20061     }
20062 
20063   stmt = make_node (OMP_TARGET);
20064   TREE_TYPE (stmt) = void_type_node;
20065 
20066   OMP_TARGET_CLAUSES (stmt)
20067     = c_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK,
20068 				"#pragma omp target");
20069   c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
20070 
20071   pc = &OMP_TARGET_CLAUSES (stmt);
20072   keep_next_level ();
20073   block = c_begin_compound_stmt (true);
20074   add_stmt (c_parser_omp_structured_block (parser, if_p));
20075   OMP_TARGET_BODY (stmt) = c_end_compound_stmt (loc, block, true);
20076 
20077   SET_EXPR_LOCATION (stmt, loc);
20078   add_stmt (stmt);
20079 
20080 check_clauses:
20081   while (*pc)
20082     {
20083       if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
20084 	switch (OMP_CLAUSE_MAP_KIND (*pc))
20085 	  {
20086 	  case GOMP_MAP_TO:
20087 	  case GOMP_MAP_ALWAYS_TO:
20088 	  case GOMP_MAP_FROM:
20089 	  case GOMP_MAP_ALWAYS_FROM:
20090 	  case GOMP_MAP_TOFROM:
20091 	  case GOMP_MAP_ALWAYS_TOFROM:
20092 	  case GOMP_MAP_ALLOC:
20093 	  case GOMP_MAP_FIRSTPRIVATE_POINTER:
20094 	  case GOMP_MAP_ALWAYS_POINTER:
20095 	  case GOMP_MAP_ATTACH_DETACH:
20096 	    break;
20097 	  default:
20098 	    error_at (OMP_CLAUSE_LOCATION (*pc),
20099 		      "%<#pragma omp target%> with map-type other "
20100 		      "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
20101 		      "on %<map%> clause");
20102 	    *pc = OMP_CLAUSE_CHAIN (*pc);
20103 	    continue;
20104 	  }
20105       pc = &OMP_CLAUSE_CHAIN (*pc);
20106     }
20107   cfun->has_omp_target = true;
20108   return true;
20109 }
20110 
20111 /* OpenMP 4.0:
20112    # pragma omp declare simd declare-simd-clauses[optseq] new-line
20113 
20114    OpenMP 5.0:
20115    # pragma omp declare variant (identifier) match(context-selector) new-line
20116    */
20117 
20118 #define OMP_DECLARE_SIMD_CLAUSE_MASK				\
20119 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN)	\
20120 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR)	\
20121 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED)	\
20122 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)	\
20123 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH)	\
20124 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
20125 
20126 static void
c_parser_omp_declare_simd(c_parser * parser,enum pragma_context context)20127 c_parser_omp_declare_simd (c_parser *parser, enum pragma_context context)
20128 {
20129   c_token *token = c_parser_peek_token (parser);
20130   gcc_assert (token->type == CPP_NAME);
20131   tree kind = token->value;
20132   gcc_assert (strcmp (IDENTIFIER_POINTER (kind), "simd") == 0
20133 	      || strcmp (IDENTIFIER_POINTER (kind), "variant") == 0);
20134 
20135   auto_vec<c_token> clauses;
20136   while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
20137     {
20138       c_token *token = c_parser_peek_token (parser);
20139       if (token->type == CPP_EOF)
20140 	{
20141 	  c_parser_skip_to_pragma_eol (parser);
20142 	  return;
20143 	}
20144       clauses.safe_push (*token);
20145       c_parser_consume_token (parser);
20146     }
20147   clauses.safe_push (*c_parser_peek_token (parser));
20148   c_parser_skip_to_pragma_eol (parser);
20149 
20150   while (c_parser_next_token_is (parser, CPP_PRAGMA))
20151     {
20152       if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_DECLARE
20153 	  || c_parser_peek_2nd_token (parser)->type != CPP_NAME
20154 	  || c_parser_peek_2nd_token (parser)->value != kind)
20155 	{
20156 	  error ("%<#pragma omp declare %s%> must be followed by "
20157 		 "function declaration or definition or another "
20158 		 "%<#pragma omp declare %s%>",
20159 		 IDENTIFIER_POINTER (kind), IDENTIFIER_POINTER (kind));
20160 	  return;
20161 	}
20162       c_parser_consume_pragma (parser);
20163       while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
20164 	{
20165 	  c_token *token = c_parser_peek_token (parser);
20166 	  if (token->type == CPP_EOF)
20167 	    {
20168 	      c_parser_skip_to_pragma_eol (parser);
20169 	      return;
20170 	    }
20171 	  clauses.safe_push (*token);
20172 	  c_parser_consume_token (parser);
20173 	}
20174       clauses.safe_push (*c_parser_peek_token (parser));
20175       c_parser_skip_to_pragma_eol (parser);
20176     }
20177 
20178   /* Make sure nothing tries to read past the end of the tokens.  */
20179   c_token eof_token;
20180   memset (&eof_token, 0, sizeof (eof_token));
20181   eof_token.type = CPP_EOF;
20182   clauses.safe_push (eof_token);
20183   clauses.safe_push (eof_token);
20184 
20185   switch (context)
20186     {
20187     case pragma_external:
20188       if (c_parser_next_token_is (parser, CPP_KEYWORD)
20189 	  && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
20190 	{
20191 	  int ext = disable_extension_diagnostics ();
20192 	  do
20193 	    c_parser_consume_token (parser);
20194 	  while (c_parser_next_token_is (parser, CPP_KEYWORD)
20195 		 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
20196 	  c_parser_declaration_or_fndef (parser, true, true, true, false, true,
20197 					 NULL, clauses);
20198 	  restore_extension_diagnostics (ext);
20199 	}
20200       else
20201 	c_parser_declaration_or_fndef (parser, true, true, true, false, true,
20202 				       NULL, clauses);
20203       break;
20204     case pragma_struct:
20205     case pragma_param:
20206     case pragma_stmt:
20207       error ("%<#pragma omp declare %s%> must be followed by "
20208 	     "function declaration or definition",
20209 	     IDENTIFIER_POINTER (kind));
20210       break;
20211     case pragma_compound:
20212       if (c_parser_next_token_is (parser, CPP_KEYWORD)
20213 	  && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
20214 	{
20215 	  int ext = disable_extension_diagnostics ();
20216 	  do
20217 	    c_parser_consume_token (parser);
20218 	  while (c_parser_next_token_is (parser, CPP_KEYWORD)
20219 		 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
20220 	  if (c_parser_next_tokens_start_declaration (parser))
20221 	    {
20222 	      c_parser_declaration_or_fndef (parser, true, true, true, true,
20223 					     true, NULL, clauses);
20224 	      restore_extension_diagnostics (ext);
20225 	      break;
20226 	    }
20227 	  restore_extension_diagnostics (ext);
20228 	}
20229       else if (c_parser_next_tokens_start_declaration (parser))
20230 	{
20231 	  c_parser_declaration_or_fndef (parser, true, true, true, true, true,
20232 					 NULL, clauses);
20233 	  break;
20234 	}
20235       error ("%<#pragma omp declare %s%> must be followed by "
20236 	     "function declaration or definition",
20237 	     IDENTIFIER_POINTER (kind));
20238       break;
20239     default:
20240       gcc_unreachable ();
20241     }
20242 }
20243 
20244 static const char *const omp_construct_selectors[] = {
20245   "simd", "target", "teams", "parallel", "for", NULL };
20246 static const char *const omp_device_selectors[] = {
20247   "kind", "isa", "arch", NULL };
20248 static const char *const omp_implementation_selectors[] = {
20249   "vendor", "extension", "atomic_default_mem_order", "unified_address",
20250   "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL };
20251 static const char *const omp_user_selectors[] = {
20252   "condition", NULL };
20253 
20254 /* OpenMP 5.0:
20255 
20256    trait-selector:
20257      trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
20258 
20259    trait-score:
20260      score(score-expression)  */
20261 
20262 static tree
c_parser_omp_context_selector(c_parser * parser,tree set,tree parms)20263 c_parser_omp_context_selector (c_parser *parser, tree set, tree parms)
20264 {
20265   tree ret = NULL_TREE;
20266   do
20267     {
20268       tree selector;
20269       if (c_parser_next_token_is (parser, CPP_KEYWORD)
20270 	  || c_parser_next_token_is (parser, CPP_NAME))
20271 	selector = c_parser_peek_token (parser)->value;
20272       else
20273 	{
20274 	  c_parser_error (parser, "expected trait selector name");
20275 	  return error_mark_node;
20276 	}
20277 
20278       tree properties = NULL_TREE;
20279       const char *const *selectors = NULL;
20280       bool allow_score = true;
20281       bool allow_user = false;
20282       int property_limit = 0;
20283       enum { CTX_PROPERTY_NONE, CTX_PROPERTY_USER, CTX_PROPERTY_NAME_LIST,
20284 	     CTX_PROPERTY_ID, CTX_PROPERTY_EXPR,
20285 	     CTX_PROPERTY_SIMD } property_kind = CTX_PROPERTY_NONE;
20286       switch (IDENTIFIER_POINTER (set)[0])
20287 	{
20288 	case 'c': /* construct */
20289 	  selectors = omp_construct_selectors;
20290 	  allow_score = false;
20291 	  property_limit = 1;
20292 	  property_kind = CTX_PROPERTY_SIMD;
20293 	  break;
20294 	case 'd': /* device */
20295 	  selectors = omp_device_selectors;
20296 	  allow_score = false;
20297 	  allow_user = true;
20298 	  property_limit = 3;
20299 	  property_kind = CTX_PROPERTY_NAME_LIST;
20300 	  break;
20301 	case 'i': /* implementation */
20302 	  selectors = omp_implementation_selectors;
20303 	  allow_user = true;
20304 	  property_limit = 3;
20305 	  property_kind = CTX_PROPERTY_NAME_LIST;
20306 	  break;
20307 	case 'u': /* user */
20308 	  selectors = omp_user_selectors;
20309 	  property_limit = 1;
20310 	  property_kind = CTX_PROPERTY_EXPR;
20311 	  break;
20312 	default:
20313 	  gcc_unreachable ();
20314 	}
20315       for (int i = 0; ; i++)
20316 	{
20317 	  if (selectors[i] == NULL)
20318 	    {
20319 	      if (allow_user)
20320 		{
20321 		  property_kind = CTX_PROPERTY_USER;
20322 		  break;
20323 		}
20324 	      else
20325 		{
20326 		  error_at (c_parser_peek_token (parser)->location,
20327 			    "selector %qs not allowed for context selector "
20328 			    "set %qs", IDENTIFIER_POINTER (selector),
20329 			    IDENTIFIER_POINTER (set));
20330 		  c_parser_consume_token (parser);
20331 		  return error_mark_node;
20332 		}
20333 	    }
20334 	  if (i == property_limit)
20335 	    property_kind = CTX_PROPERTY_NONE;
20336 	  if (strcmp (selectors[i], IDENTIFIER_POINTER (selector)) == 0)
20337 	    break;
20338 	}
20339       if (property_kind == CTX_PROPERTY_NAME_LIST
20340 	  && IDENTIFIER_POINTER (set)[0] == 'i'
20341 	  && strcmp (IDENTIFIER_POINTER (selector),
20342 		     "atomic_default_mem_order") == 0)
20343 	property_kind = CTX_PROPERTY_ID;
20344 
20345       c_parser_consume_token (parser);
20346 
20347       if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
20348 	{
20349 	  if (property_kind == CTX_PROPERTY_NONE)
20350 	    {
20351 	      error_at (c_parser_peek_token (parser)->location,
20352 			"selector %qs does not accept any properties",
20353 			IDENTIFIER_POINTER (selector));
20354 	      return error_mark_node;
20355 	    }
20356 
20357 	  matching_parens parens;
20358 	  parens.require_open (parser);
20359 
20360 	  c_token *token = c_parser_peek_token (parser);
20361 	  if (allow_score
20362 	      && c_parser_next_token_is (parser, CPP_NAME)
20363 	      && strcmp (IDENTIFIER_POINTER (token->value), "score") == 0
20364 	      && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
20365 	    {
20366 	      c_parser_consume_token (parser);
20367 
20368 	      matching_parens parens2;
20369 	      parens2.require_open (parser);
20370 	      tree score = c_parser_expr_no_commas (parser, NULL).value;
20371 	      parens2.skip_until_found_close (parser);
20372 	      c_parser_require (parser, CPP_COLON, "expected %<:%>");
20373 	      if (score != error_mark_node)
20374 		{
20375 		  mark_exp_read (score);
20376 		  score = c_fully_fold (score, false, NULL);
20377 		  if (!INTEGRAL_TYPE_P (TREE_TYPE (score))
20378 		      || TREE_CODE (score) != INTEGER_CST)
20379 		    error_at (token->location, "score argument must be "
20380 			      "constant integer expression");
20381 		  else if (tree_int_cst_sgn (score) < 0)
20382 		    error_at (token->location, "score argument must be "
20383 			      "non-negative");
20384 		  else
20385 		    properties = tree_cons (get_identifier (" score"),
20386 					    score, properties);
20387 		}
20388 	      token = c_parser_peek_token (parser);
20389 	    }
20390 
20391 	  switch (property_kind)
20392 	    {
20393 	      tree t;
20394 	    case CTX_PROPERTY_USER:
20395 	      do
20396 		{
20397 		  t = c_parser_expr_no_commas (parser, NULL).value;
20398 		  if (TREE_CODE (t) == STRING_CST)
20399 		    properties = tree_cons (NULL_TREE, t, properties);
20400 		  else if (t != error_mark_node)
20401 		    {
20402 		      mark_exp_read (t);
20403 		      t = c_fully_fold (t, false, NULL);
20404 		      if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
20405 			  || !tree_fits_shwi_p (t))
20406 			error_at (token->location, "property must be "
20407 				  "constant integer expression or string "
20408 				  "literal");
20409 		      else
20410 			properties = tree_cons (NULL_TREE, t, properties);
20411 		    }
20412 		  else
20413 		    return error_mark_node;
20414 
20415 		  if (c_parser_next_token_is (parser, CPP_COMMA))
20416 		    c_parser_consume_token (parser);
20417 		  else
20418 		    break;
20419 		}
20420 	      while (1);
20421 	      break;
20422 	    case CTX_PROPERTY_ID:
20423 	      if (c_parser_next_token_is (parser, CPP_KEYWORD)
20424 		  || c_parser_next_token_is (parser, CPP_NAME))
20425 		{
20426 		  tree prop = c_parser_peek_token (parser)->value;
20427 		  c_parser_consume_token (parser);
20428 		  properties = tree_cons (prop, NULL_TREE, properties);
20429 		}
20430 	      else
20431 		{
20432 		  c_parser_error (parser, "expected identifier");
20433 		  return error_mark_node;
20434 		}
20435 	      break;
20436 	    case CTX_PROPERTY_NAME_LIST:
20437 	      do
20438 		{
20439 		  tree prop = NULL_TREE, value = NULL_TREE;
20440 		  if (c_parser_next_token_is (parser, CPP_KEYWORD)
20441 		      || c_parser_next_token_is (parser, CPP_NAME))
20442 		    {
20443 		      prop = c_parser_peek_token (parser)->value;
20444 		      c_parser_consume_token (parser);
20445 		    }
20446 		  else if (c_parser_next_token_is (parser, CPP_STRING))
20447 		    value = c_parser_string_literal (parser, false,
20448 						     false).value;
20449 		  else
20450 		    {
20451 		      c_parser_error (parser, "expected identifier or "
20452 					      "string literal");
20453 		      return error_mark_node;
20454 		    }
20455 
20456 		  properties = tree_cons (prop, value, properties);
20457 
20458 		  if (c_parser_next_token_is (parser, CPP_COMMA))
20459 		    c_parser_consume_token (parser);
20460 		  else
20461 		    break;
20462 		}
20463 	      while (1);
20464 	      break;
20465 	    case CTX_PROPERTY_EXPR:
20466 	      t = c_parser_expr_no_commas (parser, NULL).value;
20467 	      if (t != error_mark_node)
20468 		{
20469 		  mark_exp_read (t);
20470 		  t = c_fully_fold (t, false, NULL);
20471 		  if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
20472 		      || !tree_fits_shwi_p (t))
20473 		    error_at (token->location, "property must be "
20474 			      "constant integer expression");
20475 		  else
20476 		    properties = tree_cons (NULL_TREE, t, properties);
20477 		}
20478 	      else
20479 		return error_mark_node;
20480 	      break;
20481 	    case CTX_PROPERTY_SIMD:
20482 	      if (parms == NULL_TREE)
20483 		{
20484 		  error_at (token->location, "properties for %<simd%> "
20485 			    "selector may not be specified in "
20486 			    "%<metadirective%>");
20487 		  return error_mark_node;
20488 		}
20489 	      tree c;
20490 	      c = c_parser_omp_all_clauses (parser,
20491 					    OMP_DECLARE_SIMD_CLAUSE_MASK,
20492 					    "simd", true, 2);
20493 	      c = c_omp_declare_simd_clauses_to_numbers (parms
20494 							 == error_mark_node
20495 							 ? NULL_TREE : parms,
20496 							 c);
20497 	      properties = c;
20498 	      break;
20499 	    default:
20500 	      gcc_unreachable ();
20501 	    }
20502 
20503 	  parens.skip_until_found_close (parser);
20504 	  properties = nreverse (properties);
20505 	}
20506       else if (property_kind == CTX_PROPERTY_NAME_LIST
20507 	       || property_kind == CTX_PROPERTY_ID
20508 	       || property_kind == CTX_PROPERTY_EXPR)
20509 	{
20510 	  c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>");
20511 	  return error_mark_node;
20512 	}
20513 
20514       ret = tree_cons (selector, properties, ret);
20515 
20516       if (c_parser_next_token_is (parser, CPP_COMMA))
20517 	c_parser_consume_token (parser);
20518       else
20519 	break;
20520     }
20521   while (1);
20522 
20523   return nreverse (ret);
20524 }
20525 
20526 /* OpenMP 5.0:
20527 
20528    trait-set-selector[,trait-set-selector[,...]]
20529 
20530    trait-set-selector:
20531      trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
20532 
20533    trait-set-selector-name:
20534      constructor
20535      device
20536      implementation
20537      user  */
20538 
20539 static tree
c_parser_omp_context_selector_specification(c_parser * parser,tree parms)20540 c_parser_omp_context_selector_specification (c_parser *parser, tree parms)
20541 {
20542   tree ret = NULL_TREE;
20543   do
20544     {
20545       const char *setp = "";
20546       if (c_parser_next_token_is (parser, CPP_NAME))
20547 	setp = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20548       switch (setp[0])
20549 	{
20550 	case 'c':
20551 	  if (strcmp (setp, "construct") == 0)
20552 	    setp = NULL;
20553 	  break;
20554 	case 'd':
20555 	  if (strcmp (setp, "device") == 0)
20556 	    setp = NULL;
20557 	  break;
20558 	case 'i':
20559 	  if (strcmp (setp, "implementation") == 0)
20560 	    setp = NULL;
20561 	  break;
20562 	case 'u':
20563 	  if (strcmp (setp, "user") == 0)
20564 	    setp = NULL;
20565 	  break;
20566 	default:
20567 	  break;
20568 	}
20569       if (setp)
20570 	{
20571 	  c_parser_error (parser, "expected %<construct%>, %<device%>, "
20572 				  "%<implementation%> or %<user%>");
20573 	  return error_mark_node;
20574 	}
20575 
20576       tree set = c_parser_peek_token (parser)->value;
20577       c_parser_consume_token (parser);
20578 
20579       if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
20580 	return error_mark_node;
20581 
20582       matching_braces braces;
20583       if (!braces.require_open (parser))
20584 	return error_mark_node;
20585 
20586       tree selectors = c_parser_omp_context_selector (parser, set, parms);
20587       if (selectors == error_mark_node)
20588 	ret = error_mark_node;
20589       else if (ret != error_mark_node)
20590 	ret = tree_cons (set, selectors, ret);
20591 
20592       braces.skip_until_found_close (parser);
20593 
20594       if (c_parser_next_token_is (parser, CPP_COMMA))
20595 	c_parser_consume_token (parser);
20596       else
20597 	break;
20598     }
20599   while (1);
20600 
20601   if (ret == error_mark_node)
20602     return ret;
20603   return nreverse (ret);
20604 }
20605 
20606 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
20607    that into "omp declare variant base" attribute.  */
20608 
20609 static void
c_finish_omp_declare_variant(c_parser * parser,tree fndecl,tree parms)20610 c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms)
20611 {
20612   matching_parens parens;
20613   if (!parens.require_open (parser))
20614     {
20615      fail:
20616       c_parser_skip_to_pragma_eol (parser, false);
20617       return;
20618     }
20619 
20620   if (c_parser_next_token_is_not (parser, CPP_NAME)
20621       || c_parser_peek_token (parser)->id_kind != C_ID_ID)
20622     {
20623       c_parser_error (parser, "expected identifier");
20624       goto fail;
20625     }
20626 
20627   c_token *token = c_parser_peek_token (parser);
20628   tree variant = lookup_name (token->value);
20629 
20630   if (variant == NULL_TREE)
20631     {
20632       undeclared_variable (token->location, token->value);
20633       variant = error_mark_node;
20634     }
20635 
20636   c_parser_consume_token (parser);
20637 
20638   parens.require_close (parser);
20639 
20640   const char *clause = "";
20641   location_t match_loc = c_parser_peek_token (parser)->location;
20642   if (c_parser_next_token_is (parser, CPP_NAME))
20643     clause = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20644   if (strcmp (clause, "match"))
20645     {
20646       c_parser_error (parser, "expected %<match%>");
20647       goto fail;
20648     }
20649 
20650   c_parser_consume_token (parser);
20651 
20652   if (!parens.require_open (parser))
20653     goto fail;
20654 
20655   if (parms == NULL_TREE)
20656     parms = error_mark_node;
20657 
20658   tree ctx = c_parser_omp_context_selector_specification (parser, parms);
20659   if (ctx == error_mark_node)
20660     goto fail;
20661   ctx = c_omp_check_context_selector (match_loc, ctx);
20662   if (ctx != error_mark_node && variant != error_mark_node)
20663     {
20664       if (TREE_CODE (variant) != FUNCTION_DECL)
20665 	{
20666 	  error_at (token->location, "variant %qD is not a function", variant);
20667 	  variant = error_mark_node;
20668 	}
20669       else if (omp_get_context_selector (ctx, "construct", "simd") == NULL_TREE
20670 	       && !comptypes (TREE_TYPE (fndecl), TREE_TYPE (variant)))
20671 	{
20672 	  error_at (token->location, "variant %qD and base %qD have "
20673 				     "incompatible types", variant, fndecl);
20674 	  variant = error_mark_node;
20675 	}
20676       else if (fndecl_built_in_p (variant)
20677 	       && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
20678 			    "__builtin_", strlen ("__builtin_")) == 0
20679 		   || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
20680 			       "__sync_", strlen ("__sync_")) == 0
20681 		   || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
20682 			       "__atomic_", strlen ("__atomic_")) == 0))
20683 	{
20684 	  error_at (token->location, "variant %qD is a built-in", variant);
20685 	  variant = error_mark_node;
20686 	}
20687       if (variant != error_mark_node)
20688 	{
20689 	  C_DECL_USED (variant) = 1;
20690 	  tree construct = omp_get_context_selector (ctx, "construct", NULL);
20691 	  c_omp_mark_declare_variant (match_loc, variant, construct);
20692 	  if (omp_context_selector_matches (ctx))
20693 	    {
20694 	      tree attr
20695 		= tree_cons (get_identifier ("omp declare variant base"),
20696 			     build_tree_list (variant, ctx),
20697 			     DECL_ATTRIBUTES (fndecl));
20698 	      DECL_ATTRIBUTES (fndecl) = attr;
20699 	    }
20700 	}
20701     }
20702 
20703   parens.require_close (parser);
20704   c_parser_skip_to_pragma_eol (parser);
20705 }
20706 
20707 /* Finalize #pragma omp declare simd or #pragma omp declare variant
20708    clauses after FNDECL has been parsed, and put that into "omp declare simd"
20709    or "omp declare variant base" attribute.  */
20710 
20711 static void
c_finish_omp_declare_simd(c_parser * parser,tree fndecl,tree parms,vec<c_token> clauses)20712 c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms,
20713 			   vec<c_token> clauses)
20714 {
20715   /* Normally first token is CPP_NAME "simd" or "variant".  CPP_EOF there
20716      indicates error has been reported and CPP_PRAGMA that
20717      c_finish_omp_declare_simd has already processed the tokens.  */
20718   if (clauses.exists () && clauses[0].type == CPP_EOF)
20719     return;
20720   const char *kind = "simd";
20721   if (clauses.exists ()
20722       && (clauses[0].type == CPP_NAME || clauses[0].type == CPP_PRAGMA))
20723     kind = IDENTIFIER_POINTER (clauses[0].value);
20724   gcc_assert (strcmp (kind, "simd") == 0 || strcmp (kind, "variant") == 0);
20725   if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
20726     {
20727       error ("%<#pragma omp declare %s%> not immediately followed by "
20728 	     "a function declaration or definition", kind);
20729       clauses[0].type = CPP_EOF;
20730       return;
20731     }
20732   if (clauses.exists () && clauses[0].type != CPP_NAME)
20733     {
20734       error_at (DECL_SOURCE_LOCATION (fndecl),
20735 		"%<#pragma omp declare %s%> not immediately followed by "
20736 		"a single function declaration or definition", kind);
20737       clauses[0].type = CPP_EOF;
20738       return;
20739     }
20740 
20741   if (parms == NULL_TREE)
20742     parms = DECL_ARGUMENTS (fndecl);
20743 
20744   unsigned int tokens_avail = parser->tokens_avail;
20745   gcc_assert (parser->tokens == &parser->tokens_buf[0]);
20746 
20747   parser->tokens = clauses.address ();
20748   parser->tokens_avail = clauses.length ();
20749 
20750   /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end.  */
20751   while (parser->tokens_avail > 3)
20752     {
20753       c_token *token = c_parser_peek_token (parser);
20754       gcc_assert (token->type == CPP_NAME
20755 		  && strcmp (IDENTIFIER_POINTER (token->value), kind) == 0);
20756       c_parser_consume_token (parser);
20757       parser->in_pragma = true;
20758 
20759       if (strcmp (kind, "simd") == 0)
20760 	{
20761 	  tree c;
20762 	  c = c_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
20763 					"#pragma omp declare simd");
20764 	  c = c_omp_declare_simd_clauses_to_numbers (parms, c);
20765 	  if (c != NULL_TREE)
20766 	    c = tree_cons (NULL_TREE, c, NULL_TREE);
20767 	  c = build_tree_list (get_identifier ("omp declare simd"), c);
20768 	  TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl);
20769 	  DECL_ATTRIBUTES (fndecl) = c;
20770 	}
20771       else
20772 	{
20773 	  gcc_assert (strcmp (kind, "variant") == 0);
20774 	  c_finish_omp_declare_variant (parser, fndecl, parms);
20775 	}
20776     }
20777 
20778   parser->tokens = &parser->tokens_buf[0];
20779   parser->tokens_avail = tokens_avail;
20780   if (clauses.exists ())
20781     clauses[0].type = CPP_PRAGMA;
20782 }
20783 
20784 
20785 /* OpenMP 4.0:
20786    # pragma omp declare target new-line
20787    declarations and definitions
20788    # pragma omp end declare target new-line
20789 
20790    OpenMP 4.5:
20791    # pragma omp declare target ( extended-list ) new-line
20792 
20793    # pragma omp declare target declare-target-clauses[seq] new-line  */
20794 
20795 #define OMP_DECLARE_TARGET_CLAUSE_MASK				\
20796 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO)		\
20797 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)		\
20798 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
20799 
20800 static void
c_parser_omp_declare_target(c_parser * parser)20801 c_parser_omp_declare_target (c_parser *parser)
20802 {
20803   tree clauses = NULL_TREE;
20804   int device_type = 0;
20805   bool only_device_type = true;
20806   if (c_parser_next_token_is (parser, CPP_NAME))
20807     clauses = c_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
20808 					"#pragma omp declare target");
20809   else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
20810     {
20811       clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO_DECLARE,
20812 					      clauses);
20813       clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
20814       c_parser_skip_to_pragma_eol (parser);
20815     }
20816   else
20817     {
20818       c_parser_skip_to_pragma_eol (parser);
20819       current_omp_declare_target_attribute++;
20820       return;
20821     }
20822   for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
20823     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
20824       device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
20825   for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
20826     {
20827       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
20828 	continue;
20829       tree t = OMP_CLAUSE_DECL (c), id;
20830       tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
20831       tree at2 = lookup_attribute ("omp declare target link",
20832 				   DECL_ATTRIBUTES (t));
20833       only_device_type = false;
20834       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
20835 	{
20836 	  id = get_identifier ("omp declare target link");
20837 	  std::swap (at1, at2);
20838 	}
20839       else
20840 	id = get_identifier ("omp declare target");
20841       if (at2)
20842 	{
20843 	  error_at (OMP_CLAUSE_LOCATION (c),
20844 		    "%qD specified both in declare target %<link%> and %<to%>"
20845 		    " clauses", t);
20846 	  continue;
20847 	}
20848       if (!at1)
20849 	{
20850 	  DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
20851 	  if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t))
20852 	    continue;
20853 
20854 	  symtab_node *node = symtab_node::get (t);
20855 	  if (node != NULL)
20856 	    {
20857 	      node->offloadable = 1;
20858 	      if (ENABLE_OFFLOADING)
20859 		{
20860 		  g->have_offload = true;
20861 		  if (is_a <varpool_node *> (node))
20862 		    vec_safe_push (offload_vars, t);
20863 		}
20864 	    }
20865 	}
20866       if (TREE_CODE (t) != FUNCTION_DECL)
20867 	continue;
20868       if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0)
20869 	{
20870 	  tree at3 = lookup_attribute ("omp declare target host",
20871 				       DECL_ATTRIBUTES (t));
20872 	  if (at3 == NULL_TREE)
20873 	    {
20874 	      id = get_identifier ("omp declare target host");
20875 	      DECL_ATTRIBUTES (t)
20876 		= tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
20877 	    }
20878 	}
20879       if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0)
20880 	{
20881 	  tree at3 = lookup_attribute ("omp declare target nohost",
20882 				       DECL_ATTRIBUTES (t));
20883 	  if (at3 == NULL_TREE)
20884 	    {
20885 	      id = get_identifier ("omp declare target nohost");
20886 	      DECL_ATTRIBUTES (t)
20887 		= tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
20888 	    }
20889 	}
20890     }
20891   if (device_type && only_device_type)
20892     warning_at (OMP_CLAUSE_LOCATION (clauses), 0,
20893 		"directive with only %<device_type%> clauses ignored");
20894 }
20895 
20896 static void
c_parser_omp_end_declare_target(c_parser * parser)20897 c_parser_omp_end_declare_target (c_parser *parser)
20898 {
20899   location_t loc = c_parser_peek_token (parser)->location;
20900   c_parser_consume_pragma (parser);
20901   if (c_parser_next_token_is (parser, CPP_NAME)
20902       && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
20903 		 "declare") == 0)
20904     {
20905       c_parser_consume_token (parser);
20906       if (c_parser_next_token_is (parser, CPP_NAME)
20907 	  && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
20908 		     "target") == 0)
20909 	c_parser_consume_token (parser);
20910       else
20911 	{
20912 	  c_parser_error (parser, "expected %<target%>");
20913 	  c_parser_skip_to_pragma_eol (parser);
20914 	  return;
20915 	}
20916     }
20917   else
20918     {
20919       c_parser_error (parser, "expected %<declare%>");
20920       c_parser_skip_to_pragma_eol (parser);
20921       return;
20922     }
20923   c_parser_skip_to_pragma_eol (parser);
20924   if (!current_omp_declare_target_attribute)
20925     error_at (loc, "%<#pragma omp end declare target%> without corresponding "
20926 		   "%<#pragma omp declare target%>");
20927   else
20928     current_omp_declare_target_attribute--;
20929 }
20930 
20931 
20932 /* OpenMP 4.0
20933    #pragma omp declare reduction (reduction-id : typename-list : expression) \
20934       initializer-clause[opt] new-line
20935 
20936    initializer-clause:
20937       initializer (omp_priv = initializer)
20938       initializer (function-name (argument-list))  */
20939 
20940 static void
c_parser_omp_declare_reduction(c_parser * parser,enum pragma_context context)20941 c_parser_omp_declare_reduction (c_parser *parser, enum pragma_context context)
20942 {
20943   unsigned int tokens_avail = 0, i;
20944   vec<tree> types = vNULL;
20945   vec<c_token> clauses = vNULL;
20946   enum tree_code reduc_code = ERROR_MARK;
20947   tree reduc_id = NULL_TREE;
20948   tree type;
20949   location_t rloc = c_parser_peek_token (parser)->location;
20950 
20951   if (context == pragma_struct || context == pragma_param)
20952     {
20953       error ("%<#pragma omp declare reduction%> not at file or block scope");
20954       goto fail;
20955     }
20956 
20957   if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
20958     goto fail;
20959 
20960   switch (c_parser_peek_token (parser)->type)
20961     {
20962     case CPP_PLUS:
20963       reduc_code = PLUS_EXPR;
20964       break;
20965     case CPP_MULT:
20966       reduc_code = MULT_EXPR;
20967       break;
20968     case CPP_MINUS:
20969       reduc_code = MINUS_EXPR;
20970       break;
20971     case CPP_AND:
20972       reduc_code = BIT_AND_EXPR;
20973       break;
20974     case CPP_XOR:
20975       reduc_code = BIT_XOR_EXPR;
20976       break;
20977     case CPP_OR:
20978       reduc_code = BIT_IOR_EXPR;
20979       break;
20980     case CPP_AND_AND:
20981       reduc_code = TRUTH_ANDIF_EXPR;
20982       break;
20983     case CPP_OR_OR:
20984       reduc_code = TRUTH_ORIF_EXPR;
20985       break;
20986     case CPP_NAME:
20987       const char *p;
20988       p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20989       if (strcmp (p, "min") == 0)
20990 	{
20991 	  reduc_code = MIN_EXPR;
20992 	  break;
20993 	}
20994       if (strcmp (p, "max") == 0)
20995 	{
20996 	  reduc_code = MAX_EXPR;
20997 	  break;
20998 	}
20999       reduc_id = c_parser_peek_token (parser)->value;
21000       break;
21001     default:
21002       c_parser_error (parser,
21003 		      "expected %<+%>, %<*%>, %<-%>, %<&%>, "
21004 		      "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
21005       goto fail;
21006     }
21007 
21008   tree orig_reduc_id, reduc_decl;
21009   orig_reduc_id = reduc_id;
21010   reduc_id = c_omp_reduction_id (reduc_code, reduc_id);
21011   reduc_decl = c_omp_reduction_decl (reduc_id);
21012   c_parser_consume_token (parser);
21013 
21014   if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
21015     goto fail;
21016 
21017   while (true)
21018     {
21019       location_t loc = c_parser_peek_token (parser)->location;
21020       struct c_type_name *ctype = c_parser_type_name (parser);
21021       if (ctype != NULL)
21022 	{
21023 	  type = groktypename (ctype, NULL, NULL);
21024 	  if (type == error_mark_node)
21025 	    ;
21026 	  else if ((INTEGRAL_TYPE_P (type)
21027 		    || TREE_CODE (type) == REAL_TYPE
21028 		    || TREE_CODE (type) == COMPLEX_TYPE)
21029 		   && orig_reduc_id == NULL_TREE)
21030 	    error_at (loc, "predeclared arithmetic type in "
21031 			   "%<#pragma omp declare reduction%>");
21032 	  else if (TREE_CODE (type) == FUNCTION_TYPE
21033 		   || TREE_CODE (type) == ARRAY_TYPE)
21034 	    error_at (loc, "function or array type in "
21035 		      "%<#pragma omp declare reduction%>");
21036 	  else if (TYPE_ATOMIC (type))
21037 	    error_at (loc, "%<_Atomic%> qualified type in "
21038 			   "%<#pragma omp declare reduction%>");
21039 	  else if (TYPE_QUALS_NO_ADDR_SPACE (type))
21040 	    error_at (loc, "const, volatile or restrict qualified type in "
21041 			   "%<#pragma omp declare reduction%>");
21042 	  else
21043 	    {
21044 	      tree t;
21045 	      for (t = DECL_INITIAL (reduc_decl); t; t = TREE_CHAIN (t))
21046 		if (comptypes (TREE_PURPOSE (t), type))
21047 		  {
21048 		    error_at (loc, "redeclaration of %qs "
21049 				   "%<#pragma omp declare reduction%> for "
21050 				   "type %qT",
21051 				   IDENTIFIER_POINTER (reduc_id)
21052 				   + sizeof ("omp declare reduction ") - 1,
21053 				   type);
21054 		    location_t ploc
21055 		      = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t),
21056 							    0));
21057 		    error_at (ploc, "previous %<#pragma omp declare "
21058 				    "reduction%>");
21059 		    break;
21060 		  }
21061 	      if (t == NULL_TREE)
21062 		types.safe_push (type);
21063 	    }
21064 	  if (c_parser_next_token_is (parser, CPP_COMMA))
21065 	    c_parser_consume_token (parser);
21066 	  else
21067 	    break;
21068 	}
21069       else
21070 	break;
21071     }
21072 
21073   if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")
21074       || types.is_empty ())
21075     {
21076      fail:
21077       clauses.release ();
21078       types.release ();
21079       while (true)
21080 	{
21081 	  c_token *token = c_parser_peek_token (parser);
21082 	  if (token->type == CPP_EOF || token->type == CPP_PRAGMA_EOL)
21083 	    break;
21084 	  c_parser_consume_token (parser);
21085 	}
21086       c_parser_skip_to_pragma_eol (parser);
21087       return;
21088     }
21089 
21090   if (types.length () > 1)
21091     {
21092       while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
21093 	{
21094 	  c_token *token = c_parser_peek_token (parser);
21095 	  if (token->type == CPP_EOF)
21096 	    goto fail;
21097 	  clauses.safe_push (*token);
21098 	  c_parser_consume_token (parser);
21099 	}
21100       clauses.safe_push (*c_parser_peek_token (parser));
21101       c_parser_skip_to_pragma_eol (parser);
21102 
21103       /* Make sure nothing tries to read past the end of the tokens.  */
21104       c_token eof_token;
21105       memset (&eof_token, 0, sizeof (eof_token));
21106       eof_token.type = CPP_EOF;
21107       clauses.safe_push (eof_token);
21108       clauses.safe_push (eof_token);
21109     }
21110 
21111   int errs = errorcount;
21112   FOR_EACH_VEC_ELT (types, i, type)
21113     {
21114       tokens_avail = parser->tokens_avail;
21115       gcc_assert (parser->tokens == &parser->tokens_buf[0]);
21116       if (!clauses.is_empty ())
21117 	{
21118 	  parser->tokens = clauses.address ();
21119 	  parser->tokens_avail = clauses.length ();
21120 	  parser->in_pragma = true;
21121 	}
21122 
21123       bool nested = current_function_decl != NULL_TREE;
21124       if (nested)
21125 	c_push_function_context ();
21126       tree fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
21127 				reduc_id, default_function_type);
21128       current_function_decl = fndecl;
21129       allocate_struct_function (fndecl, true);
21130       push_scope ();
21131       tree stmt = push_stmt_list ();
21132       /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
21133 	 warn about these.  */
21134       tree omp_out = build_decl (BUILTINS_LOCATION, VAR_DECL,
21135 				 get_identifier ("omp_out"), type);
21136       DECL_ARTIFICIAL (omp_out) = 1;
21137       DECL_CONTEXT (omp_out) = fndecl;
21138       pushdecl (omp_out);
21139       tree omp_in = build_decl (BUILTINS_LOCATION, VAR_DECL,
21140 				get_identifier ("omp_in"), type);
21141       DECL_ARTIFICIAL (omp_in) = 1;
21142       DECL_CONTEXT (omp_in) = fndecl;
21143       pushdecl (omp_in);
21144       struct c_expr combiner = c_parser_expression (parser);
21145       struct c_expr initializer;
21146       tree omp_priv = NULL_TREE, omp_orig = NULL_TREE;
21147       bool bad = false;
21148       initializer.set_error ();
21149       if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
21150 	bad = true;
21151       else if (c_parser_next_token_is (parser, CPP_NAME)
21152 	       && strcmp (IDENTIFIER_POINTER
21153 				(c_parser_peek_token (parser)->value),
21154 			  "initializer") == 0)
21155 	{
21156 	  c_parser_consume_token (parser);
21157 	  pop_scope ();
21158 	  push_scope ();
21159 	  omp_priv = build_decl (BUILTINS_LOCATION, VAR_DECL,
21160 				 get_identifier ("omp_priv"), type);
21161 	  DECL_ARTIFICIAL (omp_priv) = 1;
21162 	  DECL_INITIAL (omp_priv) = error_mark_node;
21163 	  DECL_CONTEXT (omp_priv) = fndecl;
21164 	  pushdecl (omp_priv);
21165 	  omp_orig = build_decl (BUILTINS_LOCATION, VAR_DECL,
21166 				 get_identifier ("omp_orig"), type);
21167 	  DECL_ARTIFICIAL (omp_orig) = 1;
21168 	  DECL_CONTEXT (omp_orig) = fndecl;
21169 	  pushdecl (omp_orig);
21170 	  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
21171 	    bad = true;
21172 	  else if (!c_parser_next_token_is (parser, CPP_NAME))
21173 	    {
21174 	      c_parser_error (parser, "expected %<omp_priv%> or "
21175 				      "function-name");
21176 	      bad = true;
21177 	    }
21178 	  else if (strcmp (IDENTIFIER_POINTER
21179 				(c_parser_peek_token (parser)->value),
21180 			   "omp_priv") != 0)
21181 	    {
21182 	      if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
21183 		  || c_parser_peek_token (parser)->id_kind != C_ID_ID)
21184 		{
21185 		  c_parser_error (parser, "expected function-name %<(%>");
21186 		  bad = true;
21187 		}
21188 	      else
21189 		initializer = c_parser_postfix_expression (parser);
21190 	      if (initializer.value
21191 		  && TREE_CODE (initializer.value) == CALL_EXPR)
21192 		{
21193 		  int j;
21194 		  tree c = initializer.value;
21195 		  for (j = 0; j < call_expr_nargs (c); j++)
21196 		    {
21197 		      tree a = CALL_EXPR_ARG (c, j);
21198 		      STRIP_NOPS (a);
21199 		      if (TREE_CODE (a) == ADDR_EXPR
21200 			  && TREE_OPERAND (a, 0) == omp_priv)
21201 			break;
21202 		    }
21203 		  if (j == call_expr_nargs (c))
21204 		    error ("one of the initializer call arguments should be "
21205 			   "%<&omp_priv%>");
21206 		}
21207 	    }
21208 	  else
21209 	    {
21210 	      c_parser_consume_token (parser);
21211 	      if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
21212 		bad = true;
21213 	      else
21214 		{
21215 		  tree st = push_stmt_list ();
21216 		  location_t loc = c_parser_peek_token (parser)->location;
21217 		  rich_location richloc (line_table, loc);
21218 		  start_init (omp_priv, NULL_TREE, 0, &richloc);
21219 		  struct c_expr init = c_parser_initializer (parser);
21220 		  finish_init ();
21221 		  finish_decl (omp_priv, loc, init.value,
21222 		      	       init.original_type, NULL_TREE);
21223 		  pop_stmt_list (st);
21224 		}
21225 	    }
21226 	  if (!bad
21227 	      && !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
21228 	    bad = true;
21229 	}
21230 
21231       if (!bad)
21232 	{
21233 	  c_parser_skip_to_pragma_eol (parser);
21234 
21235 	  tree t = tree_cons (type, make_tree_vec (omp_priv ? 6 : 3),
21236 			      DECL_INITIAL (reduc_decl));
21237 	  DECL_INITIAL (reduc_decl) = t;
21238 	  DECL_SOURCE_LOCATION (omp_out) = rloc;
21239 	  TREE_VEC_ELT (TREE_VALUE (t), 0) = omp_out;
21240 	  TREE_VEC_ELT (TREE_VALUE (t), 1) = omp_in;
21241 	  TREE_VEC_ELT (TREE_VALUE (t), 2) = combiner.value;
21242 	  walk_tree (&combiner.value, c_check_omp_declare_reduction_r,
21243 		     &TREE_VEC_ELT (TREE_VALUE (t), 0), NULL);
21244 	  if (omp_priv)
21245 	    {
21246 	      DECL_SOURCE_LOCATION (omp_priv) = rloc;
21247 	      TREE_VEC_ELT (TREE_VALUE (t), 3) = omp_priv;
21248 	      TREE_VEC_ELT (TREE_VALUE (t), 4) = omp_orig;
21249 	      TREE_VEC_ELT (TREE_VALUE (t), 5) = initializer.value;
21250 	      walk_tree (&initializer.value, c_check_omp_declare_reduction_r,
21251 			 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
21252 	      walk_tree (&DECL_INITIAL (omp_priv),
21253 			 c_check_omp_declare_reduction_r,
21254 			 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
21255 	    }
21256 	}
21257 
21258       pop_stmt_list (stmt);
21259       pop_scope ();
21260       if (cfun->language != NULL)
21261 	{
21262 	  ggc_free (cfun->language);
21263 	  cfun->language = NULL;
21264 	}
21265       set_cfun (NULL);
21266       current_function_decl = NULL_TREE;
21267       if (nested)
21268 	c_pop_function_context ();
21269 
21270       if (!clauses.is_empty ())
21271 	{
21272 	  parser->tokens = &parser->tokens_buf[0];
21273 	  parser->tokens_avail = tokens_avail;
21274 	}
21275       if (bad)
21276 	goto fail;
21277       if (errs != errorcount)
21278 	break;
21279     }
21280 
21281   clauses.release ();
21282   types.release ();
21283 }
21284 
21285 
21286 /* OpenMP 4.0
21287    #pragma omp declare simd declare-simd-clauses[optseq] new-line
21288    #pragma omp declare reduction (reduction-id : typename-list : expression) \
21289       initializer-clause[opt] new-line
21290    #pragma omp declare target new-line
21291 
21292    OpenMP 5.0
21293    #pragma omp declare variant (identifier) match (context-selector)  */
21294 
21295 static void
c_parser_omp_declare(c_parser * parser,enum pragma_context context)21296 c_parser_omp_declare (c_parser *parser, enum pragma_context context)
21297 {
21298   c_parser_consume_pragma (parser);
21299   if (c_parser_next_token_is (parser, CPP_NAME))
21300     {
21301       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21302       if (strcmp (p, "simd") == 0)
21303 	{
21304 	  /* c_parser_consume_token (parser); done in
21305 	     c_parser_omp_declare_simd.  */
21306 	  c_parser_omp_declare_simd (parser, context);
21307 	  return;
21308 	}
21309       if (strcmp (p, "reduction") == 0)
21310 	{
21311 	  c_parser_consume_token (parser);
21312 	  c_parser_omp_declare_reduction (parser, context);
21313 	  return;
21314 	}
21315       if (!flag_openmp)  /* flag_openmp_simd  */
21316 	{
21317 	  c_parser_skip_to_pragma_eol (parser, false);
21318 	  return;
21319 	}
21320       if (strcmp (p, "target") == 0)
21321 	{
21322 	  c_parser_consume_token (parser);
21323 	  c_parser_omp_declare_target (parser);
21324 	  return;
21325 	}
21326       if (strcmp (p, "variant") == 0)
21327 	{
21328 	  /* c_parser_consume_token (parser); done in
21329 	     c_parser_omp_declare_simd.  */
21330 	  c_parser_omp_declare_simd (parser, context);
21331 	  return;
21332 	}
21333     }
21334 
21335   c_parser_error (parser, "expected %<simd%>, %<reduction%>, "
21336 			  "%<target%> or %<variant%>");
21337   c_parser_skip_to_pragma_eol (parser);
21338 }
21339 
21340 /* OpenMP 5.0
21341    #pragma omp requires clauses[optseq] new-line  */
21342 
21343 static void
c_parser_omp_requires(c_parser * parser)21344 c_parser_omp_requires (c_parser *parser)
21345 {
21346   bool first = true;
21347   enum omp_requires new_req = (enum omp_requires) 0;
21348 
21349   c_parser_consume_pragma (parser);
21350 
21351   location_t loc = c_parser_peek_token (parser)->location;
21352   while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
21353     {
21354       if (!first && c_parser_next_token_is (parser, CPP_COMMA))
21355 	c_parser_consume_token (parser);
21356 
21357       first = false;
21358 
21359       if (c_parser_next_token_is (parser, CPP_NAME))
21360 	{
21361 	  const char *p
21362 	    = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21363 	  location_t cloc = c_parser_peek_token (parser)->location;
21364 	  enum omp_requires this_req = (enum omp_requires) 0;
21365 
21366 	  if (!strcmp (p, "unified_address"))
21367 	    this_req = OMP_REQUIRES_UNIFIED_ADDRESS;
21368 	  else if (!strcmp (p, "unified_shared_memory"))
21369 	    this_req = OMP_REQUIRES_UNIFIED_SHARED_MEMORY;
21370 	  else if (!strcmp (p, "dynamic_allocators"))
21371 	    this_req = OMP_REQUIRES_DYNAMIC_ALLOCATORS;
21372 	  else if (!strcmp (p, "reverse_offload"))
21373 	    this_req = OMP_REQUIRES_REVERSE_OFFLOAD;
21374 	  else if (!strcmp (p, "atomic_default_mem_order"))
21375 	    {
21376 	      c_parser_consume_token (parser);
21377 
21378 	      matching_parens parens;
21379 	      if (parens.require_open (parser))
21380 		{
21381 		  if (c_parser_next_token_is (parser, CPP_NAME))
21382 		    {
21383 		      tree v = c_parser_peek_token (parser)->value;
21384 		      p = IDENTIFIER_POINTER (v);
21385 
21386 		      if (!strcmp (p, "seq_cst"))
21387 			this_req
21388 			  = (enum omp_requires) OMP_MEMORY_ORDER_SEQ_CST;
21389 		      else if (!strcmp (p, "relaxed"))
21390 			this_req
21391 			  = (enum omp_requires) OMP_MEMORY_ORDER_RELAXED;
21392 		      else if (!strcmp (p, "acq_rel"))
21393 			this_req
21394 			  = (enum omp_requires) OMP_MEMORY_ORDER_ACQ_REL;
21395 		    }
21396 		  if (this_req == 0)
21397 		    {
21398 		      error_at (c_parser_peek_token (parser)->location,
21399 				"expected %<seq_cst%>, %<relaxed%> or "
21400 				"%<acq_rel%>");
21401 		      if (c_parser_peek_2nd_token (parser)->type
21402 			  == CPP_CLOSE_PAREN)
21403 			c_parser_consume_token (parser);
21404 		    }
21405 		  else
21406 		    c_parser_consume_token (parser);
21407 
21408 		  parens.skip_until_found_close (parser);
21409 		  if (this_req == 0)
21410 		    {
21411 		      c_parser_skip_to_pragma_eol (parser, false);
21412 		      return;
21413 		    }
21414 		}
21415 	      p = NULL;
21416 	    }
21417 	  else
21418 	    {
21419 	      error_at (cloc, "expected %<unified_address%>, "
21420 			      "%<unified_shared_memory%>, "
21421 			      "%<dynamic_allocators%>, "
21422 			       "%<reverse_offload%> "
21423 			       "or %<atomic_default_mem_order%> clause");
21424 	      c_parser_skip_to_pragma_eol (parser, false);
21425 	      return;
21426 	    }
21427 	  if (p)
21428 	    sorry_at (cloc, "%qs clause on %<requires%> directive not "
21429 			    "supported yet", p);
21430 	  if (p)
21431 	    c_parser_consume_token (parser);
21432 	  if (this_req)
21433 	    {
21434 	      if ((this_req & ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
21435 		{
21436 		  if ((this_req & new_req) != 0)
21437 		    error_at (cloc, "too many %qs clauses", p);
21438 		  if (this_req != OMP_REQUIRES_DYNAMIC_ALLOCATORS
21439 		      && (omp_requires_mask & OMP_REQUIRES_TARGET_USED) != 0)
21440 		    error_at (cloc, "%qs clause used lexically after first "
21441 				    "target construct or offloading API", p);
21442 		}
21443 	      else if ((new_req & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
21444 		{
21445 		  error_at (cloc, "too many %qs clauses",
21446 			    "atomic_default_mem_order");
21447 		  this_req = (enum omp_requires) 0;
21448 		}
21449 	      else if ((omp_requires_mask
21450 			& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
21451 		{
21452 		  error_at (cloc, "more than one %<atomic_default_mem_order%>"
21453 				  " clause in a single compilation unit");
21454 		  this_req
21455 		    = (enum omp_requires)
21456 		       (omp_requires_mask
21457 			& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER);
21458 		}
21459 	      else if ((omp_requires_mask
21460 			& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED) != 0)
21461 		error_at (cloc, "%<atomic_default_mem_order%> clause used "
21462 				"lexically after first %<atomic%> construct "
21463 				"without memory order clause");
21464 	      new_req = (enum omp_requires) (new_req | this_req);
21465 	      omp_requires_mask
21466 		= (enum omp_requires) (omp_requires_mask | this_req);
21467 	      continue;
21468 	    }
21469 	}
21470       break;
21471     }
21472   c_parser_skip_to_pragma_eol (parser);
21473 
21474   if (new_req == 0)
21475     error_at (loc, "%<pragma omp requires%> requires at least one clause");
21476 }
21477 
21478 /* Helper function for c_parser_omp_taskloop.
21479    Disallow zero sized or potentially zero sized task reductions.  */
21480 
21481 static tree
c_finish_taskloop_clauses(tree clauses)21482 c_finish_taskloop_clauses (tree clauses)
21483 {
21484   tree *pc = &clauses;
21485   for (tree c = clauses; c; c = *pc)
21486     {
21487       bool remove = false;
21488       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
21489 	{
21490 	  tree type = strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c)));
21491 	  if (integer_zerop (TYPE_SIZE_UNIT (type)))
21492 	    {
21493 	      error_at (OMP_CLAUSE_LOCATION (c),
21494 			"zero sized type %qT in %<reduction%> clause", type);
21495 	      remove = true;
21496 	    }
21497 	  else if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
21498 	    {
21499 	      error_at (OMP_CLAUSE_LOCATION (c),
21500 			"variable sized type %qT in %<reduction%> clause",
21501 			type);
21502 	      remove = true;
21503 	    }
21504 	}
21505       if (remove)
21506 	*pc = OMP_CLAUSE_CHAIN (c);
21507       else
21508 	pc = &OMP_CLAUSE_CHAIN (c);
21509     }
21510   return clauses;
21511 }
21512 
21513 /* OpenMP 4.5:
21514    #pragma omp taskloop taskloop-clause[optseq] new-line
21515      for-loop
21516 
21517    #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
21518      for-loop  */
21519 
21520 #define OMP_TASKLOOP_CLAUSE_MASK				\
21521 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED)	\
21522 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
21523 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
21524 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)	\
21525 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT)	\
21526 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE)	\
21527 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS)	\
21528 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)	\
21529 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED)	\
21530 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
21531 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL)	\
21532 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE)	\
21533 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP)	\
21534 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY)	\
21535 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)	\
21536 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)	\
21537 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
21538 
21539 static tree
c_parser_omp_taskloop(location_t loc,c_parser * parser,char * p_name,omp_clause_mask mask,tree * cclauses,bool * if_p)21540 c_parser_omp_taskloop (location_t loc, c_parser *parser,
21541 		       char *p_name, omp_clause_mask mask, tree *cclauses,
21542 		       bool *if_p)
21543 {
21544   tree clauses, block, ret;
21545 
21546   strcat (p_name, " taskloop");
21547   mask |= OMP_TASKLOOP_CLAUSE_MASK;
21548   /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
21549      clause.  */
21550   if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
21551     mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION);
21552 
21553   if (c_parser_next_token_is (parser, CPP_NAME))
21554     {
21555       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21556 
21557       if (strcmp (p, "simd") == 0)
21558 	{
21559 	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
21560 	  if (cclauses == NULL)
21561 	    cclauses = cclauses_buf;
21562 	  c_parser_consume_token (parser);
21563 	  if (!flag_openmp)  /* flag_openmp_simd  */
21564 	    return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
21565 				      if_p);
21566 	  block = c_begin_compound_stmt (true);
21567 	  ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
21568 	  block = c_end_compound_stmt (loc, block, true);
21569 	  if (ret == NULL)
21570 	    return ret;
21571 	  ret = make_node (OMP_TASKLOOP);
21572 	  TREE_TYPE (ret) = void_type_node;
21573 	  OMP_FOR_BODY (ret) = block;
21574 	  OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
21575 	  OMP_FOR_CLAUSES (ret)
21576 	    = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret));
21577 	  SET_EXPR_LOCATION (ret, loc);
21578 	  add_stmt (ret);
21579 	  return ret;
21580 	}
21581     }
21582   if (!flag_openmp)  /* flag_openmp_simd  */
21583     {
21584       c_parser_skip_to_pragma_eol (parser, false);
21585       return NULL_TREE;
21586     }
21587 
21588   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
21589   if (cclauses)
21590     {
21591       omp_split_clauses (loc, OMP_TASKLOOP, mask, clauses, cclauses);
21592       clauses = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
21593     }
21594 
21595   clauses = c_finish_taskloop_clauses (clauses);
21596   block = c_begin_compound_stmt (true);
21597   ret = c_parser_omp_for_loop (loc, parser, OMP_TASKLOOP, clauses, NULL, if_p);
21598   block = c_end_compound_stmt (loc, block, true);
21599   add_stmt (block);
21600 
21601   return ret;
21602 }
21603 
21604 /* Main entry point to parsing most OpenMP pragmas.  */
21605 
21606 static void
c_parser_omp_construct(c_parser * parser,bool * if_p)21607 c_parser_omp_construct (c_parser *parser, bool *if_p)
21608 {
21609   enum pragma_kind p_kind;
21610   location_t loc;
21611   tree stmt;
21612   char p_name[sizeof "#pragma omp teams distribute parallel for simd"];
21613   omp_clause_mask mask (0);
21614 
21615   loc = c_parser_peek_token (parser)->location;
21616   p_kind = c_parser_peek_token (parser)->pragma_kind;
21617   c_parser_consume_pragma (parser);
21618 
21619   switch (p_kind)
21620     {
21621     case PRAGMA_OACC_ATOMIC:
21622       c_parser_omp_atomic (loc, parser, true);
21623       return;
21624     case PRAGMA_OACC_CACHE:
21625       strcpy (p_name, "#pragma acc");
21626       stmt = c_parser_oacc_cache (loc, parser);
21627       break;
21628     case PRAGMA_OACC_DATA:
21629       stmt = c_parser_oacc_data (loc, parser, if_p);
21630       break;
21631     case PRAGMA_OACC_HOST_DATA:
21632       stmt = c_parser_oacc_host_data (loc, parser, if_p);
21633       break;
21634     case PRAGMA_OACC_KERNELS:
21635     case PRAGMA_OACC_PARALLEL:
21636     case PRAGMA_OACC_SERIAL:
21637       strcpy (p_name, "#pragma acc");
21638       stmt = c_parser_oacc_compute (loc, parser, p_kind, p_name, if_p);
21639       break;
21640     case PRAGMA_OACC_LOOP:
21641       strcpy (p_name, "#pragma acc");
21642       stmt = c_parser_oacc_loop (loc, parser, p_name, mask, NULL, if_p);
21643       break;
21644     case PRAGMA_OACC_WAIT:
21645       strcpy (p_name, "#pragma wait");
21646       stmt = c_parser_oacc_wait (loc, parser, p_name);
21647       break;
21648     case PRAGMA_OMP_ALLOCATE:
21649       c_parser_omp_allocate (loc, parser);
21650       return;
21651     case PRAGMA_OMP_ATOMIC:
21652       c_parser_omp_atomic (loc, parser, false);
21653       return;
21654     case PRAGMA_OMP_CRITICAL:
21655       stmt = c_parser_omp_critical (loc, parser, if_p);
21656       break;
21657     case PRAGMA_OMP_DISTRIBUTE:
21658       strcpy (p_name, "#pragma omp");
21659       stmt = c_parser_omp_distribute (loc, parser, p_name, mask, NULL, if_p);
21660       break;
21661     case PRAGMA_OMP_FOR:
21662       strcpy (p_name, "#pragma omp");
21663       stmt = c_parser_omp_for (loc, parser, p_name, mask, NULL, if_p);
21664       break;
21665     case PRAGMA_OMP_LOOP:
21666       strcpy (p_name, "#pragma omp");
21667       stmt = c_parser_omp_loop (loc, parser, p_name, mask, NULL, if_p);
21668       break;
21669     case PRAGMA_OMP_MASTER:
21670       strcpy (p_name, "#pragma omp");
21671       stmt = c_parser_omp_master (loc, parser, p_name, mask, NULL, if_p);
21672       break;
21673     case PRAGMA_OMP_PARALLEL:
21674       strcpy (p_name, "#pragma omp");
21675       stmt = c_parser_omp_parallel (loc, parser, p_name, mask, NULL, if_p);
21676       break;
21677     case PRAGMA_OMP_SECTIONS:
21678       strcpy (p_name, "#pragma omp");
21679       stmt = c_parser_omp_sections (loc, parser, p_name, mask, NULL);
21680       break;
21681     case PRAGMA_OMP_SIMD:
21682       strcpy (p_name, "#pragma omp");
21683       stmt = c_parser_omp_simd (loc, parser, p_name, mask, NULL, if_p);
21684       break;
21685     case PRAGMA_OMP_SINGLE:
21686       stmt = c_parser_omp_single (loc, parser, if_p);
21687       break;
21688     case PRAGMA_OMP_TASK:
21689       stmt = c_parser_omp_task (loc, parser, if_p);
21690       break;
21691     case PRAGMA_OMP_TASKGROUP:
21692       stmt = c_parser_omp_taskgroup (loc, parser, if_p);
21693       break;
21694     case PRAGMA_OMP_TASKLOOP:
21695       strcpy (p_name, "#pragma omp");
21696       stmt = c_parser_omp_taskloop (loc, parser, p_name, mask, NULL, if_p);
21697       break;
21698     case PRAGMA_OMP_TEAMS:
21699       strcpy (p_name, "#pragma omp");
21700       stmt = c_parser_omp_teams (loc, parser, p_name, mask, NULL, if_p);
21701       break;
21702     default:
21703       gcc_unreachable ();
21704     }
21705 
21706   if (stmt && stmt != error_mark_node)
21707     gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION);
21708 }
21709 
21710 
21711 /* OpenMP 2.5:
21712    # pragma omp threadprivate (variable-list) */
21713 
21714 static void
c_parser_omp_threadprivate(c_parser * parser)21715 c_parser_omp_threadprivate (c_parser *parser)
21716 {
21717   tree vars, t;
21718   location_t loc;
21719 
21720   c_parser_consume_pragma (parser);
21721   loc = c_parser_peek_token (parser)->location;
21722   vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
21723 
21724   /* Mark every variable in VARS to be assigned thread local storage.  */
21725   for (t = vars; t; t = TREE_CHAIN (t))
21726     {
21727       tree v = TREE_PURPOSE (t);
21728 
21729       /* FIXME diagnostics: Ideally we should keep individual
21730 	 locations for all the variables in the var list to make the
21731 	 following errors more precise.  Perhaps
21732 	 c_parser_omp_var_list_parens() should construct a list of
21733 	 locations to go along with the var list.  */
21734 
21735       /* If V had already been marked threadprivate, it doesn't matter
21736 	 whether it had been used prior to this point.  */
21737       if (!VAR_P (v))
21738 	error_at (loc, "%qD is not a variable", v);
21739       else if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v))
21740 	error_at (loc, "%qE declared %<threadprivate%> after first use", v);
21741       else if (! is_global_var (v))
21742 	error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v);
21743       else if (TREE_TYPE (v) == error_mark_node)
21744 	;
21745       else if (! COMPLETE_TYPE_P (TREE_TYPE (v)))
21746 	error_at (loc, "%<threadprivate%> %qE has incomplete type", v);
21747       else
21748 	{
21749 	  if (! DECL_THREAD_LOCAL_P (v))
21750 	    {
21751 	      set_decl_tls_model (v, decl_default_tls_model (v));
21752 	      /* If rtl has been already set for this var, call
21753 		 make_decl_rtl once again, so that encode_section_info
21754 		 has a chance to look at the new decl flags.  */
21755 	      if (DECL_RTL_SET_P (v))
21756 		make_decl_rtl (v);
21757 	    }
21758 	  C_DECL_THREADPRIVATE_P (v) = 1;
21759 	}
21760     }
21761 
21762   c_parser_skip_to_pragma_eol (parser);
21763 }
21764 
21765 /* Parse a transaction attribute (GCC Extension).
21766 
21767    transaction-attribute:
21768      gnu-attributes
21769      attribute-specifier
21770 */
21771 
21772 static tree
c_parser_transaction_attributes(c_parser * parser)21773 c_parser_transaction_attributes (c_parser *parser)
21774 {
21775   if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
21776     return c_parser_gnu_attributes (parser);
21777 
21778   if (!c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
21779     return NULL_TREE;
21780   return c_parser_std_attribute_specifier (parser, true);
21781 }
21782 
21783 /* Parse a __transaction_atomic or __transaction_relaxed statement
21784    (GCC Extension).
21785 
21786    transaction-statement:
21787      __transaction_atomic transaction-attribute[opt] compound-statement
21788      __transaction_relaxed compound-statement
21789 
21790    Note that the only valid attribute is: "outer".
21791 */
21792 
21793 static tree
c_parser_transaction(c_parser * parser,enum rid keyword)21794 c_parser_transaction (c_parser *parser, enum rid keyword)
21795 {
21796   unsigned int old_in = parser->in_transaction;
21797   unsigned int this_in = 1, new_in;
21798   location_t loc = c_parser_peek_token (parser)->location;
21799   tree stmt, attrs;
21800 
21801   gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
21802       || keyword == RID_TRANSACTION_RELAXED)
21803       && c_parser_next_token_is_keyword (parser, keyword));
21804   c_parser_consume_token (parser);
21805 
21806   if (keyword == RID_TRANSACTION_RELAXED)
21807     this_in |= TM_STMT_ATTR_RELAXED;
21808   else
21809     {
21810       attrs = c_parser_transaction_attributes (parser);
21811       if (attrs)
21812 	this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
21813     }
21814 
21815   /* Keep track if we're in the lexical scope of an outer transaction.  */
21816   new_in = this_in | (old_in & TM_STMT_ATTR_OUTER);
21817 
21818   parser->in_transaction = new_in;
21819   stmt = c_parser_compound_statement (parser);
21820   parser->in_transaction = old_in;
21821 
21822   if (flag_tm)
21823     stmt = c_finish_transaction (loc, stmt, this_in);
21824   else
21825     error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
21826 	"%<__transaction_atomic%> without transactional memory support enabled"
21827 	: "%<__transaction_relaxed %> "
21828 	"without transactional memory support enabled"));
21829 
21830   return stmt;
21831 }
21832 
21833 /* Parse a __transaction_atomic or __transaction_relaxed expression
21834    (GCC Extension).
21835 
21836    transaction-expression:
21837      __transaction_atomic ( expression )
21838      __transaction_relaxed ( expression )
21839 */
21840 
21841 static struct c_expr
c_parser_transaction_expression(c_parser * parser,enum rid keyword)21842 c_parser_transaction_expression (c_parser *parser, enum rid keyword)
21843 {
21844   struct c_expr ret;
21845   unsigned int old_in = parser->in_transaction;
21846   unsigned int this_in = 1;
21847   location_t loc = c_parser_peek_token (parser)->location;
21848   tree attrs;
21849 
21850   gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
21851       || keyword == RID_TRANSACTION_RELAXED)
21852       && c_parser_next_token_is_keyword (parser, keyword));
21853   c_parser_consume_token (parser);
21854 
21855   if (keyword == RID_TRANSACTION_RELAXED)
21856     this_in |= TM_STMT_ATTR_RELAXED;
21857   else
21858     {
21859       attrs = c_parser_transaction_attributes (parser);
21860       if (attrs)
21861 	this_in |= parse_tm_stmt_attr (attrs, 0);
21862     }
21863 
21864   parser->in_transaction = this_in;
21865   matching_parens parens;
21866   if (parens.require_open (parser))
21867     {
21868       tree expr = c_parser_expression (parser).value;
21869       ret.original_type = TREE_TYPE (expr);
21870       ret.value = build1 (TRANSACTION_EXPR, ret.original_type, expr);
21871       if (this_in & TM_STMT_ATTR_RELAXED)
21872 	TRANSACTION_EXPR_RELAXED (ret.value) = 1;
21873       SET_EXPR_LOCATION (ret.value, loc);
21874       ret.original_code = TRANSACTION_EXPR;
21875       if (!parens.require_close (parser))
21876 	{
21877 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
21878 	  goto error;
21879 	}
21880     }
21881   else
21882     {
21883      error:
21884       ret.set_error ();
21885       ret.original_code = ERROR_MARK;
21886       ret.original_type = NULL;
21887     }
21888   parser->in_transaction = old_in;
21889 
21890   if (!flag_tm)
21891     error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
21892 	"%<__transaction_atomic%> without transactional memory support enabled"
21893 	: "%<__transaction_relaxed %> "
21894 	"without transactional memory support enabled"));
21895 
21896   set_c_expr_source_range (&ret, loc, loc);
21897 
21898   return ret;
21899 }
21900 
21901 /* Parse a __transaction_cancel statement (GCC Extension).
21902 
21903    transaction-cancel-statement:
21904      __transaction_cancel transaction-attribute[opt] ;
21905 
21906    Note that the only valid attribute is "outer".
21907 */
21908 
21909 static tree
c_parser_transaction_cancel(c_parser * parser)21910 c_parser_transaction_cancel (c_parser *parser)
21911 {
21912   location_t loc = c_parser_peek_token (parser)->location;
21913   tree attrs;
21914   bool is_outer = false;
21915 
21916   gcc_assert (c_parser_next_token_is_keyword (parser, RID_TRANSACTION_CANCEL));
21917   c_parser_consume_token (parser);
21918 
21919   attrs = c_parser_transaction_attributes (parser);
21920   if (attrs)
21921     is_outer = (parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER) != 0);
21922 
21923   if (!flag_tm)
21924     {
21925       error_at (loc, "%<__transaction_cancel%> without "
21926 		"transactional memory support enabled");
21927       goto ret_error;
21928     }
21929   else if (parser->in_transaction & TM_STMT_ATTR_RELAXED)
21930     {
21931       error_at (loc, "%<__transaction_cancel%> within a "
21932 		"%<__transaction_relaxed%>");
21933       goto ret_error;
21934     }
21935   else if (is_outer)
21936     {
21937       if ((parser->in_transaction & TM_STMT_ATTR_OUTER) == 0
21938 	  && !is_tm_may_cancel_outer (current_function_decl))
21939 	{
21940 	  error_at (loc, "outer %<__transaction_cancel%> not "
21941 		    "within outer %<__transaction_atomic%> or "
21942 		    "a %<transaction_may_cancel_outer%> function");
21943 	  goto ret_error;
21944 	}
21945     }
21946   else if (parser->in_transaction == 0)
21947     {
21948       error_at (loc, "%<__transaction_cancel%> not within "
21949 		"%<__transaction_atomic%>");
21950       goto ret_error;
21951     }
21952 
21953   return add_stmt (build_tm_abort_call (loc, is_outer));
21954 
21955  ret_error:
21956   return build1 (NOP_EXPR, void_type_node, error_mark_node);
21957 }
21958 
21959 /* Parse a single source file.  */
21960 
21961 void
c_parse_file(void)21962 c_parse_file (void)
21963 {
21964   /* Use local storage to begin.  If the first token is a pragma, parse it.
21965      If it is #pragma GCC pch_preprocess, then this will load a PCH file
21966      which will cause garbage collection.  */
21967   c_parser tparser;
21968 
21969   memset (&tparser, 0, sizeof tparser);
21970   tparser.translate_strings_p = true;
21971   tparser.tokens = &tparser.tokens_buf[0];
21972   the_parser = &tparser;
21973 
21974   if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS)
21975     c_parser_pragma_pch_preprocess (&tparser);
21976   else
21977     c_common_no_more_pch ();
21978 
21979   the_parser = ggc_alloc<c_parser> ();
21980   *the_parser = tparser;
21981   if (tparser.tokens == &tparser.tokens_buf[0])
21982     the_parser->tokens = &the_parser->tokens_buf[0];
21983 
21984   /* Initialize EH, if we've been told to do so.  */
21985   if (flag_exceptions)
21986     using_eh_for_cleanups ();
21987 
21988   c_parser_translation_unit (the_parser);
21989   the_parser = NULL;
21990 }
21991 
21992 /* Parse the body of a function declaration marked with "__RTL".
21993 
21994    The RTL parser works on the level of characters read from a
21995    FILE *, whereas c_parser works at the level of tokens.
21996    Square this circle by consuming all of the tokens up to and
21997    including the closing brace, recording the start/end of the RTL
21998    fragment, and reopening the file and re-reading the relevant
21999    lines within the RTL parser.
22000 
22001    This requires the opening and closing braces of the C function
22002    to be on separate lines from the RTL they wrap.
22003 
22004    Take ownership of START_WITH_PASS, if non-NULL.  */
22005 
22006 location_t
c_parser_parse_rtl_body(c_parser * parser,char * start_with_pass)22007 c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass)
22008 {
22009   if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
22010     {
22011       free (start_with_pass);
22012       return c_parser_peek_token (parser)->location;
22013     }
22014 
22015   location_t start_loc = c_parser_peek_token (parser)->location;
22016 
22017   /* Consume all tokens, up to the closing brace, handling
22018      matching pairs of braces in the rtl dump.  */
22019   int num_open_braces = 1;
22020   while (1)
22021     {
22022       switch (c_parser_peek_token (parser)->type)
22023 	{
22024 	case CPP_OPEN_BRACE:
22025 	  num_open_braces++;
22026 	  break;
22027 	case CPP_CLOSE_BRACE:
22028 	  if (--num_open_braces == 0)
22029 	    goto found_closing_brace;
22030 	  break;
22031 	case CPP_EOF:
22032 	  error_at (start_loc, "no closing brace");
22033 	  free (start_with_pass);
22034 	  return c_parser_peek_token (parser)->location;
22035 	default:
22036 	  break;
22037 	}
22038       c_parser_consume_token (parser);
22039     }
22040 
22041  found_closing_brace:
22042   /* At the closing brace; record its location.  */
22043   location_t end_loc = c_parser_peek_token (parser)->location;
22044 
22045   /* Consume the closing brace.  */
22046   c_parser_consume_token (parser);
22047 
22048   /* Invoke the RTL parser.  */
22049   if (!read_rtl_function_body_from_file_range (start_loc, end_loc))
22050     {
22051       free (start_with_pass);
22052       return end_loc;
22053     }
22054 
22055  /*  Run the backend on the cfun created above, transferring ownership of
22056      START_WITH_PASS.  */
22057   run_rtl_passes (start_with_pass);
22058   return end_loc;
22059 }
22060 
22061 #include "gt-c-c-parser.h"
22062