]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/c/c-parser.cc
602e0235f2dab0f617d42041b4f14579c536eb63
[thirdparty/gcc.git] / gcc / c / c-parser.cc
1 /* Parser for C and Objective-C.
2 Copyright (C) 1987-2022 Free Software Foundation, Inc.
3
4 Parser actions based on the old Bison parser; structure somewhat
5 influenced by and fragments based on the C++ parser.
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
22
23 /* TODO:
24
25 Make sure all relevant comments, and all relevant code from all
26 actions, brought over from old parser. Verify exact correspondence
27 of syntax accepted.
28
29 Add testcases covering every input symbol in every state in old and
30 new parsers.
31
32 Include full syntax for GNU C, including erroneous cases accepted
33 with error messages, in syntax productions in comments.
34
35 Make more diagnostics in the front end generally take an explicit
36 location rather than implicitly using input_location. */
37
38 #include "config.h"
39 #define INCLUDE_MEMORY
40 #include "system.h"
41 #include "coretypes.h"
42 #include "target.h"
43 #include "function.h"
44 #include "c-tree.h"
45 #include "timevar.h"
46 #include "stringpool.h"
47 #include "cgraph.h"
48 #include "attribs.h"
49 #include "stor-layout.h"
50 #include "varasm.h"
51 #include "trans-mem.h"
52 #include "c-family/c-pragma.h"
53 #include "c-lang.h"
54 #include "c-family/c-objc.h"
55 #include "plugin.h"
56 #include "omp-general.h"
57 #include "omp-offload.h"
58 #include "builtins.h"
59 #include "gomp-constants.h"
60 #include "c-family/c-indentation.h"
61 #include "gimple-expr.h"
62 #include "context.h"
63 #include "gcc-rich-location.h"
64 #include "c-parser.h"
65 #include "gimple-parser.h"
66 #include "read-rtl-function.h"
67 #include "run-rtl-passes.h"
68 #include "intl.h"
69 #include "c-family/name-hint.h"
70 #include "tree-iterator.h"
71 #include "tree-pretty-print.h"
72 #include "memmodel.h"
73 #include "c-family/known-headers.h"
74 #include "bitmap.h"
75
76 /* We need to walk over decls with incomplete struct/union/enum types
77 after parsing the whole translation unit.
78 In finish_decl(), if the decl is static, has incomplete
79 struct/union/enum type, it is appended to incomplete_record_decls.
80 In c_parser_translation_unit(), we iterate over incomplete_record_decls
81 and report error if any of the decls are still incomplete. */
82
83 vec<tree> incomplete_record_decls;
84
85 void
86 set_c_expr_source_range (c_expr *expr,
87 location_t start, location_t finish)
88 {
89 expr->src_range.m_start = start;
90 expr->src_range.m_finish = finish;
91 if (expr->value)
92 set_source_range (expr->value, start, finish);
93 }
94
95 void
96 set_c_expr_source_range (c_expr *expr,
97 source_range src_range)
98 {
99 expr->src_range = src_range;
100 if (expr->value)
101 set_source_range (expr->value, src_range);
102 }
103
104 \f
105 /* Initialization routine for this file. */
106
107 void
108 c_parse_init (void)
109 {
110 /* The only initialization required is of the reserved word
111 identifiers. */
112 unsigned int i;
113 tree id;
114 int mask = 0;
115
116 /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in
117 the c_token structure. */
118 gcc_assert (RID_MAX <= 255);
119
120 mask |= D_CXXONLY;
121 if (!flag_isoc99)
122 mask |= D_C99;
123 if (!flag_isoc2x)
124 mask |= D_C2X;
125 if (flag_no_asm)
126 {
127 mask |= D_ASM | D_EXT;
128 if (!flag_isoc99)
129 mask |= D_EXT89;
130 if (!flag_isoc2x)
131 mask |= D_EXT11;
132 }
133 if (!c_dialect_objc ())
134 mask |= D_OBJC | D_CXX_OBJC;
135
136 ridpointers = ggc_cleared_vec_alloc<tree> ((int) RID_MAX);
137 for (i = 0; i < num_c_common_reswords; i++)
138 {
139 /* If a keyword is disabled, do not enter it into the table
140 and so create a canonical spelling that isn't a keyword. */
141 if (c_common_reswords[i].disable & mask)
142 {
143 if (warn_cxx_compat
144 && (c_common_reswords[i].disable & D_CXXWARN))
145 {
146 id = get_identifier (c_common_reswords[i].word);
147 C_SET_RID_CODE (id, RID_CXX_COMPAT_WARN);
148 C_IS_RESERVED_WORD (id) = 1;
149 }
150 continue;
151 }
152
153 id = get_identifier (c_common_reswords[i].word);
154 C_SET_RID_CODE (id, c_common_reswords[i].rid);
155 C_IS_RESERVED_WORD (id) = 1;
156 ridpointers [(int) c_common_reswords[i].rid] = id;
157 }
158
159 for (i = 0; i < NUM_INT_N_ENTS; i++)
160 {
161 /* We always create the symbols but they aren't always supported. */
162 char name[50];
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 sprintf (name, "__int%d__", int_n_data[i].bitsize);
169 id = get_identifier (name);
170 C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
171 C_IS_RESERVED_WORD (id) = 1;
172 }
173
174 if (flag_openmp)
175 {
176 id = get_identifier ("omp_all_memory");
177 C_SET_RID_CODE (id, RID_OMP_ALL_MEMORY);
178 C_IS_RESERVED_WORD (id) = 1;
179 ridpointers [RID_OMP_ALL_MEMORY] = id;
180 }
181 }
182 \f
183 /* A parser structure recording information about the state and
184 context of parsing. Includes lexer information with up to two
185 tokens of look-ahead; more are not needed for C. */
186 struct GTY(()) c_parser {
187 /* The look-ahead tokens. */
188 c_token * GTY((skip)) tokens;
189 /* Buffer for look-ahead tokens. */
190 c_token tokens_buf[4];
191 /* How many look-ahead tokens are available (0 - 4, or
192 more if parsing from pre-lexed tokens). */
193 unsigned int tokens_avail;
194 /* Raw look-ahead tokens, used only for checking in Objective-C
195 whether '[[' starts attributes. */
196 vec<c_token, va_gc> *raw_tokens;
197 /* The number of raw look-ahead tokens that have since been fully
198 lexed. */
199 unsigned int raw_tokens_used;
200 /* True if a syntax error is being recovered from; false otherwise.
201 c_parser_error sets this flag. It should clear this flag when
202 enough tokens have been consumed to recover from the error. */
203 BOOL_BITFIELD error : 1;
204 /* True if we're processing a pragma, and shouldn't automatically
205 consume CPP_PRAGMA_EOL. */
206 BOOL_BITFIELD in_pragma : 1;
207 /* True if we're parsing the outermost block of an if statement. */
208 BOOL_BITFIELD in_if_block : 1;
209 /* True if we want to lex a translated, joined string (for an
210 initial #pragma pch_preprocess). Otherwise the parser is
211 responsible for concatenating strings and translating to the
212 execution character set as needed. */
213 BOOL_BITFIELD lex_joined_string : 1;
214 /* True if, when the parser is concatenating string literals, it
215 should translate them to the execution character set (false
216 inside attributes). */
217 BOOL_BITFIELD translate_strings_p : 1;
218
219 /* Objective-C specific parser/lexer information. */
220
221 /* True if we are in a context where the Objective-C "PQ" keywords
222 are considered keywords. */
223 BOOL_BITFIELD objc_pq_context : 1;
224 /* True if we are parsing a (potential) Objective-C foreach
225 statement. This is set to true after we parsed 'for (' and while
226 we wait for 'in' or ';' to decide if it's a standard C for loop or an
227 Objective-C foreach loop. */
228 BOOL_BITFIELD objc_could_be_foreach_context : 1;
229 /* The following flag is needed to contextualize Objective-C lexical
230 analysis. In some cases (e.g., 'int NSObject;'), it is
231 undesirable to bind an identifier to an Objective-C class, even
232 if a class with that name exists. */
233 BOOL_BITFIELD objc_need_raw_identifier : 1;
234 /* Nonzero if we're processing a __transaction statement. The value
235 is 1 | TM_STMT_ATTR_*. */
236 unsigned int in_transaction : 4;
237 /* True if we are in a context where the Objective-C "Property attribute"
238 keywords are valid. */
239 BOOL_BITFIELD objc_property_attr_context : 1;
240
241 /* Whether we have just seen/constructed a string-literal. Set when
242 returning a string-literal from c_parser_string_literal. Reset
243 in consume_token. Useful when we get a parse error and see an
244 unknown token, which could have been a string-literal constant
245 macro. */
246 BOOL_BITFIELD seen_string_literal : 1;
247
248 /* Location of the last consumed token. */
249 location_t last_token_location;
250 };
251
252 /* Return a pointer to the Nth token in PARSERs tokens_buf. */
253
254 c_token *
255 c_parser_tokens_buf (c_parser *parser, unsigned n)
256 {
257 return &parser->tokens_buf[n];
258 }
259
260 /* Return the error state of PARSER. */
261
262 bool
263 c_parser_error (c_parser *parser)
264 {
265 return parser->error;
266 }
267
268 /* Set the error state of PARSER to ERR. */
269
270 void
271 c_parser_set_error (c_parser *parser, bool err)
272 {
273 parser->error = err;
274 }
275
276
277 /* The actual parser and external interface. ??? Does this need to be
278 garbage-collected? */
279
280 static GTY (()) c_parser *the_parser;
281
282 /* Read in and lex a single token, storing it in *TOKEN. If RAW,
283 context-sensitive postprocessing of the token is not done. */
284
285 static void
286 c_lex_one_token (c_parser *parser, c_token *token, bool raw = false)
287 {
288 timevar_push (TV_LEX);
289
290 if (raw || vec_safe_length (parser->raw_tokens) == 0)
291 {
292 token->type = c_lex_with_flags (&token->value, &token->location,
293 &token->flags,
294 (parser->lex_joined_string
295 ? 0 : C_LEX_STRING_NO_JOIN));
296 token->id_kind = C_ID_NONE;
297 token->keyword = RID_MAX;
298 token->pragma_kind = PRAGMA_NONE;
299 }
300 else
301 {
302 /* Use a token previously lexed as a raw look-ahead token, and
303 complete the processing on it. */
304 *token = (*parser->raw_tokens)[parser->raw_tokens_used];
305 ++parser->raw_tokens_used;
306 if (parser->raw_tokens_used == vec_safe_length (parser->raw_tokens))
307 {
308 vec_free (parser->raw_tokens);
309 parser->raw_tokens_used = 0;
310 }
311 }
312
313 if (raw)
314 goto out;
315
316 switch (token->type)
317 {
318 case CPP_NAME:
319 {
320 tree decl;
321
322 bool objc_force_identifier = parser->objc_need_raw_identifier;
323 if (c_dialect_objc ())
324 parser->objc_need_raw_identifier = false;
325
326 if (C_IS_RESERVED_WORD (token->value))
327 {
328 enum rid rid_code = C_RID_CODE (token->value);
329
330 if (rid_code == RID_CXX_COMPAT_WARN)
331 {
332 warning_at (token->location,
333 OPT_Wc___compat,
334 "identifier %qE conflicts with C++ keyword",
335 token->value);
336 }
337 else if (rid_code >= RID_FIRST_ADDR_SPACE
338 && rid_code <= RID_LAST_ADDR_SPACE)
339 {
340 addr_space_t as;
341 as = (addr_space_t) (rid_code - RID_FIRST_ADDR_SPACE);
342 targetm.addr_space.diagnose_usage (as, token->location);
343 token->id_kind = C_ID_ADDRSPACE;
344 token->keyword = rid_code;
345 break;
346 }
347 else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code))
348 {
349 /* We found an Objective-C "pq" keyword (in, out,
350 inout, bycopy, byref, oneway). They need special
351 care because the interpretation depends on the
352 context. */
353 if (parser->objc_pq_context)
354 {
355 token->type = CPP_KEYWORD;
356 token->keyword = rid_code;
357 break;
358 }
359 else if (parser->objc_could_be_foreach_context
360 && rid_code == RID_IN)
361 {
362 /* We are in Objective-C, inside a (potential)
363 foreach context (which means after having
364 parsed 'for (', but before having parsed ';'),
365 and we found 'in'. We consider it the keyword
366 which terminates the declaration at the
367 beginning of a foreach-statement. Note that
368 this means you can't use 'in' for anything else
369 in that context; in particular, in Objective-C
370 you can't use 'in' as the name of the running
371 variable in a C for loop. We could potentially
372 try to add code here to disambiguate, but it
373 seems a reasonable limitation. */
374 token->type = CPP_KEYWORD;
375 token->keyword = rid_code;
376 break;
377 }
378 /* Else, "pq" keywords outside of the "pq" context are
379 not keywords, and we fall through to the code for
380 normal tokens. */
381 }
382 else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code))
383 {
384 /* We found an Objective-C "property attribute"
385 keyword (getter, setter, readonly, etc). These are
386 only valid in the property context. */
387 if (parser->objc_property_attr_context)
388 {
389 token->type = CPP_KEYWORD;
390 token->keyword = rid_code;
391 break;
392 }
393 /* Else they are not special keywords.
394 */
395 }
396 else if (c_dialect_objc ()
397 && (OBJC_IS_AT_KEYWORD (rid_code)
398 || OBJC_IS_CXX_KEYWORD (rid_code)))
399 {
400 /* We found one of the Objective-C "@" keywords (defs,
401 selector, synchronized, etc) or one of the
402 Objective-C "cxx" keywords (class, private,
403 protected, public, try, catch, throw) without a
404 preceding '@' sign. Do nothing and fall through to
405 the code for normal tokens (in C++ we would still
406 consider the CXX ones keywords, but not in C). */
407 ;
408 }
409 else
410 {
411 token->type = CPP_KEYWORD;
412 token->keyword = rid_code;
413 break;
414 }
415 }
416
417 decl = lookup_name (token->value);
418 if (decl)
419 {
420 if (TREE_CODE (decl) == TYPE_DECL)
421 {
422 token->id_kind = C_ID_TYPENAME;
423 break;
424 }
425 }
426 else if (c_dialect_objc ())
427 {
428 tree objc_interface_decl = objc_is_class_name (token->value);
429 /* Objective-C class names are in the same namespace as
430 variables and typedefs, and hence are shadowed by local
431 declarations. */
432 if (objc_interface_decl
433 && (!objc_force_identifier || global_bindings_p ()))
434 {
435 token->value = objc_interface_decl;
436 token->id_kind = C_ID_CLASSNAME;
437 break;
438 }
439 }
440 token->id_kind = C_ID_ID;
441 }
442 break;
443 case CPP_AT_NAME:
444 /* This only happens in Objective-C; it must be a keyword. */
445 token->type = CPP_KEYWORD;
446 switch (C_RID_CODE (token->value))
447 {
448 /* Replace 'class' with '@class', 'private' with '@private',
449 etc. This prevents confusion with the C++ keyword
450 'class', and makes the tokens consistent with other
451 Objective-C 'AT' keywords. For example '@class' is
452 reported as RID_AT_CLASS which is consistent with
453 '@synchronized', which is reported as
454 RID_AT_SYNCHRONIZED.
455 */
456 case RID_CLASS: token->keyword = RID_AT_CLASS; break;
457 case RID_PRIVATE: token->keyword = RID_AT_PRIVATE; break;
458 case RID_PROTECTED: token->keyword = RID_AT_PROTECTED; break;
459 case RID_PUBLIC: token->keyword = RID_AT_PUBLIC; break;
460 case RID_THROW: token->keyword = RID_AT_THROW; break;
461 case RID_TRY: token->keyword = RID_AT_TRY; break;
462 case RID_CATCH: token->keyword = RID_AT_CATCH; break;
463 case RID_SYNCHRONIZED: token->keyword = RID_AT_SYNCHRONIZED; break;
464 default: token->keyword = C_RID_CODE (token->value);
465 }
466 break;
467 case CPP_COLON:
468 case CPP_COMMA:
469 case CPP_CLOSE_PAREN:
470 case CPP_SEMICOLON:
471 /* These tokens may affect the interpretation of any identifiers
472 following, if doing Objective-C. */
473 if (c_dialect_objc ())
474 parser->objc_need_raw_identifier = false;
475 break;
476 case CPP_PRAGMA:
477 /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */
478 token->pragma_kind = (enum pragma_kind) TREE_INT_CST_LOW (token->value);
479 token->value = NULL;
480 break;
481 default:
482 break;
483 }
484 out:
485 timevar_pop (TV_LEX);
486 }
487
488 /* Return a pointer to the next token from PARSER, reading it in if
489 necessary. */
490
491 c_token *
492 c_parser_peek_token (c_parser *parser)
493 {
494 if (parser->tokens_avail == 0)
495 {
496 c_lex_one_token (parser, &parser->tokens[0]);
497 parser->tokens_avail = 1;
498 }
499 return &parser->tokens[0];
500 }
501
502 /* Return a pointer to the next-but-one token from PARSER, reading it
503 in if necessary. The next token is already read in. */
504
505 c_token *
506 c_parser_peek_2nd_token (c_parser *parser)
507 {
508 if (parser->tokens_avail >= 2)
509 return &parser->tokens[1];
510 gcc_assert (parser->tokens_avail == 1);
511 gcc_assert (parser->tokens[0].type != CPP_EOF);
512 gcc_assert (parser->tokens[0].type != CPP_PRAGMA_EOL);
513 c_lex_one_token (parser, &parser->tokens[1]);
514 parser->tokens_avail = 2;
515 return &parser->tokens[1];
516 }
517
518 /* Return a pointer to the Nth token from PARSER, reading it
519 in if necessary. The N-1th token is already read in. */
520
521 c_token *
522 c_parser_peek_nth_token (c_parser *parser, unsigned int n)
523 {
524 /* N is 1-based, not zero-based. */
525 gcc_assert (n > 0);
526
527 if (parser->tokens_avail >= n)
528 return &parser->tokens[n - 1];
529 gcc_assert (parser->tokens_avail == n - 1);
530 c_lex_one_token (parser, &parser->tokens[n - 1]);
531 parser->tokens_avail = n;
532 return &parser->tokens[n - 1];
533 }
534
535 /* Return a pointer to the Nth token from PARSER, reading it in as a
536 raw look-ahead token if necessary. The N-1th token is already read
537 in. Raw look-ahead tokens remain available for when the non-raw
538 functions above are called. */
539
540 c_token *
541 c_parser_peek_nth_token_raw (c_parser *parser, unsigned int n)
542 {
543 /* N is 1-based, not zero-based. */
544 gcc_assert (n > 0);
545
546 if (parser->tokens_avail >= n)
547 return &parser->tokens[n - 1];
548 unsigned int raw_len = vec_safe_length (parser->raw_tokens);
549 unsigned int raw_avail
550 = parser->tokens_avail + raw_len - parser->raw_tokens_used;
551 gcc_assert (raw_avail >= n - 1);
552 if (raw_avail >= n)
553 return &(*parser->raw_tokens)[parser->raw_tokens_used
554 + n - 1 - parser->tokens_avail];
555 vec_safe_reserve (parser->raw_tokens, 1);
556 parser->raw_tokens->quick_grow (raw_len + 1);
557 c_lex_one_token (parser, &(*parser->raw_tokens)[raw_len], true);
558 return &(*parser->raw_tokens)[raw_len];
559 }
560
561 bool
562 c_keyword_starts_typename (enum rid keyword)
563 {
564 switch (keyword)
565 {
566 case RID_UNSIGNED:
567 case RID_LONG:
568 case RID_SHORT:
569 case RID_SIGNED:
570 case RID_COMPLEX:
571 case RID_INT:
572 case RID_CHAR:
573 case RID_FLOAT:
574 case RID_DOUBLE:
575 case RID_VOID:
576 case RID_DFLOAT32:
577 case RID_DFLOAT64:
578 case RID_DFLOAT128:
579 CASE_RID_FLOATN_NX:
580 case RID_BOOL:
581 case RID_ENUM:
582 case RID_STRUCT:
583 case RID_UNION:
584 case RID_TYPEOF:
585 case RID_TYPEOF_UNQUAL:
586 case RID_CONST:
587 case RID_ATOMIC:
588 case RID_VOLATILE:
589 case RID_RESTRICT:
590 case RID_ATTRIBUTE:
591 case RID_FRACT:
592 case RID_ACCUM:
593 case RID_SAT:
594 case RID_AUTO_TYPE:
595 case RID_ALIGNAS:
596 return true;
597 default:
598 if (keyword >= RID_FIRST_INT_N
599 && keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
600 && int_n_enabled_p[keyword - RID_FIRST_INT_N])
601 return true;
602 return false;
603 }
604 }
605
606 /* Return true if TOKEN can start a type name,
607 false otherwise. */
608 bool
609 c_token_starts_typename (c_token *token)
610 {
611 switch (token->type)
612 {
613 case CPP_NAME:
614 switch (token->id_kind)
615 {
616 case C_ID_ID:
617 return false;
618 case C_ID_ADDRSPACE:
619 return true;
620 case C_ID_TYPENAME:
621 return true;
622 case C_ID_CLASSNAME:
623 gcc_assert (c_dialect_objc ());
624 return true;
625 default:
626 gcc_unreachable ();
627 }
628 case CPP_KEYWORD:
629 return c_keyword_starts_typename (token->keyword);
630 case CPP_LESS:
631 if (c_dialect_objc ())
632 return true;
633 return false;
634 default:
635 return false;
636 }
637 }
638
639 /* Return true if the next token from PARSER can start a type name,
640 false otherwise. LA specifies how to do lookahead in order to
641 detect unknown type names. If unsure, pick CLA_PREFER_ID. */
642
643 static inline bool
644 c_parser_next_tokens_start_typename (c_parser *parser, enum c_lookahead_kind la)
645 {
646 c_token *token = c_parser_peek_token (parser);
647 if (c_token_starts_typename (token))
648 return true;
649
650 /* Try a bit harder to detect an unknown typename. */
651 if (la != cla_prefer_id
652 && token->type == CPP_NAME
653 && token->id_kind == C_ID_ID
654
655 /* Do not try too hard when we could have "object in array". */
656 && !parser->objc_could_be_foreach_context
657
658 && (la == cla_prefer_type
659 || c_parser_peek_2nd_token (parser)->type == CPP_NAME
660 || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
661
662 /* Only unknown identifiers. */
663 && !lookup_name (token->value))
664 return true;
665
666 return false;
667 }
668
669 /* Return true if TOKEN, after an open parenthesis, can start a
670 compound literal (either a storage class specifier allowed in that
671 context, or a type name), false otherwise. */
672 static bool
673 c_token_starts_compound_literal (c_token *token)
674 {
675 switch (token->type)
676 {
677 case CPP_KEYWORD:
678 switch (token->keyword)
679 {
680 case RID_REGISTER:
681 case RID_STATIC:
682 case RID_THREAD:
683 return true;
684 default:
685 break;
686 }
687 /* Fall through. */
688 default:
689 return c_token_starts_typename (token);
690 }
691 }
692
693 /* Return true if TOKEN is a type qualifier, false otherwise. */
694 static bool
695 c_token_is_qualifier (c_token *token)
696 {
697 switch (token->type)
698 {
699 case CPP_NAME:
700 switch (token->id_kind)
701 {
702 case C_ID_ADDRSPACE:
703 return true;
704 default:
705 return false;
706 }
707 case CPP_KEYWORD:
708 switch (token->keyword)
709 {
710 case RID_CONST:
711 case RID_VOLATILE:
712 case RID_RESTRICT:
713 case RID_ATTRIBUTE:
714 case RID_ATOMIC:
715 return true;
716 default:
717 return false;
718 }
719 case CPP_LESS:
720 return false;
721 default:
722 gcc_unreachable ();
723 }
724 }
725
726 /* Return true if the next token from PARSER is a type qualifier,
727 false otherwise. */
728 static inline bool
729 c_parser_next_token_is_qualifier (c_parser *parser)
730 {
731 c_token *token = c_parser_peek_token (parser);
732 return c_token_is_qualifier (token);
733 }
734
735 /* Return true if TOKEN can start declaration specifiers (not
736 including standard attributes), false otherwise. */
737 static bool
738 c_token_starts_declspecs (c_token *token)
739 {
740 switch (token->type)
741 {
742 case CPP_NAME:
743 switch (token->id_kind)
744 {
745 case C_ID_ID:
746 return false;
747 case C_ID_ADDRSPACE:
748 return true;
749 case C_ID_TYPENAME:
750 return true;
751 case C_ID_CLASSNAME:
752 gcc_assert (c_dialect_objc ());
753 return true;
754 default:
755 gcc_unreachable ();
756 }
757 case CPP_KEYWORD:
758 switch (token->keyword)
759 {
760 case RID_STATIC:
761 case RID_EXTERN:
762 case RID_REGISTER:
763 case RID_TYPEDEF:
764 case RID_INLINE:
765 case RID_NORETURN:
766 case RID_AUTO:
767 case RID_THREAD:
768 case RID_UNSIGNED:
769 case RID_LONG:
770 case RID_SHORT:
771 case RID_SIGNED:
772 case RID_COMPLEX:
773 case RID_INT:
774 case RID_CHAR:
775 case RID_FLOAT:
776 case RID_DOUBLE:
777 case RID_VOID:
778 case RID_DFLOAT32:
779 case RID_DFLOAT64:
780 case RID_DFLOAT128:
781 CASE_RID_FLOATN_NX:
782 case RID_BOOL:
783 case RID_ENUM:
784 case RID_STRUCT:
785 case RID_UNION:
786 case RID_TYPEOF:
787 case RID_TYPEOF_UNQUAL:
788 case RID_CONST:
789 case RID_VOLATILE:
790 case RID_RESTRICT:
791 case RID_ATTRIBUTE:
792 case RID_FRACT:
793 case RID_ACCUM:
794 case RID_SAT:
795 case RID_ALIGNAS:
796 case RID_ATOMIC:
797 case RID_AUTO_TYPE:
798 return true;
799 default:
800 if (token->keyword >= RID_FIRST_INT_N
801 && token->keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
802 && int_n_enabled_p[token->keyword - RID_FIRST_INT_N])
803 return true;
804 return false;
805 }
806 case CPP_LESS:
807 if (c_dialect_objc ())
808 return true;
809 return false;
810 default:
811 return false;
812 }
813 }
814
815
816 /* Return true if TOKEN can start declaration specifiers (not
817 including standard attributes) or a static assertion, false
818 otherwise. */
819 static bool
820 c_token_starts_declaration (c_token *token)
821 {
822 if (c_token_starts_declspecs (token)
823 || token->keyword == RID_STATIC_ASSERT)
824 return true;
825 else
826 return false;
827 }
828
829 /* Return true if the next token from PARSER can start declaration
830 specifiers (not including standard attributes), false
831 otherwise. */
832 bool
833 c_parser_next_token_starts_declspecs (c_parser *parser)
834 {
835 c_token *token = c_parser_peek_token (parser);
836
837 /* In Objective-C, a classname normally starts a declspecs unless it
838 is immediately followed by a dot. In that case, it is the
839 Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
840 setter/getter on the class. c_token_starts_declspecs() can't
841 differentiate between the two cases because it only checks the
842 current token, so we have a special check here. */
843 if (c_dialect_objc ()
844 && token->type == CPP_NAME
845 && token->id_kind == C_ID_CLASSNAME
846 && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
847 return false;
848
849 return c_token_starts_declspecs (token);
850 }
851
852 /* Return true if the next tokens from PARSER can start declaration
853 specifiers (not including standard attributes) or a static
854 assertion, false otherwise. */
855 bool
856 c_parser_next_tokens_start_declaration (c_parser *parser)
857 {
858 c_token *token = c_parser_peek_token (parser);
859
860 /* Same as above. */
861 if (c_dialect_objc ()
862 && token->type == CPP_NAME
863 && token->id_kind == C_ID_CLASSNAME
864 && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
865 return false;
866
867 /* Labels do not start declarations. */
868 if (token->type == CPP_NAME
869 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
870 return false;
871
872 if (c_token_starts_declaration (token))
873 return true;
874
875 if (c_parser_next_tokens_start_typename (parser, cla_nonabstract_decl))
876 return true;
877
878 return false;
879 }
880
881 /* Consume the next token from PARSER. */
882
883 void
884 c_parser_consume_token (c_parser *parser)
885 {
886 gcc_assert (parser->tokens_avail >= 1);
887 gcc_assert (parser->tokens[0].type != CPP_EOF);
888 gcc_assert (!parser->in_pragma || parser->tokens[0].type != CPP_PRAGMA_EOL);
889 gcc_assert (parser->error || parser->tokens[0].type != CPP_PRAGMA);
890 parser->last_token_location = parser->tokens[0].location;
891 if (parser->tokens != &parser->tokens_buf[0])
892 parser->tokens++;
893 else if (parser->tokens_avail >= 2)
894 {
895 parser->tokens[0] = parser->tokens[1];
896 if (parser->tokens_avail >= 3)
897 {
898 parser->tokens[1] = parser->tokens[2];
899 if (parser->tokens_avail >= 4)
900 parser->tokens[2] = parser->tokens[3];
901 }
902 }
903 parser->tokens_avail--;
904 parser->seen_string_literal = false;
905 }
906
907 /* Expect the current token to be a #pragma. Consume it and remember
908 that we've begun parsing a pragma. */
909
910 static void
911 c_parser_consume_pragma (c_parser *parser)
912 {
913 gcc_assert (!parser->in_pragma);
914 gcc_assert (parser->tokens_avail >= 1);
915 gcc_assert (parser->tokens[0].type == CPP_PRAGMA);
916 if (parser->tokens != &parser->tokens_buf[0])
917 parser->tokens++;
918 else if (parser->tokens_avail >= 2)
919 {
920 parser->tokens[0] = parser->tokens[1];
921 if (parser->tokens_avail >= 3)
922 parser->tokens[1] = parser->tokens[2];
923 }
924 parser->tokens_avail--;
925 parser->in_pragma = true;
926 }
927
928 /* Update the global input_location from TOKEN. */
929 static inline void
930 c_parser_set_source_position_from_token (c_token *token)
931 {
932 if (token->type != CPP_EOF)
933 {
934 input_location = token->location;
935 }
936 }
937
938 /* Helper function for c_parser_error.
939 Having peeked a token of kind TOK1_KIND that might signify
940 a conflict marker, peek successor tokens to determine
941 if we actually do have a conflict marker.
942 Specifically, we consider a run of 7 '<', '=' or '>' characters
943 at the start of a line as a conflict marker.
944 These come through the lexer as three pairs and a single,
945 e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<').
946 If it returns true, *OUT_LOC is written to with the location/range
947 of the marker. */
948
949 static bool
950 c_parser_peek_conflict_marker (c_parser *parser, enum cpp_ttype tok1_kind,
951 location_t *out_loc)
952 {
953 c_token *token2 = c_parser_peek_2nd_token (parser);
954 if (token2->type != tok1_kind)
955 return false;
956 c_token *token3 = c_parser_peek_nth_token (parser, 3);
957 if (token3->type != tok1_kind)
958 return false;
959 c_token *token4 = c_parser_peek_nth_token (parser, 4);
960 if (token4->type != conflict_marker_get_final_tok_kind (tok1_kind))
961 return false;
962
963 /* It must be at the start of the line. */
964 location_t start_loc = c_parser_peek_token (parser)->location;
965 if (LOCATION_COLUMN (start_loc) != 1)
966 return false;
967
968 /* We have a conflict marker. Construct a location of the form:
969 <<<<<<<
970 ^~~~~~~
971 with start == caret, finishing at the end of the marker. */
972 location_t finish_loc = get_finish (token4->location);
973 *out_loc = make_location (start_loc, start_loc, finish_loc);
974
975 return true;
976 }
977
978 /* Issue a diagnostic of the form
979 FILE:LINE: MESSAGE before TOKEN
980 where TOKEN is the next token in the input stream of PARSER.
981 MESSAGE (specified by the caller) is usually of the form "expected
982 OTHER-TOKEN".
983
984 Use RICHLOC as the location of the diagnostic.
985
986 Do not issue a diagnostic if still recovering from an error.
987
988 Return true iff an error was actually emitted.
989
990 ??? This is taken from the C++ parser, but building up messages in
991 this way is not i18n-friendly and some other approach should be
992 used. */
993
994 static bool
995 c_parser_error_richloc (c_parser *parser, const char *gmsgid,
996 rich_location *richloc)
997 {
998 c_token *token = c_parser_peek_token (parser);
999 if (parser->error)
1000 return false;
1001 parser->error = true;
1002 if (!gmsgid)
1003 return false;
1004
1005 /* If this is actually a conflict marker, report it as such. */
1006 if (token->type == CPP_LSHIFT
1007 || token->type == CPP_RSHIFT
1008 || token->type == CPP_EQ_EQ)
1009 {
1010 location_t loc;
1011 if (c_parser_peek_conflict_marker (parser, token->type, &loc))
1012 {
1013 error_at (loc, "version control conflict marker in file");
1014 return true;
1015 }
1016 }
1017
1018 /* If we were parsing a string-literal and there is an unknown name
1019 token right after, then check to see if that could also have been
1020 a literal string by checking the name against a list of known
1021 standard string literal constants defined in header files. If
1022 there is one, then add that as an hint to the error message. */
1023 auto_diagnostic_group d;
1024 name_hint h;
1025 if (parser->seen_string_literal && token->type == CPP_NAME)
1026 {
1027 tree name = token->value;
1028 const char *token_name = IDENTIFIER_POINTER (name);
1029 const char *header_hint
1030 = get_c_stdlib_header_for_string_macro_name (token_name);
1031 if (header_hint != NULL)
1032 h = name_hint (NULL, new suggest_missing_header (token->location,
1033 token_name,
1034 header_hint));
1035 }
1036
1037 c_parse_error (gmsgid,
1038 /* Because c_parse_error does not understand
1039 CPP_KEYWORD, keywords are treated like
1040 identifiers. */
1041 (token->type == CPP_KEYWORD ? CPP_NAME : token->type),
1042 /* ??? The C parser does not save the cpp flags of a
1043 token, we need to pass 0 here and we will not get
1044 the source spelling of some tokens but rather the
1045 canonical spelling. */
1046 token->value, /*flags=*/0, richloc);
1047 return true;
1048 }
1049
1050 /* As c_parser_error_richloc, but issue the message at the
1051 location of PARSER's next token, or at input_location
1052 if the next token is EOF. */
1053
1054 bool
1055 c_parser_error (c_parser *parser, const char *gmsgid)
1056 {
1057 c_token *token = c_parser_peek_token (parser);
1058 c_parser_set_source_position_from_token (token);
1059 rich_location richloc (line_table, input_location);
1060 return c_parser_error_richloc (parser, gmsgid, &richloc);
1061 }
1062
1063 /* Some tokens naturally come in pairs e.g.'(' and ')'.
1064 This class is for tracking such a matching pair of symbols.
1065 In particular, it tracks the location of the first token,
1066 so that if the second token is missing, we can highlight the
1067 location of the first token when notifying the user about the
1068 problem. */
1069
1070 template <typename traits_t>
1071 class token_pair
1072 {
1073 public:
1074 /* token_pair's ctor. */
1075 token_pair () : m_open_loc (UNKNOWN_LOCATION) {}
1076
1077 /* If the next token is the opening symbol for this pair, consume it and
1078 return true.
1079 Otherwise, issue an error and return false.
1080 In either case, record the location of the opening token. */
1081
1082 bool require_open (c_parser *parser)
1083 {
1084 c_token *token = c_parser_peek_token (parser);
1085 if (token)
1086 m_open_loc = token->location;
1087
1088 return c_parser_require (parser, traits_t::open_token_type,
1089 traits_t::open_gmsgid);
1090 }
1091
1092 /* Consume the next token from PARSER, recording its location as
1093 that of the opening token within the pair. */
1094
1095 void consume_open (c_parser *parser)
1096 {
1097 c_token *token = c_parser_peek_token (parser);
1098 gcc_assert (token->type == traits_t::open_token_type);
1099 m_open_loc = token->location;
1100 c_parser_consume_token (parser);
1101 }
1102
1103 /* If the next token is the closing symbol for this pair, consume it
1104 and return true.
1105 Otherwise, issue an error, highlighting the location of the
1106 corresponding opening token, and return false. */
1107
1108 bool require_close (c_parser *parser) const
1109 {
1110 return c_parser_require (parser, traits_t::close_token_type,
1111 traits_t::close_gmsgid, m_open_loc);
1112 }
1113
1114 /* Like token_pair::require_close, except that tokens will be skipped
1115 until the desired token is found. An error message is still produced
1116 if the next token is not as expected. */
1117
1118 void skip_until_found_close (c_parser *parser) const
1119 {
1120 c_parser_skip_until_found (parser, traits_t::close_token_type,
1121 traits_t::close_gmsgid, m_open_loc);
1122 }
1123
1124 private:
1125 location_t m_open_loc;
1126 };
1127
1128 /* Traits for token_pair<T> for tracking matching pairs of parentheses. */
1129
1130 struct matching_paren_traits
1131 {
1132 static const enum cpp_ttype open_token_type = CPP_OPEN_PAREN;
1133 static const char * const open_gmsgid;
1134 static const enum cpp_ttype close_token_type = CPP_CLOSE_PAREN;
1135 static const char * const close_gmsgid;
1136 };
1137
1138 const char * const matching_paren_traits::open_gmsgid = "expected %<(%>";
1139 const char * const matching_paren_traits::close_gmsgid = "expected %<)%>";
1140
1141 /* "matching_parens" is a token_pair<T> class for tracking matching
1142 pairs of parentheses. */
1143
1144 typedef token_pair<matching_paren_traits> matching_parens;
1145
1146 /* Traits for token_pair<T> for tracking matching pairs of braces. */
1147
1148 struct matching_brace_traits
1149 {
1150 static const enum cpp_ttype open_token_type = CPP_OPEN_BRACE;
1151 static const char * const open_gmsgid;
1152 static const enum cpp_ttype close_token_type = CPP_CLOSE_BRACE;
1153 static const char * const close_gmsgid;
1154 };
1155
1156 const char * const matching_brace_traits::open_gmsgid = "expected %<{%>";
1157 const char * const matching_brace_traits::close_gmsgid = "expected %<}%>";
1158
1159 /* "matching_braces" is a token_pair<T> class for tracking matching
1160 pairs of braces. */
1161
1162 typedef token_pair<matching_brace_traits> matching_braces;
1163
1164 /* Get a description of the matching symbol to TYPE e.g. "(" for
1165 CPP_CLOSE_PAREN. */
1166
1167 static const char *
1168 get_matching_symbol (enum cpp_ttype type)
1169 {
1170 switch (type)
1171 {
1172 default:
1173 gcc_unreachable ();
1174 case CPP_CLOSE_PAREN:
1175 return "(";
1176 case CPP_CLOSE_BRACE:
1177 return "{";
1178 }
1179 }
1180
1181 /* If the next token is of the indicated TYPE, consume it. Otherwise,
1182 issue the error MSGID. If MSGID is NULL then a message has already
1183 been produced and no message will be produced this time. Returns
1184 true if found, false otherwise.
1185
1186 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1187 within any error as the location of an "opening" token matching
1188 the close token TYPE (e.g. the location of the '(' when TYPE is
1189 CPP_CLOSE_PAREN).
1190
1191 If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly
1192 one type (e.g. "expected %<)%>") and thus it may be reasonable to
1193 attempt to generate a fix-it hint for the problem.
1194 Otherwise msgid describes multiple token types (e.g.
1195 "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to
1196 generate a fix-it hint. */
1197
1198 bool
1199 c_parser_require (c_parser *parser,
1200 enum cpp_ttype type,
1201 const char *msgid,
1202 location_t matching_location,
1203 bool type_is_unique)
1204 {
1205 if (c_parser_next_token_is (parser, type))
1206 {
1207 c_parser_consume_token (parser);
1208 return true;
1209 }
1210 else
1211 {
1212 location_t next_token_loc = c_parser_peek_token (parser)->location;
1213 gcc_rich_location richloc (next_token_loc);
1214
1215 /* Potentially supply a fix-it hint, suggesting to add the
1216 missing token immediately after the *previous* token.
1217 This may move the primary location within richloc. */
1218 if (!parser->error && type_is_unique)
1219 maybe_suggest_missing_token_insertion (&richloc, type,
1220 parser->last_token_location);
1221
1222 /* If matching_location != UNKNOWN_LOCATION, highlight it.
1223 Attempt to consolidate diagnostics by printing it as a
1224 secondary range within the main diagnostic. */
1225 bool added_matching_location = false;
1226 if (matching_location != UNKNOWN_LOCATION)
1227 added_matching_location
1228 = richloc.add_location_if_nearby (matching_location);
1229
1230 if (c_parser_error_richloc (parser, msgid, &richloc))
1231 /* If we weren't able to consolidate matching_location, then
1232 print it as a secondary diagnostic. */
1233 if (matching_location != UNKNOWN_LOCATION && !added_matching_location)
1234 inform (matching_location, "to match this %qs",
1235 get_matching_symbol (type));
1236
1237 return false;
1238 }
1239 }
1240
1241 /* If the next token is the indicated keyword, consume it. Otherwise,
1242 issue the error MSGID. Returns true if found, false otherwise. */
1243
1244 static bool
1245 c_parser_require_keyword (c_parser *parser,
1246 enum rid keyword,
1247 const char *msgid)
1248 {
1249 if (c_parser_next_token_is_keyword (parser, keyword))
1250 {
1251 c_parser_consume_token (parser);
1252 return true;
1253 }
1254 else
1255 {
1256 c_parser_error (parser, msgid);
1257 return false;
1258 }
1259 }
1260
1261 /* Like c_parser_require, except that tokens will be skipped until the
1262 desired token is found. An error message is still produced if the
1263 next token is not as expected. If MSGID is NULL then a message has
1264 already been produced and no message will be produced this
1265 time.
1266
1267 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1268 within any error as the location of an "opening" token matching
1269 the close token TYPE (e.g. the location of the '(' when TYPE is
1270 CPP_CLOSE_PAREN). */
1271
1272 void
1273 c_parser_skip_until_found (c_parser *parser,
1274 enum cpp_ttype type,
1275 const char *msgid,
1276 location_t matching_location)
1277 {
1278 unsigned nesting_depth = 0;
1279
1280 if (c_parser_require (parser, type, msgid, matching_location))
1281 return;
1282
1283 /* Skip tokens until the desired token is found. */
1284 while (true)
1285 {
1286 /* Peek at the next token. */
1287 c_token *token = c_parser_peek_token (parser);
1288 /* If we've reached the token we want, consume it and stop. */
1289 if (token->type == type && !nesting_depth)
1290 {
1291 c_parser_consume_token (parser);
1292 break;
1293 }
1294
1295 /* If we've run out of tokens, stop. */
1296 if (token->type == CPP_EOF)
1297 return;
1298 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1299 return;
1300 if (token->type == CPP_OPEN_BRACE
1301 || token->type == CPP_OPEN_PAREN
1302 || token->type == CPP_OPEN_SQUARE)
1303 ++nesting_depth;
1304 else if (token->type == CPP_CLOSE_BRACE
1305 || token->type == CPP_CLOSE_PAREN
1306 || token->type == CPP_CLOSE_SQUARE)
1307 {
1308 if (nesting_depth-- == 0)
1309 break;
1310 }
1311 /* Consume this token. */
1312 c_parser_consume_token (parser);
1313 }
1314 parser->error = false;
1315 }
1316
1317 /* Skip tokens until the end of a parameter is found, but do not
1318 consume the comma, semicolon or closing delimiter. */
1319
1320 static void
1321 c_parser_skip_to_end_of_parameter (c_parser *parser)
1322 {
1323 unsigned nesting_depth = 0;
1324
1325 while (true)
1326 {
1327 c_token *token = c_parser_peek_token (parser);
1328 if ((token->type == CPP_COMMA || token->type == CPP_SEMICOLON)
1329 && !nesting_depth)
1330 break;
1331 /* If we've run out of tokens, stop. */
1332 if (token->type == CPP_EOF)
1333 return;
1334 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1335 return;
1336 if (token->type == CPP_OPEN_BRACE
1337 || token->type == CPP_OPEN_PAREN
1338 || token->type == CPP_OPEN_SQUARE)
1339 ++nesting_depth;
1340 else if (token->type == CPP_CLOSE_BRACE
1341 || token->type == CPP_CLOSE_PAREN
1342 || token->type == CPP_CLOSE_SQUARE)
1343 {
1344 if (nesting_depth-- == 0)
1345 break;
1346 }
1347 /* Consume this token. */
1348 c_parser_consume_token (parser);
1349 }
1350 parser->error = false;
1351 }
1352
1353 /* Expect to be at the end of the pragma directive and consume an
1354 end of line marker. */
1355
1356 static void
1357 c_parser_skip_to_pragma_eol (c_parser *parser, bool error_if_not_eol = true)
1358 {
1359 gcc_assert (parser->in_pragma);
1360 parser->in_pragma = false;
1361
1362 if (error_if_not_eol && c_parser_peek_token (parser)->type != CPP_PRAGMA_EOL)
1363 c_parser_error (parser, "expected end of line");
1364
1365 cpp_ttype token_type;
1366 do
1367 {
1368 c_token *token = c_parser_peek_token (parser);
1369 token_type = token->type;
1370 if (token_type == CPP_EOF)
1371 break;
1372 c_parser_consume_token (parser);
1373 }
1374 while (token_type != CPP_PRAGMA_EOL);
1375
1376 parser->error = false;
1377 }
1378
1379 /* Skip tokens until we have consumed an entire block, or until we
1380 have consumed a non-nested ';'. */
1381
1382 static void
1383 c_parser_skip_to_end_of_block_or_statement (c_parser *parser)
1384 {
1385 unsigned nesting_depth = 0;
1386 bool save_error = parser->error;
1387
1388 while (true)
1389 {
1390 c_token *token;
1391
1392 /* Peek at the next token. */
1393 token = c_parser_peek_token (parser);
1394
1395 switch (token->type)
1396 {
1397 case CPP_EOF:
1398 return;
1399
1400 case CPP_PRAGMA_EOL:
1401 if (parser->in_pragma)
1402 return;
1403 break;
1404
1405 case CPP_SEMICOLON:
1406 /* If the next token is a ';', we have reached the
1407 end of the statement. */
1408 if (!nesting_depth)
1409 {
1410 /* Consume the ';'. */
1411 c_parser_consume_token (parser);
1412 goto finished;
1413 }
1414 break;
1415
1416 case CPP_CLOSE_BRACE:
1417 /* If the next token is a non-nested '}', then we have
1418 reached the end of the current block. */
1419 if (nesting_depth == 0 || --nesting_depth == 0)
1420 {
1421 c_parser_consume_token (parser);
1422 goto finished;
1423 }
1424 break;
1425
1426 case CPP_OPEN_BRACE:
1427 /* If it the next token is a '{', then we are entering a new
1428 block. Consume the entire block. */
1429 ++nesting_depth;
1430 break;
1431
1432 case CPP_PRAGMA:
1433 /* If we see a pragma, consume the whole thing at once. We
1434 have some safeguards against consuming pragmas willy-nilly.
1435 Normally, we'd expect to be here with parser->error set,
1436 which disables these safeguards. But it's possible to get
1437 here for secondary error recovery, after parser->error has
1438 been cleared. */
1439 c_parser_consume_pragma (parser);
1440 c_parser_skip_to_pragma_eol (parser);
1441 parser->error = save_error;
1442 continue;
1443
1444 default:
1445 break;
1446 }
1447
1448 c_parser_consume_token (parser);
1449 }
1450
1451 finished:
1452 parser->error = false;
1453 }
1454
1455 /* CPP's options (initialized by c-opts.cc). */
1456 extern cpp_options *cpp_opts;
1457
1458 /* Save the warning flags which are controlled by __extension__. */
1459
1460 static inline int
1461 disable_extension_diagnostics (void)
1462 {
1463 int ret = (pedantic
1464 | (warn_pointer_arith << 1)
1465 | (warn_traditional << 2)
1466 | (flag_iso << 3)
1467 | (warn_long_long << 4)
1468 | (warn_cxx_compat << 5)
1469 | (warn_overlength_strings << 6)
1470 /* warn_c90_c99_compat has three states: -1/0/1, so we must
1471 play tricks to properly restore it. */
1472 | ((warn_c90_c99_compat == 1) << 7)
1473 | ((warn_c90_c99_compat == -1) << 8)
1474 /* Similarly for warn_c99_c11_compat. */
1475 | ((warn_c99_c11_compat == 1) << 9)
1476 | ((warn_c99_c11_compat == -1) << 10)
1477 /* Similarly for warn_c11_c2x_compat. */
1478 | ((warn_c11_c2x_compat == 1) << 11)
1479 | ((warn_c11_c2x_compat == -1) << 12)
1480 );
1481 cpp_opts->cpp_pedantic = pedantic = 0;
1482 warn_pointer_arith = 0;
1483 cpp_opts->cpp_warn_traditional = warn_traditional = 0;
1484 flag_iso = 0;
1485 cpp_opts->cpp_warn_long_long = warn_long_long = 0;
1486 warn_cxx_compat = 0;
1487 warn_overlength_strings = 0;
1488 warn_c90_c99_compat = 0;
1489 warn_c99_c11_compat = 0;
1490 warn_c11_c2x_compat = 0;
1491 return ret;
1492 }
1493
1494 /* Restore the warning flags which are controlled by __extension__.
1495 FLAGS is the return value from disable_extension_diagnostics. */
1496
1497 static inline void
1498 restore_extension_diagnostics (int flags)
1499 {
1500 cpp_opts->cpp_pedantic = pedantic = flags & 1;
1501 warn_pointer_arith = (flags >> 1) & 1;
1502 cpp_opts->cpp_warn_traditional = warn_traditional = (flags >> 2) & 1;
1503 flag_iso = (flags >> 3) & 1;
1504 cpp_opts->cpp_warn_long_long = warn_long_long = (flags >> 4) & 1;
1505 warn_cxx_compat = (flags >> 5) & 1;
1506 warn_overlength_strings = (flags >> 6) & 1;
1507 /* See above for why is this needed. */
1508 warn_c90_c99_compat = (flags >> 7) & 1 ? 1 : ((flags >> 8) & 1 ? -1 : 0);
1509 warn_c99_c11_compat = (flags >> 9) & 1 ? 1 : ((flags >> 10) & 1 ? -1 : 0);
1510 warn_c11_c2x_compat = (flags >> 11) & 1 ? 1 : ((flags >> 12) & 1 ? -1 : 0);
1511 }
1512
1513 /* Helper data structure for parsing #pragma acc routine. */
1514 struct oacc_routine_data {
1515 bool error_seen; /* Set if error has been reported. */
1516 bool fndecl_seen; /* Set if one fn decl/definition has been seen already. */
1517 tree clauses;
1518 location_t loc;
1519 };
1520
1521 /* Used for parsing objc foreach statements. */
1522 static tree objc_foreach_break_label, objc_foreach_continue_label;
1523
1524 static bool c_parser_nth_token_starts_std_attributes (c_parser *,
1525 unsigned int);
1526 static tree c_parser_std_attribute_specifier_sequence (c_parser *);
1527 static void c_parser_external_declaration (c_parser *);
1528 static void c_parser_asm_definition (c_parser *);
1529 static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
1530 bool, bool, tree * = NULL,
1531 vec<c_token> * = NULL,
1532 bool have_attrs = false,
1533 tree attrs = NULL,
1534 struct oacc_routine_data * = NULL,
1535 bool * = NULL);
1536 static void c_parser_static_assert_declaration_no_semi (c_parser *);
1537 static void c_parser_static_assert_declaration (c_parser *);
1538 static struct c_typespec c_parser_enum_specifier (c_parser *);
1539 static struct c_typespec c_parser_struct_or_union_specifier (c_parser *);
1540 static tree c_parser_struct_declaration (c_parser *);
1541 static struct c_typespec c_parser_typeof_specifier (c_parser *);
1542 static tree c_parser_alignas_specifier (c_parser *);
1543 static struct c_declarator *c_parser_direct_declarator (c_parser *, bool,
1544 c_dtr_syn, bool *);
1545 static struct c_declarator *c_parser_direct_declarator_inner (c_parser *,
1546 bool,
1547 struct c_declarator *);
1548 static struct c_arg_info *c_parser_parms_declarator (c_parser *, bool, tree,
1549 bool);
1550 static struct c_arg_info *c_parser_parms_list_declarator (c_parser *, tree,
1551 tree, bool);
1552 static struct c_parm *c_parser_parameter_declaration (c_parser *, tree, bool);
1553 static tree c_parser_simple_asm_expr (c_parser *);
1554 static tree c_parser_gnu_attributes (c_parser *);
1555 static struct c_expr c_parser_initializer (c_parser *, tree);
1556 static struct c_expr c_parser_braced_init (c_parser *, tree, bool,
1557 struct obstack *, tree);
1558 static void c_parser_initelt (c_parser *, struct obstack *);
1559 static void c_parser_initval (c_parser *, struct c_expr *,
1560 struct obstack *);
1561 static tree c_parser_compound_statement (c_parser *, location_t * = NULL);
1562 static location_t c_parser_compound_statement_nostart (c_parser *);
1563 static void c_parser_label (c_parser *, tree);
1564 static void c_parser_statement (c_parser *, bool *, location_t * = NULL);
1565 static void c_parser_statement_after_labels (c_parser *, bool *,
1566 vec<tree> * = NULL);
1567 static tree c_parser_c99_block_statement (c_parser *, bool *,
1568 location_t * = NULL);
1569 static void c_parser_if_statement (c_parser *, bool *, vec<tree> *);
1570 static void c_parser_switch_statement (c_parser *, bool *);
1571 static void c_parser_while_statement (c_parser *, bool, unsigned short, bool *);
1572 static void c_parser_do_statement (c_parser *, bool, unsigned short);
1573 static void c_parser_for_statement (c_parser *, bool, unsigned short, bool *);
1574 static tree c_parser_asm_statement (c_parser *);
1575 static tree c_parser_asm_operands (c_parser *);
1576 static tree c_parser_asm_goto_operands (c_parser *);
1577 static tree c_parser_asm_clobbers (c_parser *);
1578 static struct c_expr c_parser_expr_no_commas (c_parser *, struct c_expr *,
1579 tree = NULL_TREE);
1580 static struct c_expr c_parser_conditional_expression (c_parser *,
1581 struct c_expr *, tree);
1582 static struct c_expr c_parser_binary_expression (c_parser *, struct c_expr *,
1583 tree);
1584 static struct c_expr c_parser_cast_expression (c_parser *, struct c_expr *);
1585 static struct c_expr c_parser_unary_expression (c_parser *);
1586 static struct c_expr c_parser_sizeof_expression (c_parser *);
1587 static struct c_expr c_parser_alignof_expression (c_parser *);
1588 static struct c_expr c_parser_postfix_expression (c_parser *);
1589 static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *,
1590 struct c_declspecs *,
1591 struct c_type_name *,
1592 location_t);
1593 static struct c_expr c_parser_postfix_expression_after_primary (c_parser *,
1594 location_t loc,
1595 struct c_expr);
1596 static tree c_parser_transaction (c_parser *, enum rid);
1597 static struct c_expr c_parser_transaction_expression (c_parser *, enum rid);
1598 static tree c_parser_transaction_cancel (c_parser *);
1599 static struct c_expr c_parser_expression (c_parser *);
1600 static struct c_expr c_parser_expression_conv (c_parser *);
1601 static vec<tree, va_gc> *c_parser_expr_list (c_parser *, bool, bool,
1602 vec<tree, va_gc> **, location_t *,
1603 tree *, vec<location_t> *,
1604 unsigned int * = NULL);
1605 static struct c_expr c_parser_has_attribute_expression (c_parser *);
1606
1607 static void c_parser_oacc_declare (c_parser *);
1608 static void c_parser_oacc_enter_exit_data (c_parser *, bool);
1609 static void c_parser_oacc_update (c_parser *);
1610 static void c_parser_omp_construct (c_parser *, bool *);
1611 static void c_parser_omp_threadprivate (c_parser *);
1612 static void c_parser_omp_barrier (c_parser *);
1613 static void c_parser_omp_depobj (c_parser *);
1614 static void c_parser_omp_flush (c_parser *);
1615 static tree c_parser_omp_for_loop (location_t, c_parser *, enum tree_code,
1616 tree, tree *, bool *);
1617 static void c_parser_omp_taskwait (c_parser *);
1618 static void c_parser_omp_taskyield (c_parser *);
1619 static void c_parser_omp_cancel (c_parser *);
1620 static void c_parser_omp_nothing (c_parser *);
1621
1622 enum pragma_context { pragma_external, pragma_struct, pragma_param,
1623 pragma_stmt, pragma_compound };
1624 static bool c_parser_pragma (c_parser *, enum pragma_context, bool *);
1625 static bool c_parser_omp_cancellation_point (c_parser *, enum pragma_context);
1626 static bool c_parser_omp_target (c_parser *, enum pragma_context, bool *);
1627 static void c_parser_omp_begin (c_parser *);
1628 static void c_parser_omp_end (c_parser *);
1629 static bool c_parser_omp_declare (c_parser *, enum pragma_context);
1630 static void c_parser_omp_requires (c_parser *);
1631 static bool c_parser_omp_error (c_parser *, enum pragma_context);
1632 static void c_parser_omp_assumption_clauses (c_parser *, bool);
1633 static void c_parser_omp_assumes (c_parser *);
1634 static bool c_parser_omp_ordered (c_parser *, enum pragma_context, bool *);
1635 static void c_parser_oacc_routine (c_parser *, enum pragma_context);
1636
1637 /* These Objective-C parser functions are only ever called when
1638 compiling Objective-C. */
1639 static void c_parser_objc_class_definition (c_parser *, tree);
1640 static void c_parser_objc_class_instance_variables (c_parser *);
1641 static void c_parser_objc_class_declaration (c_parser *);
1642 static void c_parser_objc_alias_declaration (c_parser *);
1643 static void c_parser_objc_protocol_definition (c_parser *, tree);
1644 static bool c_parser_objc_method_type (c_parser *);
1645 static void c_parser_objc_method_definition (c_parser *);
1646 static void c_parser_objc_methodprotolist (c_parser *);
1647 static void c_parser_objc_methodproto (c_parser *);
1648 static tree c_parser_objc_method_decl (c_parser *, bool, tree *, tree *);
1649 static tree c_parser_objc_type_name (c_parser *);
1650 static tree c_parser_objc_protocol_refs (c_parser *);
1651 static void c_parser_objc_try_catch_finally_statement (c_parser *);
1652 static void c_parser_objc_synchronized_statement (c_parser *);
1653 static tree c_parser_objc_selector (c_parser *);
1654 static tree c_parser_objc_selector_arg (c_parser *);
1655 static tree c_parser_objc_receiver (c_parser *);
1656 static tree c_parser_objc_message_args (c_parser *);
1657 static tree c_parser_objc_keywordexpr (c_parser *);
1658 static void c_parser_objc_at_property_declaration (c_parser *);
1659 static void c_parser_objc_at_synthesize_declaration (c_parser *);
1660 static void c_parser_objc_at_dynamic_declaration (c_parser *);
1661 static bool c_parser_objc_diagnose_bad_element_prefix
1662 (c_parser *, struct c_declspecs *);
1663 static location_t c_parser_parse_rtl_body (c_parser *, char *);
1664
1665 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
1666
1667 translation-unit:
1668 external-declarations
1669
1670 external-declarations:
1671 external-declaration
1672 external-declarations external-declaration
1673
1674 GNU extensions:
1675
1676 translation-unit:
1677 empty
1678 */
1679
1680 static void
1681 c_parser_translation_unit (c_parser *parser)
1682 {
1683 if (c_parser_next_token_is (parser, CPP_EOF))
1684 {
1685 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1686 "ISO C forbids an empty translation unit");
1687 }
1688 else
1689 {
1690 void *obstack_position = obstack_alloc (&parser_obstack, 0);
1691 mark_valid_location_for_stdc_pragma (false);
1692 do
1693 {
1694 ggc_collect ();
1695 c_parser_external_declaration (parser);
1696 obstack_free (&parser_obstack, obstack_position);
1697 }
1698 while (c_parser_next_token_is_not (parser, CPP_EOF));
1699 }
1700
1701 unsigned int i;
1702 tree decl;
1703 FOR_EACH_VEC_ELT (incomplete_record_decls, i, decl)
1704 if (DECL_SIZE (decl) == NULL_TREE && TREE_TYPE (decl) != error_mark_node)
1705 error ("storage size of %q+D isn%'t known", decl);
1706
1707 if (vec_safe_length (current_omp_declare_target_attribute))
1708 {
1709 c_omp_declare_target_attr
1710 a = current_omp_declare_target_attribute->pop ();
1711 if (!errorcount)
1712 error ("%qs without corresponding %qs",
1713 a.device_type >= 0 ? "#pragma omp begin declare target"
1714 : "#pragma omp declare target",
1715 "#pragma omp end declare target");
1716 vec_safe_truncate (current_omp_declare_target_attribute, 0);
1717 }
1718 if (current_omp_begin_assumes)
1719 {
1720 if (!errorcount)
1721 error ("%qs without corresponding %qs",
1722 "#pragma omp begin assumes", "#pragma omp end assumes");
1723 current_omp_begin_assumes = 0;
1724 }
1725 }
1726
1727 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
1728
1729 external-declaration:
1730 function-definition
1731 declaration
1732
1733 GNU extensions:
1734
1735 external-declaration:
1736 asm-definition
1737 ;
1738 __extension__ external-declaration
1739
1740 Objective-C:
1741
1742 external-declaration:
1743 objc-class-definition
1744 objc-class-declaration
1745 objc-alias-declaration
1746 objc-protocol-definition
1747 objc-method-definition
1748 @end
1749 */
1750
1751 static void
1752 c_parser_external_declaration (c_parser *parser)
1753 {
1754 int ext;
1755 switch (c_parser_peek_token (parser)->type)
1756 {
1757 case CPP_KEYWORD:
1758 switch (c_parser_peek_token (parser)->keyword)
1759 {
1760 case RID_EXTENSION:
1761 ext = disable_extension_diagnostics ();
1762 c_parser_consume_token (parser);
1763 c_parser_external_declaration (parser);
1764 restore_extension_diagnostics (ext);
1765 break;
1766 case RID_ASM:
1767 c_parser_asm_definition (parser);
1768 break;
1769 case RID_AT_INTERFACE:
1770 case RID_AT_IMPLEMENTATION:
1771 gcc_assert (c_dialect_objc ());
1772 c_parser_objc_class_definition (parser, NULL_TREE);
1773 break;
1774 case RID_AT_CLASS:
1775 gcc_assert (c_dialect_objc ());
1776 c_parser_objc_class_declaration (parser);
1777 break;
1778 case RID_AT_ALIAS:
1779 gcc_assert (c_dialect_objc ());
1780 c_parser_objc_alias_declaration (parser);
1781 break;
1782 case RID_AT_PROTOCOL:
1783 gcc_assert (c_dialect_objc ());
1784 c_parser_objc_protocol_definition (parser, NULL_TREE);
1785 break;
1786 case RID_AT_PROPERTY:
1787 gcc_assert (c_dialect_objc ());
1788 c_parser_objc_at_property_declaration (parser);
1789 break;
1790 case RID_AT_SYNTHESIZE:
1791 gcc_assert (c_dialect_objc ());
1792 c_parser_objc_at_synthesize_declaration (parser);
1793 break;
1794 case RID_AT_DYNAMIC:
1795 gcc_assert (c_dialect_objc ());
1796 c_parser_objc_at_dynamic_declaration (parser);
1797 break;
1798 case RID_AT_END:
1799 gcc_assert (c_dialect_objc ());
1800 c_parser_consume_token (parser);
1801 objc_finish_implementation ();
1802 break;
1803 default:
1804 goto decl_or_fndef;
1805 }
1806 break;
1807 case CPP_SEMICOLON:
1808 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1809 "ISO C does not allow extra %<;%> outside of a function");
1810 c_parser_consume_token (parser);
1811 break;
1812 case CPP_PRAGMA:
1813 mark_valid_location_for_stdc_pragma (true);
1814 c_parser_pragma (parser, pragma_external, NULL);
1815 mark_valid_location_for_stdc_pragma (false);
1816 break;
1817 case CPP_PLUS:
1818 case CPP_MINUS:
1819 if (c_dialect_objc ())
1820 {
1821 c_parser_objc_method_definition (parser);
1822 break;
1823 }
1824 /* Else fall through, and yield a syntax error trying to parse
1825 as a declaration or function definition. */
1826 /* FALLTHRU */
1827 default:
1828 decl_or_fndef:
1829 /* A declaration or a function definition (or, in Objective-C,
1830 an @interface or @protocol with prefix attributes). We can
1831 only tell which after parsing the declaration specifiers, if
1832 any, and the first declarator. */
1833 c_parser_declaration_or_fndef (parser, true, true, true, false, true);
1834 break;
1835 }
1836 }
1837
1838 static void c_finish_omp_declare_simd (c_parser *, tree, tree, vec<c_token> *);
1839 static void c_finish_oacc_routine (struct oacc_routine_data *, tree, bool);
1840
1841 /* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */
1842
1843 static void
1844 add_debug_begin_stmt (location_t loc)
1845 {
1846 /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721. */
1847 if (!MAY_HAVE_DEBUG_MARKER_STMTS || !building_stmt_list_p ())
1848 return;
1849
1850 tree stmt = build0 (DEBUG_BEGIN_STMT, void_type_node);
1851 SET_EXPR_LOCATION (stmt, loc);
1852 add_stmt (stmt);
1853 }
1854
1855 /* Helper function for c_parser_declaration_or_fndef and
1856 Handle assume attribute(s). */
1857
1858 static tree
1859 handle_assume_attribute (location_t here, tree attrs, bool nested)
1860 {
1861 if (nested)
1862 for (tree attr = lookup_attribute ("gnu", "assume", attrs); attr;
1863 attr = lookup_attribute ("gnu", "assume", TREE_CHAIN (attr)))
1864 {
1865 tree args = TREE_VALUE (attr);
1866 int nargs = list_length (args);
1867 if (nargs != 1)
1868 {
1869 error_at (here, "wrong number of arguments specified "
1870 "for %qE attribute",
1871 get_attribute_name (attr));
1872 inform (here, "expected %i, found %i", 1, nargs);
1873 }
1874 else
1875 {
1876 tree arg = TREE_VALUE (args);
1877 arg = c_objc_common_truthvalue_conversion (here, arg);
1878 arg = c_fully_fold (arg, false, NULL);
1879 if (arg != error_mark_node)
1880 {
1881 tree fn = build_call_expr_internal_loc (here, IFN_ASSUME,
1882 void_type_node, 1,
1883 arg);
1884 add_stmt (fn);
1885 }
1886 }
1887 }
1888 else
1889 pedwarn (here, OPT_Wattributes,
1890 "%<assume%> attribute at top level");
1891
1892 return remove_attribute ("gnu", "assume", attrs);
1893 }
1894
1895 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
1896 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition
1897 is accepted; otherwise (old-style parameter declarations) only other
1898 declarations are accepted. If STATIC_ASSERT_OK is true, a static
1899 assertion is accepted; otherwise (old-style parameter declarations)
1900 it is not. If NESTED is true, we are inside a function or parsing
1901 old-style parameter declarations; any functions encountered are
1902 nested functions and declaration specifiers are required; otherwise
1903 we are at top level and functions are normal functions and
1904 declaration specifiers may be optional. If EMPTY_OK is true, empty
1905 declarations are OK (subject to all other constraints); otherwise
1906 (old-style parameter declarations) they are diagnosed. If
1907 START_ATTR_OK is true, the declaration specifiers may start with
1908 attributes (GNU or standard); otherwise they may not.
1909 OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
1910 declaration when parsing an Objective-C foreach statement.
1911 FALLTHRU_ATTR_P is used to signal whether this function parsed
1912 "__attribute__((fallthrough));". ATTRS are any standard attributes
1913 parsed in the caller (in contexts where such attributes had to be
1914 parsed to determine whether what follows is a declaration or a
1915 statement); HAVE_ATTRS says whether there were any such attributes
1916 (even empty).
1917
1918 declaration:
1919 declaration-specifiers init-declarator-list[opt] ;
1920 static_assert-declaration
1921
1922 function-definition:
1923 declaration-specifiers[opt] declarator declaration-list[opt]
1924 compound-statement
1925
1926 declaration-list:
1927 declaration
1928 declaration-list declaration
1929
1930 init-declarator-list:
1931 init-declarator
1932 init-declarator-list , init-declarator
1933
1934 init-declarator:
1935 declarator simple-asm-expr[opt] gnu-attributes[opt]
1936 declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
1937
1938 GNU extensions:
1939
1940 nested-function-definition:
1941 declaration-specifiers declarator declaration-list[opt]
1942 compound-statement
1943
1944 attribute ;
1945
1946 Objective-C:
1947 gnu-attributes objc-class-definition
1948 gnu-attributes objc-category-definition
1949 gnu-attributes objc-protocol-definition
1950
1951 The simple-asm-expr and gnu-attributes are GNU extensions.
1952
1953 This function does not handle __extension__; that is handled in its
1954 callers. ??? Following the old parser, __extension__ may start
1955 external declarations, declarations in functions and declarations
1956 at the start of "for" loops, but not old-style parameter
1957 declarations.
1958
1959 C99 requires declaration specifiers in a function definition; the
1960 absence is diagnosed through the diagnosis of implicit int. In GNU
1961 C we also allow but diagnose declarations without declaration
1962 specifiers, but only at top level (elsewhere they conflict with
1963 other syntax).
1964
1965 In Objective-C, declarations of the looping variable in a foreach
1966 statement are exceptionally terminated by 'in' (for example, 'for
1967 (NSObject *object in array) { ... }').
1968
1969 OpenMP:
1970
1971 declaration:
1972 threadprivate-directive
1973
1974 GIMPLE:
1975
1976 gimple-function-definition:
1977 declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
1978 declaration-list[opt] compound-statement
1979
1980 rtl-function-definition:
1981 declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
1982 declaration-list[opt] compound-statement */
1983
1984 static void
1985 c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
1986 bool static_assert_ok, bool empty_ok,
1987 bool nested, bool start_attr_ok,
1988 tree *objc_foreach_object_declaration
1989 /* = NULL */,
1990 vec<c_token> *omp_declare_simd_clauses
1991 /* = NULL */,
1992 bool have_attrs /* = false */,
1993 tree attrs /* = NULL_TREE */,
1994 struct oacc_routine_data *oacc_routine_data
1995 /* = NULL */,
1996 bool *fallthru_attr_p /* = NULL */)
1997 {
1998 struct c_declspecs *specs;
1999 tree prefix_attrs;
2000 tree all_prefix_attrs;
2001 bool diagnosed_no_specs = false;
2002 location_t here = c_parser_peek_token (parser)->location;
2003
2004 add_debug_begin_stmt (c_parser_peek_token (parser)->location);
2005
2006 if (static_assert_ok
2007 && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
2008 {
2009 c_parser_static_assert_declaration (parser);
2010 return;
2011 }
2012 specs = build_null_declspecs ();
2013
2014 /* Handle any standard attributes parsed in the caller. */
2015 if (have_attrs)
2016 {
2017 declspecs_add_attrs (here, specs, attrs);
2018 specs->non_std_attrs_seen_p = false;
2019 }
2020
2021 /* Try to detect an unknown type name when we have "A B" or "A *B". */
2022 if (c_parser_peek_token (parser)->type == CPP_NAME
2023 && c_parser_peek_token (parser)->id_kind == C_ID_ID
2024 && (c_parser_peek_2nd_token (parser)->type == CPP_NAME
2025 || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
2026 && (!nested || !lookup_name (c_parser_peek_token (parser)->value)))
2027 {
2028 tree name = c_parser_peek_token (parser)->value;
2029
2030 /* Issue a warning about NAME being an unknown type name, perhaps
2031 with some kind of hint.
2032 If the user forgot a "struct" etc, suggest inserting
2033 it. Otherwise, attempt to look for misspellings. */
2034 gcc_rich_location richloc (here);
2035 if (tag_exists_p (RECORD_TYPE, name))
2036 {
2037 /* This is not C++ with its implicit typedef. */
2038 richloc.add_fixit_insert_before ("struct ");
2039 error_at (&richloc,
2040 "unknown type name %qE;"
2041 " use %<struct%> keyword to refer to the type",
2042 name);
2043 }
2044 else if (tag_exists_p (UNION_TYPE, name))
2045 {
2046 richloc.add_fixit_insert_before ("union ");
2047 error_at (&richloc,
2048 "unknown type name %qE;"
2049 " use %<union%> keyword to refer to the type",
2050 name);
2051 }
2052 else if (tag_exists_p (ENUMERAL_TYPE, name))
2053 {
2054 richloc.add_fixit_insert_before ("enum ");
2055 error_at (&richloc,
2056 "unknown type name %qE;"
2057 " use %<enum%> keyword to refer to the type",
2058 name);
2059 }
2060 else
2061 {
2062 auto_diagnostic_group d;
2063 name_hint hint = lookup_name_fuzzy (name, FUZZY_LOOKUP_TYPENAME,
2064 here);
2065 if (const char *suggestion = hint.suggestion ())
2066 {
2067 richloc.add_fixit_replace (suggestion);
2068 error_at (&richloc,
2069 "unknown type name %qE; did you mean %qs?",
2070 name, suggestion);
2071 }
2072 else
2073 error_at (here, "unknown type name %qE", name);
2074 }
2075
2076 /* Parse declspecs normally to get a correct pointer type, but avoid
2077 a further "fails to be a type name" error. Refuse nested functions
2078 since it is not how the user likely wants us to recover. */
2079 c_parser_peek_token (parser)->type = CPP_KEYWORD;
2080 c_parser_peek_token (parser)->keyword = RID_VOID;
2081 c_parser_peek_token (parser)->value = error_mark_node;
2082 fndef_ok = !nested;
2083 }
2084
2085 /* When there are standard attributes at the start of the
2086 declaration (to apply to the entity being declared), an
2087 init-declarator-list or function definition must be present. */
2088 if (c_parser_nth_token_starts_std_attributes (parser, 1))
2089 have_attrs = true;
2090
2091 c_parser_declspecs (parser, specs, true, true, start_attr_ok,
2092 true, true, start_attr_ok, true, cla_nonabstract_decl);
2093 if (parser->error)
2094 {
2095 c_parser_skip_to_end_of_block_or_statement (parser);
2096 return;
2097 }
2098 if (nested && !specs->declspecs_seen_p)
2099 {
2100 c_parser_error (parser, "expected declaration specifiers");
2101 c_parser_skip_to_end_of_block_or_statement (parser);
2102 return;
2103 }
2104
2105 finish_declspecs (specs);
2106 bool auto_type_p = specs->typespec_word == cts_auto_type;
2107 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2108 {
2109 bool handled_assume = false;
2110 if (specs->typespec_kind == ctsk_none
2111 && lookup_attribute ("gnu", "assume", specs->attrs))
2112 {
2113 handled_assume = true;
2114 specs->attrs
2115 = handle_assume_attribute (here, specs->attrs, nested);
2116 }
2117 if (auto_type_p)
2118 error_at (here, "%<__auto_type%> in empty declaration");
2119 else if (specs->typespec_kind == ctsk_none
2120 && attribute_fallthrough_p (specs->attrs))
2121 {
2122 if (fallthru_attr_p != NULL)
2123 *fallthru_attr_p = true;
2124 if (nested)
2125 {
2126 tree fn = build_call_expr_internal_loc (here, IFN_FALLTHROUGH,
2127 void_type_node, 0);
2128 add_stmt (fn);
2129 }
2130 else
2131 pedwarn (here, OPT_Wattributes,
2132 "%<fallthrough%> attribute at top level");
2133 }
2134 else if (empty_ok
2135 && !(have_attrs && specs->non_std_attrs_seen_p)
2136 && !handled_assume)
2137 shadow_tag (specs);
2138 else
2139 {
2140 shadow_tag_warned (specs, 1);
2141 if (!handled_assume)
2142 pedwarn (here, 0, "empty declaration");
2143 }
2144 c_parser_consume_token (parser);
2145 if (oacc_routine_data)
2146 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2147 return;
2148 }
2149
2150 /* Provide better error recovery. Note that a type name here is usually
2151 better diagnosed as a redeclaration. */
2152 if (empty_ok
2153 && specs->typespec_kind == ctsk_tagdef
2154 && c_parser_next_token_starts_declspecs (parser)
2155 && !c_parser_next_token_is (parser, CPP_NAME))
2156 {
2157 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
2158 parser->error = false;
2159 shadow_tag_warned (specs, 1);
2160 return;
2161 }
2162 else if (c_dialect_objc () && !auto_type_p)
2163 {
2164 /* Prefix attributes are an error on method decls. */
2165 switch (c_parser_peek_token (parser)->type)
2166 {
2167 case CPP_PLUS:
2168 case CPP_MINUS:
2169 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2170 return;
2171 if (specs->attrs)
2172 {
2173 warning_at (c_parser_peek_token (parser)->location,
2174 OPT_Wattributes,
2175 "prefix attributes are ignored for methods");
2176 specs->attrs = NULL_TREE;
2177 }
2178 if (fndef_ok)
2179 c_parser_objc_method_definition (parser);
2180 else
2181 c_parser_objc_methodproto (parser);
2182 return;
2183 break;
2184 default:
2185 break;
2186 }
2187 /* This is where we parse 'attributes @interface ...',
2188 'attributes @implementation ...', 'attributes @protocol ...'
2189 (where attributes could be, for example, __attribute__
2190 ((deprecated)).
2191 */
2192 switch (c_parser_peek_token (parser)->keyword)
2193 {
2194 case RID_AT_INTERFACE:
2195 {
2196 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2197 return;
2198 c_parser_objc_class_definition (parser, specs->attrs);
2199 return;
2200 }
2201 break;
2202 case RID_AT_IMPLEMENTATION:
2203 {
2204 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2205 return;
2206 if (specs->attrs)
2207 {
2208 warning_at (c_parser_peek_token (parser)->location,
2209 OPT_Wattributes,
2210 "prefix attributes are ignored for implementations");
2211 specs->attrs = NULL_TREE;
2212 }
2213 c_parser_objc_class_definition (parser, NULL_TREE);
2214 return;
2215 }
2216 break;
2217 case RID_AT_PROTOCOL:
2218 {
2219 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2220 return;
2221 c_parser_objc_protocol_definition (parser, specs->attrs);
2222 return;
2223 }
2224 break;
2225 case RID_AT_ALIAS:
2226 case RID_AT_CLASS:
2227 case RID_AT_END:
2228 case RID_AT_PROPERTY:
2229 if (specs->attrs)
2230 {
2231 c_parser_error (parser, "unexpected attribute");
2232 specs->attrs = NULL;
2233 }
2234 break;
2235 default:
2236 break;
2237 }
2238 }
2239 else if (attribute_fallthrough_p (specs->attrs))
2240 warning_at (here, OPT_Wattributes,
2241 "%<fallthrough%> attribute not followed by %<;%>");
2242 else if (lookup_attribute ("gnu", "assume", specs->attrs))
2243 warning_at (here, OPT_Wattributes,
2244 "%<assume%> attribute not followed by %<;%>");
2245
2246 pending_xref_error ();
2247 prefix_attrs = specs->attrs;
2248 all_prefix_attrs = prefix_attrs;
2249 specs->attrs = NULL_TREE;
2250 while (true)
2251 {
2252 struct c_declarator *declarator;
2253 bool dummy = false;
2254 timevar_id_t tv;
2255 tree fnbody = NULL_TREE;
2256 /* Declaring either one or more declarators (in which case we
2257 should diagnose if there were no declaration specifiers) or a
2258 function definition (in which case the diagnostic for
2259 implicit int suffices). */
2260 declarator = c_parser_declarator (parser,
2261 specs->typespec_kind != ctsk_none,
2262 C_DTR_NORMAL, &dummy);
2263 if (declarator == NULL)
2264 {
2265 if (omp_declare_simd_clauses)
2266 c_finish_omp_declare_simd (parser, NULL_TREE, NULL_TREE,
2267 omp_declare_simd_clauses);
2268 if (oacc_routine_data)
2269 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2270 c_parser_skip_to_end_of_block_or_statement (parser);
2271 return;
2272 }
2273 if (auto_type_p && declarator->kind != cdk_id)
2274 {
2275 error_at (here,
2276 "%<__auto_type%> requires a plain identifier"
2277 " as declarator");
2278 c_parser_skip_to_end_of_block_or_statement (parser);
2279 return;
2280 }
2281 if (c_parser_next_token_is (parser, CPP_EQ)
2282 || c_parser_next_token_is (parser, CPP_COMMA)
2283 || c_parser_next_token_is (parser, CPP_SEMICOLON)
2284 || c_parser_next_token_is_keyword (parser, RID_ASM)
2285 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)
2286 || c_parser_next_token_is_keyword (parser, RID_IN))
2287 {
2288 tree asm_name = NULL_TREE;
2289 tree postfix_attrs = NULL_TREE;
2290 if (!diagnosed_no_specs && !specs->declspecs_seen_p)
2291 {
2292 diagnosed_no_specs = true;
2293 pedwarn (here, 0, "data definition has no type or storage class");
2294 }
2295 /* Having seen a data definition, there cannot now be a
2296 function definition. */
2297 fndef_ok = false;
2298 if (c_parser_next_token_is_keyword (parser, RID_ASM))
2299 asm_name = c_parser_simple_asm_expr (parser);
2300 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2301 {
2302 postfix_attrs = c_parser_gnu_attributes (parser);
2303 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
2304 {
2305 /* This means there is an attribute specifier after
2306 the declarator in a function definition. Provide
2307 some more information for the user. */
2308 error_at (here, "attributes should be specified before the "
2309 "declarator in a function definition");
2310 c_parser_skip_to_end_of_block_or_statement (parser);
2311 return;
2312 }
2313 }
2314 if (c_parser_next_token_is (parser, CPP_EQ))
2315 {
2316 tree d;
2317 struct c_expr init;
2318 location_t init_loc;
2319 c_parser_consume_token (parser);
2320 if (auto_type_p)
2321 {
2322 init_loc = c_parser_peek_token (parser)->location;
2323 rich_location richloc (line_table, init_loc);
2324 start_init (NULL_TREE, asm_name, global_bindings_p (), &richloc);
2325 /* A parameter is initialized, which is invalid. Don't
2326 attempt to instrument the initializer. */
2327 int flag_sanitize_save = flag_sanitize;
2328 if (nested && !empty_ok)
2329 flag_sanitize = 0;
2330 init = c_parser_expr_no_commas (parser, NULL);
2331 flag_sanitize = flag_sanitize_save;
2332 if (TREE_CODE (init.value) == COMPONENT_REF
2333 && DECL_C_BIT_FIELD (TREE_OPERAND (init.value, 1)))
2334 error_at (here,
2335 "%<__auto_type%> used with a bit-field"
2336 " initializer");
2337 init = convert_lvalue_to_rvalue (init_loc, init, true, true);
2338 tree init_type = TREE_TYPE (init.value);
2339 bool vm_type = variably_modified_type_p (init_type,
2340 NULL_TREE);
2341 if (vm_type)
2342 init.value = save_expr (init.value);
2343 finish_init ();
2344 specs->typespec_kind = ctsk_typeof;
2345 specs->locations[cdw_typedef] = init_loc;
2346 specs->typedef_p = true;
2347 specs->type = init_type;
2348 if (vm_type)
2349 {
2350 bool maybe_const = true;
2351 tree type_expr = c_fully_fold (init.value, false,
2352 &maybe_const);
2353 specs->expr_const_operands &= maybe_const;
2354 if (specs->expr)
2355 specs->expr = build2 (COMPOUND_EXPR,
2356 TREE_TYPE (type_expr),
2357 specs->expr, type_expr);
2358 else
2359 specs->expr = type_expr;
2360 }
2361 d = start_decl (declarator, specs, true,
2362 chainon (postfix_attrs, all_prefix_attrs));
2363 if (!d)
2364 d = error_mark_node;
2365 if (omp_declare_simd_clauses)
2366 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2367 omp_declare_simd_clauses);
2368 }
2369 else
2370 {
2371 /* The declaration of the variable is in effect while
2372 its initializer is parsed. */
2373 d = start_decl (declarator, specs, true,
2374 chainon (postfix_attrs, all_prefix_attrs));
2375 if (!d)
2376 d = error_mark_node;
2377 if (omp_declare_simd_clauses)
2378 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2379 omp_declare_simd_clauses);
2380 init_loc = c_parser_peek_token (parser)->location;
2381 rich_location richloc (line_table, init_loc);
2382 start_init (d, asm_name, global_bindings_p (), &richloc);
2383 /* A parameter is initialized, which is invalid. Don't
2384 attempt to instrument the initializer. */
2385 int flag_sanitize_save = flag_sanitize;
2386 if (TREE_CODE (d) == PARM_DECL)
2387 flag_sanitize = 0;
2388 init = c_parser_initializer (parser, d);
2389 flag_sanitize = flag_sanitize_save;
2390 finish_init ();
2391 }
2392 if (oacc_routine_data)
2393 c_finish_oacc_routine (oacc_routine_data, d, false);
2394 if (d != error_mark_node)
2395 {
2396 maybe_warn_string_init (init_loc, TREE_TYPE (d), init);
2397 finish_decl (d, init_loc, init.value,
2398 init.original_type, asm_name);
2399 }
2400 }
2401 else
2402 {
2403 if (auto_type_p)
2404 {
2405 error_at (here,
2406 "%<__auto_type%> requires an initialized "
2407 "data declaration");
2408 c_parser_skip_to_end_of_block_or_statement (parser);
2409 return;
2410 }
2411
2412 location_t lastloc = UNKNOWN_LOCATION;
2413 tree attrs = chainon (postfix_attrs, all_prefix_attrs);
2414 tree d = start_decl (declarator, specs, false, attrs, &lastloc);
2415 if (d && TREE_CODE (d) == FUNCTION_DECL)
2416 {
2417 /* Find the innermost declarator that is neither cdk_id
2418 nor cdk_attrs. */
2419 const struct c_declarator *decl = declarator;
2420 const struct c_declarator *last_non_id_attrs = NULL;
2421
2422 while (decl)
2423 switch (decl->kind)
2424 {
2425 case cdk_array:
2426 case cdk_function:
2427 case cdk_pointer:
2428 last_non_id_attrs = decl;
2429 decl = decl->declarator;
2430 break;
2431
2432 case cdk_attrs:
2433 decl = decl->declarator;
2434 break;
2435
2436 case cdk_id:
2437 decl = 0;
2438 break;
2439
2440 default:
2441 gcc_unreachable ();
2442 }
2443
2444 /* If it exists and is cdk_function declaration whose
2445 arguments have not been set yet, use its arguments. */
2446 if (last_non_id_attrs
2447 && last_non_id_attrs->kind == cdk_function)
2448 {
2449 tree parms = last_non_id_attrs->u.arg_info->parms;
2450 if (DECL_ARGUMENTS (d) == NULL_TREE
2451 && DECL_INITIAL (d) == NULL_TREE)
2452 DECL_ARGUMENTS (d) = parms;
2453
2454 warn_parm_array_mismatch (lastloc, d, parms);
2455 }
2456 }
2457 if (omp_declare_simd_clauses)
2458 {
2459 tree parms = NULL_TREE;
2460 if (d && TREE_CODE (d) == FUNCTION_DECL)
2461 {
2462 struct c_declarator *ce = declarator;
2463 while (ce != NULL)
2464 if (ce->kind == cdk_function)
2465 {
2466 parms = ce->u.arg_info->parms;
2467 break;
2468 }
2469 else
2470 ce = ce->declarator;
2471 }
2472 if (parms)
2473 temp_store_parm_decls (d, parms);
2474 c_finish_omp_declare_simd (parser, d, parms,
2475 omp_declare_simd_clauses);
2476 if (parms)
2477 temp_pop_parm_decls ();
2478 }
2479 if (oacc_routine_data)
2480 c_finish_oacc_routine (oacc_routine_data, d, false);
2481 if (d)
2482 finish_decl (d, UNKNOWN_LOCATION, NULL_TREE,
2483 NULL_TREE, asm_name);
2484
2485 if (c_parser_next_token_is_keyword (parser, RID_IN))
2486 {
2487 if (d)
2488 *objc_foreach_object_declaration = d;
2489 else
2490 *objc_foreach_object_declaration = error_mark_node;
2491 }
2492 }
2493 if (c_parser_next_token_is (parser, CPP_COMMA))
2494 {
2495 if (auto_type_p)
2496 {
2497 error_at (here,
2498 "%<__auto_type%> may only be used with"
2499 " a single declarator");
2500 c_parser_skip_to_end_of_block_or_statement (parser);
2501 return;
2502 }
2503 c_parser_consume_token (parser);
2504 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2505 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
2506 prefix_attrs);
2507 else
2508 all_prefix_attrs = prefix_attrs;
2509 continue;
2510 }
2511 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2512 {
2513 c_parser_consume_token (parser);
2514 return;
2515 }
2516 else if (c_parser_next_token_is_keyword (parser, RID_IN))
2517 {
2518 /* This can only happen in Objective-C: we found the
2519 'in' that terminates the declaration inside an
2520 Objective-C foreach statement. Do not consume the
2521 token, so that the caller can use it to determine
2522 that this indeed is a foreach context. */
2523 return;
2524 }
2525 else
2526 {
2527 c_parser_error (parser, "expected %<,%> or %<;%>");
2528 c_parser_skip_to_end_of_block_or_statement (parser);
2529 return;
2530 }
2531 }
2532 else if (auto_type_p)
2533 {
2534 error_at (here,
2535 "%<__auto_type%> requires an initialized data declaration");
2536 c_parser_skip_to_end_of_block_or_statement (parser);
2537 return;
2538 }
2539 else if (!fndef_ok)
2540 {
2541 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, "
2542 "%<asm%> or %<__attribute__%>");
2543 c_parser_skip_to_end_of_block_or_statement (parser);
2544 return;
2545 }
2546 /* Function definition (nested or otherwise). */
2547 if (nested)
2548 {
2549 pedwarn (here, OPT_Wpedantic, "ISO C forbids nested functions");
2550 c_push_function_context ();
2551 }
2552 if (!start_function (specs, declarator, all_prefix_attrs))
2553 {
2554 /* At this point we've consumed:
2555 declaration-specifiers declarator
2556 and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2557 RID_ASM, RID_ATTRIBUTE, or RID_IN,
2558 but the
2559 declaration-specifiers declarator
2560 aren't grokkable as a function definition, so we have
2561 an error. */
2562 gcc_assert (!c_parser_next_token_is (parser, CPP_SEMICOLON));
2563 if (c_parser_next_token_starts_declspecs (parser))
2564 {
2565 /* If we have
2566 declaration-specifiers declarator decl-specs
2567 then assume we have a missing semicolon, which would
2568 give us:
2569 declaration-specifiers declarator decl-specs
2570 ^
2571 ;
2572 <~~~~~~~~~ declaration ~~~~~~~~~~>
2573 Use c_parser_require to get an error with a fix-it hint. */
2574 c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>");
2575 parser->error = false;
2576 }
2577 else
2578 {
2579 /* This can appear in many cases looking nothing like a
2580 function definition, so we don't give a more specific
2581 error suggesting there was one. */
2582 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2583 "or %<__attribute__%>");
2584 }
2585 if (nested)
2586 c_pop_function_context ();
2587 break;
2588 }
2589
2590 if (DECL_DECLARED_INLINE_P (current_function_decl))
2591 tv = TV_PARSE_INLINE;
2592 else
2593 tv = TV_PARSE_FUNC;
2594 auto_timevar at (g_timer, tv);
2595
2596 /* Parse old-style parameter declarations. ??? Attributes are
2597 not allowed to start declaration specifiers here because of a
2598 syntax conflict between a function declaration with attribute
2599 suffix and a function definition with an attribute prefix on
2600 first old-style parameter declaration. Following the old
2601 parser, they are not accepted on subsequent old-style
2602 parameter declarations either. However, there is no
2603 ambiguity after the first declaration, nor indeed on the
2604 first as long as we don't allow postfix attributes after a
2605 declarator with a nonempty identifier list in a definition;
2606 and postfix attributes have never been accepted here in
2607 function definitions either. */
2608 while (c_parser_next_token_is_not (parser, CPP_EOF)
2609 && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE))
2610 c_parser_declaration_or_fndef (parser, false, false, false,
2611 true, false);
2612 store_parm_decls ();
2613 if (omp_declare_simd_clauses)
2614 c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE,
2615 omp_declare_simd_clauses);
2616 if (oacc_routine_data)
2617 c_finish_oacc_routine (oacc_routine_data, current_function_decl, true);
2618 location_t startloc = c_parser_peek_token (parser)->location;
2619 DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
2620 = startloc;
2621 location_t endloc = startloc;
2622
2623 /* If the definition was marked with __RTL, use the RTL parser now,
2624 consuming the function body. */
2625 if (specs->declspec_il == cdil_rtl)
2626 {
2627 endloc = c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass);
2628
2629 /* Normally, store_parm_decls sets next_is_function_body,
2630 anticipating a function body. We need a push_scope/pop_scope
2631 pair to flush out this state, or subsequent function parsing
2632 will go wrong. */
2633 push_scope ();
2634 pop_scope ();
2635
2636 finish_function (endloc);
2637 return;
2638 }
2639 /* If the definition was marked with __GIMPLE then parse the
2640 function body as GIMPLE. */
2641 else if (specs->declspec_il != cdil_none)
2642 {
2643 bool saved = in_late_binary_op;
2644 in_late_binary_op = true;
2645 c_parser_parse_gimple_body (parser, specs->gimple_or_rtl_pass,
2646 specs->declspec_il,
2647 specs->entry_bb_count);
2648 in_late_binary_op = saved;
2649 }
2650 else
2651 fnbody = c_parser_compound_statement (parser, &endloc);
2652 tree fndecl = current_function_decl;
2653 if (nested)
2654 {
2655 tree decl = current_function_decl;
2656 /* Mark nested functions as needing static-chain initially.
2657 lower_nested_functions will recompute it but the
2658 DECL_STATIC_CHAIN flag is also used before that happens,
2659 by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
2660 DECL_STATIC_CHAIN (decl) = 1;
2661 add_stmt (fnbody);
2662 finish_function (endloc);
2663 c_pop_function_context ();
2664 add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));
2665 }
2666 else
2667 {
2668 if (fnbody)
2669 add_stmt (fnbody);
2670 finish_function (endloc);
2671 }
2672 /* Get rid of the empty stmt list for GIMPLE/RTL. */
2673 if (specs->declspec_il != cdil_none)
2674 DECL_SAVED_TREE (fndecl) = NULL_TREE;
2675
2676 break;
2677 }
2678 }
2679
2680 /* Parse an asm-definition (asm() outside a function body). This is a
2681 GNU extension.
2682
2683 asm-definition:
2684 simple-asm-expr ;
2685 */
2686
2687 static void
2688 c_parser_asm_definition (c_parser *parser)
2689 {
2690 tree asm_str = c_parser_simple_asm_expr (parser);
2691 if (asm_str)
2692 symtab->finalize_toplevel_asm (asm_str);
2693 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
2694 }
2695
2696 /* Parse a static assertion (C11 6.7.10).
2697
2698 static_assert-declaration:
2699 static_assert-declaration-no-semi ;
2700 */
2701
2702 static void
2703 c_parser_static_assert_declaration (c_parser *parser)
2704 {
2705 c_parser_static_assert_declaration_no_semi (parser);
2706 if (parser->error
2707 || !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
2708 c_parser_skip_to_end_of_block_or_statement (parser);
2709 }
2710
2711 /* Parse a static assertion (C11 6.7.10), without the trailing
2712 semicolon.
2713
2714 static_assert-declaration-no-semi:
2715 _Static_assert ( constant-expression , string-literal )
2716
2717 C2X:
2718 static_assert-declaration-no-semi:
2719 _Static_assert ( constant-expression )
2720 */
2721
2722 static void
2723 c_parser_static_assert_declaration_no_semi (c_parser *parser)
2724 {
2725 location_t assert_loc, value_loc;
2726 tree value;
2727 tree string = NULL_TREE;
2728
2729 gcc_assert (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT));
2730 tree spelling = c_parser_peek_token (parser)->value;
2731 assert_loc = c_parser_peek_token (parser)->location;
2732 if (flag_isoc99)
2733 pedwarn_c99 (assert_loc, OPT_Wpedantic,
2734 "ISO C99 does not support %qE", spelling);
2735 else
2736 pedwarn_c99 (assert_loc, OPT_Wpedantic,
2737 "ISO C90 does not support %qE", spelling);
2738 c_parser_consume_token (parser);
2739 matching_parens parens;
2740 if (!parens.require_open (parser))
2741 return;
2742 location_t value_tok_loc = c_parser_peek_token (parser)->location;
2743 value = c_parser_expr_no_commas (parser, NULL).value;
2744 value_loc = EXPR_LOC_OR_LOC (value, value_tok_loc);
2745 if (c_parser_next_token_is (parser, CPP_COMMA))
2746 {
2747 c_parser_consume_token (parser);
2748 switch (c_parser_peek_token (parser)->type)
2749 {
2750 case CPP_STRING:
2751 case CPP_STRING16:
2752 case CPP_STRING32:
2753 case CPP_WSTRING:
2754 case CPP_UTF8STRING:
2755 string = c_parser_string_literal (parser, false, true).value;
2756 break;
2757 default:
2758 c_parser_error (parser, "expected string literal");
2759 return;
2760 }
2761 }
2762 else if (flag_isoc11)
2763 /* If pedantic for pre-C11, the use of _Static_assert itself will
2764 have been diagnosed, so do not also diagnose the use of this
2765 new C2X feature of _Static_assert. */
2766 pedwarn_c11 (assert_loc, OPT_Wpedantic,
2767 "ISO C11 does not support omitting the string in "
2768 "%qE", spelling);
2769 parens.require_close (parser);
2770
2771 if (!INTEGRAL_TYPE_P (TREE_TYPE (value)))
2772 {
2773 error_at (value_loc, "expression in static assertion is not an integer");
2774 return;
2775 }
2776 if (TREE_CODE (value) != INTEGER_CST)
2777 {
2778 value = c_fully_fold (value, false, NULL);
2779 /* Strip no-op conversions. */
2780 STRIP_TYPE_NOPS (value);
2781 if (TREE_CODE (value) == INTEGER_CST)
2782 pedwarn (value_loc, OPT_Wpedantic, "expression in static assertion "
2783 "is not an integer constant expression");
2784 }
2785 if (TREE_CODE (value) != INTEGER_CST)
2786 {
2787 error_at (value_loc, "expression in static assertion is not constant");
2788 return;
2789 }
2790 constant_expression_warning (value);
2791 if (integer_zerop (value))
2792 {
2793 if (string)
2794 error_at (assert_loc, "static assertion failed: %E", string);
2795 else
2796 error_at (assert_loc, "static assertion failed");
2797 }
2798 }
2799
2800 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
2801 6.7, C11 6.7), adding them to SPECS (which may already include some).
2802 Storage class specifiers are accepted iff SCSPEC_OK; type
2803 specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
2804 accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start
2805 iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK. In
2806 addition to the syntax shown, standard attributes are accepted at
2807 the start iff START_STD_ATTR_OK and at the end iff END_STD_ATTR_OK;
2808 unlike gnu-attributes, they are not accepted in the middle of the
2809 list. (This combines various different syntax productions in the C
2810 standard, and in some cases gnu-attributes and standard attributes
2811 at the start may already have been parsed before this function is
2812 called.)
2813
2814 declaration-specifiers:
2815 storage-class-specifier declaration-specifiers[opt]
2816 type-specifier declaration-specifiers[opt]
2817 type-qualifier declaration-specifiers[opt]
2818 function-specifier declaration-specifiers[opt]
2819 alignment-specifier declaration-specifiers[opt]
2820
2821 Function specifiers (inline) are from C99, and are currently
2822 handled as storage class specifiers, as is __thread. Alignment
2823 specifiers are from C11.
2824
2825 C90 6.5.1, C99 6.7.1, C11 6.7.1:
2826 storage-class-specifier:
2827 typedef
2828 extern
2829 static
2830 auto
2831 register
2832 _Thread_local
2833
2834 (_Thread_local is new in C11.)
2835
2836 C99 6.7.4, C11 6.7.4:
2837 function-specifier:
2838 inline
2839 _Noreturn
2840
2841 (_Noreturn is new in C11.)
2842
2843 C90 6.5.2, C99 6.7.2, C11 6.7.2:
2844 type-specifier:
2845 void
2846 char
2847 short
2848 int
2849 long
2850 float
2851 double
2852 signed
2853 unsigned
2854 _Bool
2855 _Complex
2856 [_Imaginary removed in C99 TC2]
2857 struct-or-union-specifier
2858 enum-specifier
2859 typedef-name
2860 atomic-type-specifier
2861
2862 (_Bool and _Complex are new in C99.)
2863 (atomic-type-specifier is new in C11.)
2864
2865 C90 6.5.3, C99 6.7.3, C11 6.7.3:
2866
2867 type-qualifier:
2868 const
2869 restrict
2870 volatile
2871 address-space-qualifier
2872 _Atomic
2873
2874 (restrict is new in C99.)
2875 (_Atomic is new in C11.)
2876
2877 GNU extensions:
2878
2879 declaration-specifiers:
2880 gnu-attributes declaration-specifiers[opt]
2881
2882 type-qualifier:
2883 address-space
2884
2885 address-space:
2886 identifier recognized by the target
2887
2888 storage-class-specifier:
2889 __thread
2890
2891 type-specifier:
2892 typeof-specifier
2893 __auto_type
2894 __intN
2895 _Decimal32
2896 _Decimal64
2897 _Decimal128
2898 _Fract
2899 _Accum
2900 _Sat
2901
2902 (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
2903 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
2904
2905 atomic-type-specifier
2906 _Atomic ( type-name )
2907
2908 Objective-C:
2909
2910 type-specifier:
2911 class-name objc-protocol-refs[opt]
2912 typedef-name objc-protocol-refs
2913 objc-protocol-refs
2914 */
2915
2916 void
2917 c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
2918 bool scspec_ok, bool typespec_ok, bool start_attr_ok,
2919 bool alignspec_ok, bool auto_type_ok,
2920 bool start_std_attr_ok, bool end_std_attr_ok,
2921 enum c_lookahead_kind la)
2922 {
2923 bool attrs_ok = start_attr_ok;
2924 bool seen_type = specs->typespec_kind != ctsk_none;
2925
2926 if (!typespec_ok)
2927 gcc_assert (la == cla_prefer_id);
2928
2929 if (start_std_attr_ok
2930 && c_parser_nth_token_starts_std_attributes (parser, 1))
2931 {
2932 gcc_assert (!specs->non_std_attrs_seen_p);
2933 location_t loc = c_parser_peek_token (parser)->location;
2934 tree attrs = c_parser_std_attribute_specifier_sequence (parser);
2935 declspecs_add_attrs (loc, specs, attrs);
2936 specs->non_std_attrs_seen_p = false;
2937 }
2938
2939 while (c_parser_next_token_is (parser, CPP_NAME)
2940 || c_parser_next_token_is (parser, CPP_KEYWORD)
2941 || (c_dialect_objc () && c_parser_next_token_is (parser, CPP_LESS)))
2942 {
2943 struct c_typespec t;
2944 tree attrs;
2945 tree align;
2946 location_t loc = c_parser_peek_token (parser)->location;
2947
2948 /* If we cannot accept a type, exit if the next token must start
2949 one. Also, if we already have seen a tagged definition,
2950 a typename would be an error anyway and likely the user
2951 has simply forgotten a semicolon, so we exit. */
2952 if ((!typespec_ok || specs->typespec_kind == ctsk_tagdef)
2953 && c_parser_next_tokens_start_typename (parser, la)
2954 && !c_parser_next_token_is_qualifier (parser)
2955 && !c_parser_next_token_is_keyword (parser, RID_ALIGNAS))
2956 break;
2957
2958 if (c_parser_next_token_is (parser, CPP_NAME))
2959 {
2960 c_token *name_token = c_parser_peek_token (parser);
2961 tree value = name_token->value;
2962 c_id_kind kind = name_token->id_kind;
2963
2964 if (kind == C_ID_ADDRSPACE)
2965 {
2966 addr_space_t as
2967 = name_token->keyword - RID_FIRST_ADDR_SPACE;
2968 declspecs_add_addrspace (name_token->location, specs, as);
2969 c_parser_consume_token (parser);
2970 attrs_ok = true;
2971 continue;
2972 }
2973
2974 gcc_assert (!c_parser_next_token_is_qualifier (parser));
2975
2976 /* If we cannot accept a type, and the next token must start one,
2977 exit. Do the same if we already have seen a tagged definition,
2978 since it would be an error anyway and likely the user has simply
2979 forgotten a semicolon. */
2980 if (seen_type || !c_parser_next_tokens_start_typename (parser, la))
2981 break;
2982
2983 /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
2984 a C_ID_CLASSNAME. */
2985 c_parser_consume_token (parser);
2986 seen_type = true;
2987 attrs_ok = true;
2988 if (kind == C_ID_ID)
2989 {
2990 error_at (loc, "unknown type name %qE", value);
2991 t.kind = ctsk_typedef;
2992 t.spec = error_mark_node;
2993 }
2994 else if (kind == C_ID_TYPENAME
2995 && (!c_dialect_objc ()
2996 || c_parser_next_token_is_not (parser, CPP_LESS)))
2997 {
2998 t.kind = ctsk_typedef;
2999 /* For a typedef name, record the meaning, not the name.
3000 In case of 'foo foo, bar;'. */
3001 t.spec = lookup_name (value);
3002 }
3003 else
3004 {
3005 tree proto = NULL_TREE;
3006 gcc_assert (c_dialect_objc ());
3007 t.kind = ctsk_objc;
3008 if (c_parser_next_token_is (parser, CPP_LESS))
3009 proto = c_parser_objc_protocol_refs (parser);
3010 t.spec = objc_get_protocol_qualified_type (value, proto);
3011 }
3012 t.expr = NULL_TREE;
3013 t.expr_const_operands = true;
3014 declspecs_add_type (name_token->location, specs, t);
3015 continue;
3016 }
3017 if (c_parser_next_token_is (parser, CPP_LESS))
3018 {
3019 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
3020 nisse@lysator.liu.se. */
3021 tree proto;
3022 gcc_assert (c_dialect_objc ());
3023 if (!typespec_ok || seen_type)
3024 break;
3025 proto = c_parser_objc_protocol_refs (parser);
3026 t.kind = ctsk_objc;
3027 t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto);
3028 t.expr = NULL_TREE;
3029 t.expr_const_operands = true;
3030 declspecs_add_type (loc, specs, t);
3031 continue;
3032 }
3033 gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD));
3034 switch (c_parser_peek_token (parser)->keyword)
3035 {
3036 case RID_STATIC:
3037 case RID_EXTERN:
3038 case RID_REGISTER:
3039 case RID_TYPEDEF:
3040 case RID_INLINE:
3041 case RID_NORETURN:
3042 case RID_AUTO:
3043 case RID_THREAD:
3044 if (!scspec_ok)
3045 goto out;
3046 attrs_ok = true;
3047 /* TODO: Distinguish between function specifiers (inline, noreturn)
3048 and storage class specifiers, either here or in
3049 declspecs_add_scspec. */
3050 declspecs_add_scspec (loc, specs,
3051 c_parser_peek_token (parser)->value);
3052 c_parser_consume_token (parser);
3053 break;
3054 case RID_AUTO_TYPE:
3055 if (!auto_type_ok)
3056 goto out;
3057 /* Fall through. */
3058 case RID_UNSIGNED:
3059 case RID_LONG:
3060 case RID_SHORT:
3061 case RID_SIGNED:
3062 case RID_COMPLEX:
3063 case RID_INT:
3064 case RID_CHAR:
3065 case RID_FLOAT:
3066 case RID_DOUBLE:
3067 case RID_VOID:
3068 case RID_DFLOAT32:
3069 case RID_DFLOAT64:
3070 case RID_DFLOAT128:
3071 CASE_RID_FLOATN_NX:
3072 case RID_BOOL:
3073 case RID_FRACT:
3074 case RID_ACCUM:
3075 case RID_SAT:
3076 case RID_INT_N_0:
3077 case RID_INT_N_1:
3078 case RID_INT_N_2:
3079 case RID_INT_N_3:
3080 if (!typespec_ok)
3081 goto out;
3082 attrs_ok = true;
3083 seen_type = true;
3084 if (c_dialect_objc ())
3085 parser->objc_need_raw_identifier = true;
3086 t.kind = ctsk_resword;
3087 t.spec = c_parser_peek_token (parser)->value;
3088 t.expr = NULL_TREE;
3089 t.expr_const_operands = true;
3090 declspecs_add_type (loc, specs, t);
3091 c_parser_consume_token (parser);
3092 break;
3093 case RID_ENUM:
3094 if (!typespec_ok)
3095 goto out;
3096 attrs_ok = true;
3097 seen_type = true;
3098 t = c_parser_enum_specifier (parser);
3099 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
3100 declspecs_add_type (loc, specs, t);
3101 break;
3102 case RID_STRUCT:
3103 case RID_UNION:
3104 if (!typespec_ok)
3105 goto out;
3106 attrs_ok = true;
3107 seen_type = true;
3108 t = c_parser_struct_or_union_specifier (parser);
3109 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
3110 declspecs_add_type (loc, specs, t);
3111 break;
3112 case RID_TYPEOF:
3113 case RID_TYPEOF_UNQUAL:
3114 /* ??? The old parser rejected typeof after other type
3115 specifiers, but is a syntax error the best way of
3116 handling this? */
3117 if (!typespec_ok || seen_type)
3118 goto out;
3119 attrs_ok = true;
3120 seen_type = true;
3121 t = c_parser_typeof_specifier (parser);
3122 declspecs_add_type (loc, specs, t);
3123 break;
3124 case RID_ATOMIC:
3125 /* C parser handling of Objective-C constructs needs
3126 checking for correct lvalue-to-rvalue conversions, and
3127 the code in build_modify_expr handling various
3128 Objective-C cases, and that in build_unary_op handling
3129 Objective-C cases for increment / decrement, also needs
3130 updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
3131 and objc_types_are_equivalent may also need updates. */
3132 if (c_dialect_objc ())
3133 sorry ("%<_Atomic%> in Objective-C");
3134 if (flag_isoc99)
3135 pedwarn_c99 (loc, OPT_Wpedantic,
3136 "ISO C99 does not support the %<_Atomic%> qualifier");
3137 else
3138 pedwarn_c99 (loc, OPT_Wpedantic,
3139 "ISO C90 does not support the %<_Atomic%> qualifier");
3140 attrs_ok = true;
3141 tree value;
3142 value = c_parser_peek_token (parser)->value;
3143 c_parser_consume_token (parser);
3144 if (typespec_ok && c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3145 {
3146 /* _Atomic ( type-name ). */
3147 seen_type = true;
3148 c_parser_consume_token (parser);
3149 struct c_type_name *type = c_parser_type_name (parser);
3150 t.kind = ctsk_typeof;
3151 t.spec = error_mark_node;
3152 t.expr = NULL_TREE;
3153 t.expr_const_operands = true;
3154 if (type != NULL)
3155 t.spec = groktypename (type, &t.expr,
3156 &t.expr_const_operands);
3157 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3158 "expected %<)%>");
3159 if (t.spec != error_mark_node)
3160 {
3161 if (TREE_CODE (t.spec) == ARRAY_TYPE)
3162 error_at (loc, "%<_Atomic%>-qualified array type");
3163 else if (TREE_CODE (t.spec) == FUNCTION_TYPE)
3164 error_at (loc, "%<_Atomic%>-qualified function type");
3165 else if (TYPE_QUALS (t.spec) != TYPE_UNQUALIFIED)
3166 error_at (loc, "%<_Atomic%> applied to a qualified type");
3167 else
3168 t.spec = c_build_qualified_type (t.spec, TYPE_QUAL_ATOMIC);
3169 }
3170 declspecs_add_type (loc, specs, t);
3171 }
3172 else
3173 declspecs_add_qual (loc, specs, value);
3174 break;
3175 case RID_CONST:
3176 case RID_VOLATILE:
3177 case RID_RESTRICT:
3178 attrs_ok = true;
3179 declspecs_add_qual (loc, specs, c_parser_peek_token (parser)->value);
3180 c_parser_consume_token (parser);
3181 break;
3182 case RID_ATTRIBUTE:
3183 if (!attrs_ok)
3184 goto out;
3185 attrs = c_parser_gnu_attributes (parser);
3186 declspecs_add_attrs (loc, specs, attrs);
3187 break;
3188 case RID_ALIGNAS:
3189 if (!alignspec_ok)
3190 goto out;
3191 align = c_parser_alignas_specifier (parser);
3192 declspecs_add_alignas (loc, specs, align);
3193 break;
3194 case RID_GIMPLE:
3195 if (! flag_gimple)
3196 error_at (loc, "%<__GIMPLE%> only valid with %<-fgimple%>");
3197 c_parser_consume_token (parser);
3198 specs->declspec_il = cdil_gimple;
3199 specs->locations[cdw_gimple] = loc;
3200 c_parser_gimple_or_rtl_pass_list (parser, specs);
3201 break;
3202 case RID_RTL:
3203 c_parser_consume_token (parser);
3204 specs->declspec_il = cdil_rtl;
3205 specs->locations[cdw_rtl] = loc;
3206 c_parser_gimple_or_rtl_pass_list (parser, specs);
3207 break;
3208 default:
3209 goto out;
3210 }
3211 }
3212 out:
3213 if (end_std_attr_ok
3214 && c_parser_nth_token_starts_std_attributes (parser, 1))
3215 specs->postfix_attrs = c_parser_std_attribute_specifier_sequence (parser);
3216 }
3217
3218 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
3219
3220 enum-specifier:
3221 enum gnu-attributes[opt] identifier[opt] { enumerator-list }
3222 gnu-attributes[opt]
3223 enum gnu-attributes[opt] identifier[opt] { enumerator-list , }
3224 gnu-attributes[opt]
3225 enum gnu-attributes[opt] identifier
3226
3227 The form with trailing comma is new in C99. The forms with
3228 gnu-attributes are GNU extensions. In GNU C, we accept any expression
3229 without commas in the syntax (assignment expressions, not just
3230 conditional expressions); assignment expressions will be diagnosed
3231 as non-constant.
3232
3233 enumerator-list:
3234 enumerator
3235 enumerator-list , enumerator
3236
3237 enumerator:
3238 enumeration-constant attribute-specifier-sequence[opt]
3239 enumeration-constant attribute-specifier-sequence[opt]
3240 = constant-expression
3241
3242 GNU Extensions:
3243
3244 enumerator:
3245 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3246 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3247 = constant-expression
3248
3249 */
3250
3251 static struct c_typespec
3252 c_parser_enum_specifier (c_parser *parser)
3253 {
3254 struct c_typespec ret;
3255 bool have_std_attrs;
3256 tree std_attrs = NULL_TREE;
3257 tree attrs;
3258 tree ident = NULL_TREE;
3259 location_t enum_loc;
3260 location_t ident_loc = UNKNOWN_LOCATION; /* Quiet warning. */
3261 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ENUM));
3262 c_parser_consume_token (parser);
3263 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3264 if (have_std_attrs)
3265 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3266 attrs = c_parser_gnu_attributes (parser);
3267 enum_loc = c_parser_peek_token (parser)->location;
3268 /* Set the location in case we create a decl now. */
3269 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3270 if (c_parser_next_token_is (parser, CPP_NAME))
3271 {
3272 ident = c_parser_peek_token (parser)->value;
3273 ident_loc = c_parser_peek_token (parser)->location;
3274 enum_loc = ident_loc;
3275 c_parser_consume_token (parser);
3276 }
3277 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3278 {
3279 /* Parse an enum definition. */
3280 struct c_enum_contents the_enum;
3281 tree type;
3282 tree postfix_attrs;
3283 /* We chain the enumerators in reverse order, then put them in
3284 forward order at the end. */
3285 tree values;
3286 timevar_push (TV_PARSE_ENUM);
3287 type = start_enum (enum_loc, &the_enum, ident);
3288 values = NULL_TREE;
3289 c_parser_consume_token (parser);
3290 while (true)
3291 {
3292 tree enum_id;
3293 tree enum_value;
3294 tree enum_decl;
3295 bool seen_comma;
3296 c_token *token;
3297 location_t comma_loc = UNKNOWN_LOCATION; /* Quiet warning. */
3298 location_t decl_loc, value_loc;
3299 if (c_parser_next_token_is_not (parser, CPP_NAME))
3300 {
3301 /* Give a nicer error for "enum {}". */
3302 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3303 && !parser->error)
3304 {
3305 error_at (c_parser_peek_token (parser)->location,
3306 "empty enum is invalid");
3307 parser->error = true;
3308 }
3309 else
3310 c_parser_error (parser, "expected identifier");
3311 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3312 values = error_mark_node;
3313 break;
3314 }
3315 token = c_parser_peek_token (parser);
3316 enum_id = token->value;
3317 /* Set the location in case we create a decl now. */
3318 c_parser_set_source_position_from_token (token);
3319 decl_loc = value_loc = token->location;
3320 c_parser_consume_token (parser);
3321 /* Parse any specified attributes. */
3322 tree std_attrs = NULL_TREE;
3323 if (c_parser_nth_token_starts_std_attributes (parser, 1))
3324 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3325 tree enum_attrs = chainon (std_attrs,
3326 c_parser_gnu_attributes (parser));
3327 if (c_parser_next_token_is (parser, CPP_EQ))
3328 {
3329 c_parser_consume_token (parser);
3330 value_loc = c_parser_peek_token (parser)->location;
3331 enum_value = c_parser_expr_no_commas (parser, NULL).value;
3332 }
3333 else
3334 enum_value = NULL_TREE;
3335 enum_decl = build_enumerator (decl_loc, value_loc,
3336 &the_enum, enum_id, enum_value);
3337 if (enum_attrs)
3338 decl_attributes (&TREE_PURPOSE (enum_decl), enum_attrs, 0);
3339 TREE_CHAIN (enum_decl) = values;
3340 values = enum_decl;
3341 seen_comma = false;
3342 if (c_parser_next_token_is (parser, CPP_COMMA))
3343 {
3344 comma_loc = c_parser_peek_token (parser)->location;
3345 seen_comma = true;
3346 c_parser_consume_token (parser);
3347 }
3348 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3349 {
3350 if (seen_comma)
3351 pedwarn_c90 (comma_loc, OPT_Wpedantic,
3352 "comma at end of enumerator list");
3353 c_parser_consume_token (parser);
3354 break;
3355 }
3356 if (!seen_comma)
3357 {
3358 c_parser_error (parser, "expected %<,%> or %<}%>");
3359 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3360 values = error_mark_node;
3361 break;
3362 }
3363 }
3364 postfix_attrs = c_parser_gnu_attributes (parser);
3365 ret.spec = finish_enum (type, nreverse (values),
3366 chainon (std_attrs,
3367 chainon (attrs, postfix_attrs)));
3368 ret.kind = ctsk_tagdef;
3369 ret.expr = NULL_TREE;
3370 ret.expr_const_operands = true;
3371 timevar_pop (TV_PARSE_ENUM);
3372 return ret;
3373 }
3374 else if (!ident)
3375 {
3376 c_parser_error (parser, "expected %<{%>");
3377 ret.spec = error_mark_node;
3378 ret.kind = ctsk_tagref;
3379 ret.expr = NULL_TREE;
3380 ret.expr_const_operands = true;
3381 return ret;
3382 }
3383 /* Attributes may only appear when the members are defined or in
3384 certain forward declarations (treat enum forward declarations in
3385 GNU C analogously to struct and union forward declarations in
3386 standard C). */
3387 if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3388 c_parser_error (parser, "expected %<;%>");
3389 ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident, have_std_attrs,
3390 std_attrs);
3391 /* In ISO C, enumerated types can be referred to only if already
3392 defined. */
3393 if (pedantic && !COMPLETE_TYPE_P (ret.spec))
3394 {
3395 gcc_assert (ident);
3396 pedwarn (enum_loc, OPT_Wpedantic,
3397 "ISO C forbids forward references to %<enum%> types");
3398 }
3399 return ret;
3400 }
3401
3402 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3403
3404 struct-or-union-specifier:
3405 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3406 identifier[opt] { struct-contents } gnu-attributes[opt]
3407 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3408 identifier
3409
3410 struct-contents:
3411 struct-declaration-list
3412
3413 struct-declaration-list:
3414 struct-declaration ;
3415 struct-declaration-list struct-declaration ;
3416
3417 GNU extensions:
3418
3419 struct-contents:
3420 empty
3421 struct-declaration
3422 struct-declaration-list struct-declaration
3423
3424 struct-declaration-list:
3425 struct-declaration-list ;
3426 ;
3427
3428 (Note that in the syntax here, unlike that in ISO C, the semicolons
3429 are included here rather than in struct-declaration, in order to
3430 describe the syntax with extra semicolons and missing semicolon at
3431 end.)
3432
3433 Objective-C:
3434
3435 struct-declaration-list:
3436 @defs ( class-name )
3437
3438 (Note this does not include a trailing semicolon, but can be
3439 followed by further declarations, and gets a pedwarn-if-pedantic
3440 when followed by a semicolon.) */
3441
3442 static struct c_typespec
3443 c_parser_struct_or_union_specifier (c_parser *parser)
3444 {
3445 struct c_typespec ret;
3446 bool have_std_attrs;
3447 tree std_attrs = NULL_TREE;
3448 tree attrs;
3449 tree ident = NULL_TREE;
3450 location_t struct_loc;
3451 location_t ident_loc = UNKNOWN_LOCATION;
3452 enum tree_code code;
3453 switch (c_parser_peek_token (parser)->keyword)
3454 {
3455 case RID_STRUCT:
3456 code = RECORD_TYPE;
3457 break;
3458 case RID_UNION:
3459 code = UNION_TYPE;
3460 break;
3461 default:
3462 gcc_unreachable ();
3463 }
3464 struct_loc = c_parser_peek_token (parser)->location;
3465 c_parser_consume_token (parser);
3466 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3467 if (have_std_attrs)
3468 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3469 attrs = c_parser_gnu_attributes (parser);
3470
3471 /* Set the location in case we create a decl now. */
3472 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3473
3474 if (c_parser_next_token_is (parser, CPP_NAME))
3475 {
3476 ident = c_parser_peek_token (parser)->value;
3477 ident_loc = c_parser_peek_token (parser)->location;
3478 struct_loc = ident_loc;
3479 c_parser_consume_token (parser);
3480 }
3481 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3482 {
3483 /* Parse a struct or union definition. Start the scope of the
3484 tag before parsing components. */
3485 class c_struct_parse_info *struct_info;
3486 tree type = start_struct (struct_loc, code, ident, &struct_info);
3487 tree postfix_attrs;
3488 /* We chain the components in reverse order, then put them in
3489 forward order at the end. Each struct-declaration may
3490 declare multiple components (comma-separated), so we must use
3491 chainon to join them, although when parsing each
3492 struct-declaration we can use TREE_CHAIN directly.
3493
3494 The theory behind all this is that there will be more
3495 semicolon separated fields than comma separated fields, and
3496 so we'll be minimizing the number of node traversals required
3497 by chainon. */
3498 tree contents;
3499 timevar_push (TV_PARSE_STRUCT);
3500 contents = NULL_TREE;
3501 c_parser_consume_token (parser);
3502 /* Handle the Objective-C @defs construct,
3503 e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
3504 if (c_parser_next_token_is_keyword (parser, RID_AT_DEFS))
3505 {
3506 tree name;
3507 gcc_assert (c_dialect_objc ());
3508 c_parser_consume_token (parser);
3509 matching_parens parens;
3510 if (!parens.require_open (parser))
3511 goto end_at_defs;
3512 if (c_parser_next_token_is (parser, CPP_NAME)
3513 && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)
3514 {
3515 name = c_parser_peek_token (parser)->value;
3516 c_parser_consume_token (parser);
3517 }
3518 else
3519 {
3520 c_parser_error (parser, "expected class name");
3521 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
3522 goto end_at_defs;
3523 }
3524 parens.skip_until_found_close (parser);
3525 contents = nreverse (objc_get_class_ivars (name));
3526 }
3527 end_at_defs:
3528 /* Parse the struct-declarations and semicolons. Problems with
3529 semicolons are diagnosed here; empty structures are diagnosed
3530 elsewhere. */
3531 while (true)
3532 {
3533 tree decls;
3534 /* Parse any stray semicolon. */
3535 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3536 {
3537 location_t semicolon_loc
3538 = c_parser_peek_token (parser)->location;
3539 gcc_rich_location richloc (semicolon_loc);
3540 richloc.add_fixit_remove ();
3541 pedwarn (&richloc, OPT_Wpedantic,
3542 "extra semicolon in struct or union specified");
3543 c_parser_consume_token (parser);
3544 continue;
3545 }
3546 /* Stop if at the end of the struct or union contents. */
3547 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3548 {
3549 c_parser_consume_token (parser);
3550 break;
3551 }
3552 /* Accept #pragmas at struct scope. */
3553 if (c_parser_next_token_is (parser, CPP_PRAGMA))
3554 {
3555 c_parser_pragma (parser, pragma_struct, NULL);
3556 continue;
3557 }
3558 /* Parse some comma-separated declarations, but not the
3559 trailing semicolon if any. */
3560 decls = c_parser_struct_declaration (parser);
3561 contents = chainon (decls, contents);
3562 /* If no semicolon follows, either we have a parse error or
3563 are at the end of the struct or union and should
3564 pedwarn. */
3565 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3566 c_parser_consume_token (parser);
3567 else
3568 {
3569 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3570 pedwarn (c_parser_peek_token (parser)->location, 0,
3571 "no semicolon at end of struct or union");
3572 else if (parser->error
3573 || !c_parser_next_token_starts_declspecs (parser))
3574 {
3575 c_parser_error (parser, "expected %<;%>");
3576 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3577 break;
3578 }
3579
3580 /* If we come here, we have already emitted an error
3581 for an expected `;', identifier or `(', and we also
3582 recovered already. Go on with the next field. */
3583 }
3584 }
3585 postfix_attrs = c_parser_gnu_attributes (parser);
3586 ret.spec = finish_struct (struct_loc, type, nreverse (contents),
3587 chainon (std_attrs,
3588 chainon (attrs, postfix_attrs)),
3589 struct_info);
3590 ret.kind = ctsk_tagdef;
3591 ret.expr = NULL_TREE;
3592 ret.expr_const_operands = true;
3593 timevar_pop (TV_PARSE_STRUCT);
3594 return ret;
3595 }
3596 else if (!ident)
3597 {
3598 c_parser_error (parser, "expected %<{%>");
3599 ret.spec = error_mark_node;
3600 ret.kind = ctsk_tagref;
3601 ret.expr = NULL_TREE;
3602 ret.expr_const_operands = true;
3603 return ret;
3604 }
3605 /* Attributes may only appear when the members are defined or in
3606 certain forward declarations. */
3607 if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3608 c_parser_error (parser, "expected %<;%>");
3609 /* ??? Existing practice is that GNU attributes are ignored after
3610 the struct or union keyword when not defining the members. */
3611 ret = parser_xref_tag (ident_loc, code, ident, have_std_attrs, std_attrs);
3612 return ret;
3613 }
3614
3615 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
3616 *without* the trailing semicolon.
3617
3618 struct-declaration:
3619 attribute-specifier-sequence[opt] specifier-qualifier-list
3620 attribute-specifier-sequence[opt] struct-declarator-list
3621 static_assert-declaration-no-semi
3622
3623 specifier-qualifier-list:
3624 type-specifier specifier-qualifier-list[opt]
3625 type-qualifier specifier-qualifier-list[opt]
3626 alignment-specifier specifier-qualifier-list[opt]
3627 gnu-attributes specifier-qualifier-list[opt]
3628
3629 struct-declarator-list:
3630 struct-declarator
3631 struct-declarator-list , gnu-attributes[opt] struct-declarator
3632
3633 struct-declarator:
3634 declarator gnu-attributes[opt]
3635 declarator[opt] : constant-expression gnu-attributes[opt]
3636
3637 GNU extensions:
3638
3639 struct-declaration:
3640 __extension__ struct-declaration
3641 specifier-qualifier-list
3642
3643 Unlike the ISO C syntax, semicolons are handled elsewhere. The use
3644 of gnu-attributes where shown is a GNU extension. In GNU C, we accept
3645 any expression without commas in the syntax (assignment
3646 expressions, not just conditional expressions); assignment
3647 expressions will be diagnosed as non-constant. */
3648
3649 static tree
3650 c_parser_struct_declaration (c_parser *parser)
3651 {
3652 struct c_declspecs *specs;
3653 tree prefix_attrs;
3654 tree all_prefix_attrs;
3655 tree decls;
3656 location_t decl_loc;
3657 if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
3658 {
3659 int ext;
3660 tree decl;
3661 ext = disable_extension_diagnostics ();
3662 c_parser_consume_token (parser);
3663 decl = c_parser_struct_declaration (parser);
3664 restore_extension_diagnostics (ext);
3665 return decl;
3666 }
3667 if (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
3668 {
3669 c_parser_static_assert_declaration_no_semi (parser);
3670 return NULL_TREE;
3671 }
3672 specs = build_null_declspecs ();
3673 decl_loc = c_parser_peek_token (parser)->location;
3674 /* Strictly by the standard, we shouldn't allow _Alignas here,
3675 but it appears to have been intended to allow it there, so
3676 we're keeping it as it is until WG14 reaches a conclusion
3677 of N1731.
3678 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */
3679 c_parser_declspecs (parser, specs, false, true, true,
3680 true, false, true, true, cla_nonabstract_decl);
3681 if (parser->error)
3682 return NULL_TREE;
3683 if (!specs->declspecs_seen_p)
3684 {
3685 c_parser_error (parser, "expected specifier-qualifier-list");
3686 return NULL_TREE;
3687 }
3688 finish_declspecs (specs);
3689 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3690 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3691 {
3692 tree ret;
3693 if (specs->typespec_kind == ctsk_none)
3694 {
3695 pedwarn (decl_loc, OPT_Wpedantic,
3696 "ISO C forbids member declarations with no members");
3697 shadow_tag_warned (specs, pedantic);
3698 ret = NULL_TREE;
3699 }
3700 else
3701 {
3702 /* Support for unnamed structs or unions as members of
3703 structs or unions (which is [a] useful and [b] supports
3704 MS P-SDK). */
3705 tree attrs = NULL;
3706
3707 ret = grokfield (c_parser_peek_token (parser)->location,
3708 build_id_declarator (NULL_TREE), specs,
3709 NULL_TREE, &attrs);
3710 if (ret)
3711 decl_attributes (&ret, attrs, 0);
3712 }
3713 return ret;
3714 }
3715
3716 /* Provide better error recovery. Note that a type name here is valid,
3717 and will be treated as a field name. */
3718 if (specs->typespec_kind == ctsk_tagdef
3719 && TREE_CODE (specs->type) != ENUMERAL_TYPE
3720 && c_parser_next_token_starts_declspecs (parser)
3721 && !c_parser_next_token_is (parser, CPP_NAME))
3722 {
3723 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
3724 parser->error = false;
3725 return NULL_TREE;
3726 }
3727
3728 pending_xref_error ();
3729 prefix_attrs = specs->attrs;
3730 all_prefix_attrs = prefix_attrs;
3731 specs->attrs = NULL_TREE;
3732 decls = NULL_TREE;
3733 while (true)
3734 {
3735 /* Declaring one or more declarators or un-named bit-fields. */
3736 struct c_declarator *declarator;
3737 bool dummy = false;
3738 if (c_parser_next_token_is (parser, CPP_COLON))
3739 declarator = build_id_declarator (NULL_TREE);
3740 else
3741 declarator = c_parser_declarator (parser,
3742 specs->typespec_kind != ctsk_none,
3743 C_DTR_NORMAL, &dummy);
3744 if (declarator == NULL)
3745 {
3746 c_parser_skip_to_end_of_block_or_statement (parser);
3747 break;
3748 }
3749 if (c_parser_next_token_is (parser, CPP_COLON)
3750 || c_parser_next_token_is (parser, CPP_COMMA)
3751 || c_parser_next_token_is (parser, CPP_SEMICOLON)
3752 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3753 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3754 {
3755 tree postfix_attrs = NULL_TREE;
3756 tree width = NULL_TREE;
3757 tree d;
3758 if (c_parser_next_token_is (parser, CPP_COLON))
3759 {
3760 c_parser_consume_token (parser);
3761 width = c_parser_expr_no_commas (parser, NULL).value;
3762 }
3763 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3764 postfix_attrs = c_parser_gnu_attributes (parser);
3765 d = grokfield (c_parser_peek_token (parser)->location,
3766 declarator, specs, width, &all_prefix_attrs);
3767 decl_attributes (&d, chainon (postfix_attrs,
3768 all_prefix_attrs), 0);
3769 DECL_CHAIN (d) = decls;
3770 decls = d;
3771 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3772 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
3773 prefix_attrs);
3774 else
3775 all_prefix_attrs = prefix_attrs;
3776 if (c_parser_next_token_is (parser, CPP_COMMA))
3777 c_parser_consume_token (parser);
3778 else if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3779 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3780 {
3781 /* Semicolon consumed in caller. */
3782 break;
3783 }
3784 else
3785 {
3786 c_parser_error (parser, "expected %<,%>, %<;%> or %<}%>");
3787 break;
3788 }
3789 }
3790 else
3791 {
3792 c_parser_error (parser,
3793 "expected %<:%>, %<,%>, %<;%>, %<}%> or "
3794 "%<__attribute__%>");
3795 break;
3796 }
3797 }
3798 return decls;
3799 }
3800
3801 /* Parse a typeof specifier (a GNU extension adopted in C2X).
3802
3803 typeof-specifier:
3804 typeof ( expression )
3805 typeof ( type-name )
3806 typeof_unqual ( expression )
3807 typeof_unqual ( type-name )
3808 */
3809
3810 static struct c_typespec
3811 c_parser_typeof_specifier (c_parser *parser)
3812 {
3813 bool is_unqual;
3814 bool is_std;
3815 struct c_typespec ret;
3816 ret.kind = ctsk_typeof;
3817 ret.spec = error_mark_node;
3818 ret.expr = NULL_TREE;
3819 ret.expr_const_operands = true;
3820 if (c_parser_next_token_is_keyword (parser, RID_TYPEOF))
3821 {
3822 is_unqual = false;
3823 tree spelling = c_parser_peek_token (parser)->value;
3824 is_std = (flag_isoc2x
3825 && strcmp (IDENTIFIER_POINTER (spelling), "typeof") == 0);
3826 }
3827 else
3828 {
3829 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF_UNQUAL));
3830 is_unqual = true;
3831 is_std = true;
3832 }
3833 c_parser_consume_token (parser);
3834 c_inhibit_evaluation_warnings++;
3835 in_typeof++;
3836 matching_parens parens;
3837 if (!parens.require_open (parser))
3838 {
3839 c_inhibit_evaluation_warnings--;
3840 in_typeof--;
3841 return ret;
3842 }
3843 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
3844 {
3845 struct c_type_name *type = c_parser_type_name (parser);
3846 c_inhibit_evaluation_warnings--;
3847 in_typeof--;
3848 if (type != NULL)
3849 {
3850 ret.spec = groktypename (type, &ret.expr, &ret.expr_const_operands);
3851 pop_maybe_used (variably_modified_type_p (ret.spec, NULL_TREE));
3852 }
3853 }
3854 else
3855 {
3856 bool was_vm;
3857 location_t here = c_parser_peek_token (parser)->location;
3858 struct c_expr expr = c_parser_expression (parser);
3859 c_inhibit_evaluation_warnings--;
3860 in_typeof--;
3861 if (TREE_CODE (expr.value) == COMPONENT_REF
3862 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
3863 error_at (here, "%<typeof%> applied to a bit-field");
3864 mark_exp_read (expr.value);
3865 ret.spec = TREE_TYPE (expr.value);
3866 was_vm = variably_modified_type_p (ret.spec, NULL_TREE);
3867 /* This is returned with the type so that when the type is
3868 evaluated, this can be evaluated. */
3869 if (was_vm)
3870 ret.expr = c_fully_fold (expr.value, false, &ret.expr_const_operands);
3871 pop_maybe_used (was_vm);
3872 }
3873 parens.skip_until_found_close (parser);
3874 if (ret.spec != error_mark_node)
3875 {
3876 if (is_unqual && TYPE_QUALS (ret.spec) != TYPE_UNQUALIFIED)
3877 ret.spec = TYPE_MAIN_VARIANT (ret.spec);
3878 if (is_std)
3879 {
3880 /* In ISO C terms, _Noreturn is not part of the type of
3881 expressions such as &abort, but in GCC it is represented
3882 internally as a type qualifier. */
3883 if (TREE_CODE (ret.spec) == FUNCTION_TYPE
3884 && TYPE_QUALS (ret.spec) != TYPE_UNQUALIFIED)
3885 ret.spec = TYPE_MAIN_VARIANT (ret.spec);
3886 else if (FUNCTION_POINTER_TYPE_P (ret.spec)
3887 && TYPE_QUALS (TREE_TYPE (ret.spec)) != TYPE_UNQUALIFIED)
3888 ret.spec
3889 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (ret.spec)));
3890 }
3891 }
3892 return ret;
3893 }
3894
3895 /* Parse an alignment-specifier.
3896
3897 C11 6.7.5:
3898
3899 alignment-specifier:
3900 _Alignas ( type-name )
3901 _Alignas ( constant-expression )
3902 */
3903
3904 static tree
3905 c_parser_alignas_specifier (c_parser * parser)
3906 {
3907 tree ret = error_mark_node;
3908 location_t loc = c_parser_peek_token (parser)->location;
3909 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNAS));
3910 tree spelling = c_parser_peek_token (parser)->value;
3911 c_parser_consume_token (parser);
3912 if (flag_isoc99)
3913 pedwarn_c99 (loc, OPT_Wpedantic,
3914 "ISO C99 does not support %qE", spelling);
3915 else
3916 pedwarn_c99 (loc, OPT_Wpedantic,
3917 "ISO C90 does not support %qE", spelling);
3918 matching_parens parens;
3919 if (!parens.require_open (parser))
3920 return ret;
3921 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
3922 {
3923 struct c_type_name *type = c_parser_type_name (parser);
3924 if (type != NULL)
3925 ret = c_sizeof_or_alignof_type (loc, groktypename (type, NULL, NULL),
3926 false, true, 1);
3927 }
3928 else
3929 ret = c_parser_expr_no_commas (parser, NULL).value;
3930 parens.skip_until_found_close (parser);
3931 return ret;
3932 }
3933
3934 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
3935 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then
3936 a typedef name may be redeclared; otherwise it may not. KIND
3937 indicates which kind of declarator is wanted. Returns a valid
3938 declarator except in the case of a syntax error in which case NULL is
3939 returned. *SEEN_ID is set to true if an identifier being declared is
3940 seen; this is used to diagnose bad forms of abstract array declarators
3941 and to determine whether an identifier list is syntactically permitted.
3942
3943 declarator:
3944 pointer[opt] direct-declarator
3945
3946 direct-declarator:
3947 identifier
3948 ( gnu-attributes[opt] declarator )
3949 direct-declarator array-declarator
3950 direct-declarator ( parameter-type-list )
3951 direct-declarator ( identifier-list[opt] )
3952
3953 pointer:
3954 * type-qualifier-list[opt]
3955 * type-qualifier-list[opt] pointer
3956
3957 type-qualifier-list:
3958 type-qualifier
3959 gnu-attributes
3960 type-qualifier-list type-qualifier
3961 type-qualifier-list gnu-attributes
3962
3963 array-declarator:
3964 [ type-qualifier-list[opt] assignment-expression[opt] ]
3965 [ static type-qualifier-list[opt] assignment-expression ]
3966 [ type-qualifier-list static assignment-expression ]
3967 [ type-qualifier-list[opt] * ]
3968
3969 parameter-type-list:
3970 parameter-list
3971 parameter-list , ...
3972
3973 parameter-list:
3974 parameter-declaration
3975 parameter-list , parameter-declaration
3976
3977 parameter-declaration:
3978 declaration-specifiers declarator gnu-attributes[opt]
3979 declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
3980
3981 identifier-list:
3982 identifier
3983 identifier-list , identifier
3984
3985 abstract-declarator:
3986 pointer
3987 pointer[opt] direct-abstract-declarator
3988
3989 direct-abstract-declarator:
3990 ( gnu-attributes[opt] abstract-declarator )
3991 direct-abstract-declarator[opt] array-declarator
3992 direct-abstract-declarator[opt] ( parameter-type-list[opt] )
3993
3994 GNU extensions:
3995
3996 direct-declarator:
3997 direct-declarator ( parameter-forward-declarations
3998 parameter-type-list[opt] )
3999
4000 direct-abstract-declarator:
4001 direct-abstract-declarator[opt] ( parameter-forward-declarations
4002 parameter-type-list[opt] )
4003
4004 parameter-forward-declarations:
4005 parameter-list ;
4006 parameter-forward-declarations parameter-list ;
4007
4008 The uses of gnu-attributes shown above are GNU extensions.
4009
4010 Some forms of array declarator are not included in C99 in the
4011 syntax for abstract declarators; these are disallowed elsewhere.
4012 This may be a defect (DR#289).
4013
4014 This function also accepts an omitted abstract declarator as being
4015 an abstract declarator, although not part of the formal syntax. */
4016
4017 struct c_declarator *
4018 c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
4019 bool *seen_id)
4020 {
4021 /* Parse any initial pointer part. */
4022 if (c_parser_next_token_is (parser, CPP_MULT))
4023 {
4024 struct c_declspecs *quals_attrs = build_null_declspecs ();
4025 struct c_declarator *inner;
4026 c_parser_consume_token (parser);
4027 c_parser_declspecs (parser, quals_attrs, false, false, true,
4028 false, false, true, false, cla_prefer_id);
4029 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
4030 if (inner == NULL)
4031 return NULL;
4032 else
4033 return make_pointer_declarator (quals_attrs, inner);
4034 }
4035 /* Now we have a direct declarator, direct abstract declarator or
4036 nothing (which counts as a direct abstract declarator here). */
4037 return c_parser_direct_declarator (parser, type_seen_p, kind, seen_id);
4038 }
4039
4040 /* Parse a direct declarator or direct abstract declarator; arguments
4041 as c_parser_declarator. */
4042
4043 static struct c_declarator *
4044 c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
4045 bool *seen_id)
4046 {
4047 /* The direct declarator must start with an identifier (possibly
4048 omitted) or a parenthesized declarator (possibly abstract). In
4049 an ordinary declarator, initial parentheses must start a
4050 parenthesized declarator. In an abstract declarator or parameter
4051 declarator, they could start a parenthesized declarator or a
4052 parameter list. To tell which, the open parenthesis and any
4053 following gnu-attributes must be read. If a declaration
4054 specifier or standard attributes follow, then it is a parameter
4055 list; if the specifier is a typedef name, there might be an
4056 ambiguity about redeclaring it, which is resolved in the
4057 direction of treating it as a typedef name. If a close
4058 parenthesis follows, it is also an empty parameter list, as the
4059 syntax does not permit empty abstract declarators. Otherwise, it
4060 is a parenthesized declarator (in which case the analysis may be
4061 repeated inside it, recursively).
4062
4063 ??? There is an ambiguity in a parameter declaration "int
4064 (__attribute__((foo)) x)", where x is not a typedef name: it
4065 could be an abstract declarator for a function, or declare x with
4066 parentheses. The proper resolution of this ambiguity needs
4067 documenting. At present we follow an accident of the old
4068 parser's implementation, whereby the first parameter must have
4069 some declaration specifiers other than just gnu-attributes. Thus as
4070 a parameter declaration it is treated as a parenthesized
4071 parameter named x, and as an abstract declarator it is
4072 rejected.
4073
4074 ??? Also following the old parser, gnu-attributes inside an empty
4075 parameter list are ignored, making it a list not yielding a
4076 prototype, rather than giving an error or making it have one
4077 parameter with implicit type int.
4078
4079 ??? Also following the old parser, typedef names may be
4080 redeclared in declarators, but not Objective-C class names. */
4081
4082 if (kind != C_DTR_ABSTRACT
4083 && c_parser_next_token_is (parser, CPP_NAME)
4084 && ((type_seen_p
4085 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
4086 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
4087 || c_parser_peek_token (parser)->id_kind == C_ID_ID))
4088 {
4089 struct c_declarator *inner
4090 = build_id_declarator (c_parser_peek_token (parser)->value);
4091 *seen_id = true;
4092 inner->id_loc = c_parser_peek_token (parser)->location;
4093 c_parser_consume_token (parser);
4094 if (c_parser_nth_token_starts_std_attributes (parser, 1))
4095 inner->u.id.attrs = c_parser_std_attribute_specifier_sequence (parser);
4096 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
4097 }
4098
4099 if (kind != C_DTR_NORMAL
4100 && c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
4101 && !c_parser_nth_token_starts_std_attributes (parser, 1))
4102 {
4103 struct c_declarator *inner = build_id_declarator (NULL_TREE);
4104 inner->id_loc = c_parser_peek_token (parser)->location;
4105 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
4106 }
4107
4108 /* Either we are at the end of an abstract declarator, or we have
4109 parentheses. */
4110
4111 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
4112 {
4113 tree attrs;
4114 struct c_declarator *inner;
4115 c_parser_consume_token (parser);
4116 bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
4117 RID_ATTRIBUTE);
4118 attrs = c_parser_gnu_attributes (parser);
4119 if (kind != C_DTR_NORMAL
4120 && (c_parser_next_token_starts_declspecs (parser)
4121 || (!have_gnu_attrs
4122 && c_parser_nth_token_starts_std_attributes (parser, 1))
4123 || c_parser_next_token_is (parser, CPP_CLOSE_PAREN)))
4124 {
4125 struct c_arg_info *args
4126 = c_parser_parms_declarator (parser, kind == C_DTR_NORMAL,
4127 attrs, have_gnu_attrs);
4128 if (args == NULL)
4129 return NULL;
4130 else
4131 {
4132 inner = build_id_declarator (NULL_TREE);
4133 if (!(args->types
4134 && args->types != error_mark_node
4135 && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
4136 && c_parser_nth_token_starts_std_attributes (parser, 1))
4137 {
4138 tree std_attrs
4139 = c_parser_std_attribute_specifier_sequence (parser);
4140 if (std_attrs)
4141 inner = build_attrs_declarator (std_attrs, inner);
4142 }
4143 inner = build_function_declarator (args, inner);
4144 return c_parser_direct_declarator_inner (parser, *seen_id,
4145 inner);
4146 }
4147 }
4148 /* A parenthesized declarator. */
4149 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
4150 if (inner != NULL && attrs != NULL)
4151 inner = build_attrs_declarator (attrs, inner);
4152 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4153 {
4154 c_parser_consume_token (parser);
4155 if (inner == NULL)
4156 return NULL;
4157 else
4158 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
4159 }
4160 else
4161 {
4162 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4163 "expected %<)%>");
4164 return NULL;
4165 }
4166 }
4167 else
4168 {
4169 if (kind == C_DTR_NORMAL)
4170 {
4171 c_parser_error (parser, "expected identifier or %<(%>");
4172 return NULL;
4173 }
4174 else
4175 return build_id_declarator (NULL_TREE);
4176 }
4177 }
4178
4179 /* Parse part of a direct declarator or direct abstract declarator,
4180 given that some (in INNER) has already been parsed; ID_PRESENT is
4181 true if an identifier is present, false for an abstract
4182 declarator. */
4183
4184 static struct c_declarator *
4185 c_parser_direct_declarator_inner (c_parser *parser, bool id_present,
4186 struct c_declarator *inner)
4187 {
4188 /* Parse a sequence of array declarators and parameter lists. */
4189 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
4190 && !c_parser_nth_token_starts_std_attributes (parser, 1))
4191 {
4192 location_t brace_loc = c_parser_peek_token (parser)->location;
4193 struct c_declarator *declarator;
4194 struct c_declspecs *quals_attrs = build_null_declspecs ();
4195 bool static_seen;
4196 bool star_seen;
4197 struct c_expr dimen;
4198 dimen.value = NULL_TREE;
4199 dimen.original_code = ERROR_MARK;
4200 dimen.original_type = NULL_TREE;
4201 c_parser_consume_token (parser);
4202 c_parser_declspecs (parser, quals_attrs, false, false, true,
4203 false, false, false, false, cla_prefer_id);
4204 static_seen = c_parser_next_token_is_keyword (parser, RID_STATIC);
4205 if (static_seen)
4206 c_parser_consume_token (parser);
4207 if (static_seen && !quals_attrs->declspecs_seen_p)
4208 c_parser_declspecs (parser, quals_attrs, false, false, true,
4209 false, false, false, false, cla_prefer_id);
4210 if (!quals_attrs->declspecs_seen_p)
4211 quals_attrs = NULL;
4212 /* If "static" is present, there must be an array dimension.
4213 Otherwise, there may be a dimension, "*", or no
4214 dimension. */
4215 if (static_seen)
4216 {
4217 star_seen = false;
4218 dimen = c_parser_expr_no_commas (parser, NULL);
4219 }
4220 else
4221 {
4222 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4223 {
4224 dimen.value = NULL_TREE;
4225 star_seen = false;
4226 }
4227 else if (c_parser_next_token_is (parser, CPP_MULT))
4228 {
4229 if (c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_SQUARE)
4230 {
4231 dimen.value = NULL_TREE;
4232 star_seen = true;
4233 c_parser_consume_token (parser);
4234 }
4235 else
4236 {
4237 star_seen = false;
4238 dimen = c_parser_expr_no_commas (parser, NULL);
4239 }
4240 }
4241 else
4242 {
4243 star_seen = false;
4244 dimen = c_parser_expr_no_commas (parser, NULL);
4245 }
4246 }
4247 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4248 c_parser_consume_token (parser);
4249 else
4250 {
4251 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
4252 "expected %<]%>");
4253 return NULL;
4254 }
4255 if (dimen.value)
4256 dimen = convert_lvalue_to_rvalue (brace_loc, dimen, true, true);
4257 declarator = build_array_declarator (brace_loc, dimen.value, quals_attrs,
4258 static_seen, star_seen);
4259 if (declarator == NULL)
4260 return NULL;
4261 if (c_parser_nth_token_starts_std_attributes (parser, 1))
4262 {
4263 tree std_attrs
4264 = c_parser_std_attribute_specifier_sequence (parser);
4265 if (std_attrs)
4266 inner = build_attrs_declarator (std_attrs, inner);
4267 }
4268 inner = set_array_declarator_inner (declarator, inner);
4269 return c_parser_direct_declarator_inner (parser, id_present, inner);
4270 }
4271 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
4272 {
4273 tree attrs;
4274 struct c_arg_info *args;
4275 c_parser_consume_token (parser);
4276 bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
4277 RID_ATTRIBUTE);
4278 attrs = c_parser_gnu_attributes (parser);
4279 args = c_parser_parms_declarator (parser, id_present, attrs,
4280 have_gnu_attrs);
4281 if (args == NULL)
4282 return NULL;
4283 else
4284 {
4285 if (!(args->types
4286 && args->types != error_mark_node
4287 && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
4288 && c_parser_nth_token_starts_std_attributes (parser, 1))
4289 {
4290 tree std_attrs
4291 = c_parser_std_attribute_specifier_sequence (parser);
4292 if (std_attrs)
4293 inner = build_attrs_declarator (std_attrs, inner);
4294 }
4295 inner = build_function_declarator (args, inner);
4296 return c_parser_direct_declarator_inner (parser, id_present, inner);
4297 }
4298 }
4299 return inner;
4300 }
4301
4302 /* Parse a parameter list or identifier list, including the closing
4303 parenthesis but not the opening one. ATTRS are the gnu-attributes
4304 at the start of the list. ID_LIST_OK is true if an identifier list
4305 is acceptable; such a list must not have attributes at the start.
4306 HAVE_GNU_ATTRS says whether any gnu-attributes (including empty
4307 attributes) were present (in which case standard attributes cannot
4308 occur). */
4309
4310 static struct c_arg_info *
4311 c_parser_parms_declarator (c_parser *parser, bool id_list_ok, tree attrs,
4312 bool have_gnu_attrs)
4313 {
4314 push_scope ();
4315 declare_parm_level ();
4316 /* If the list starts with an identifier, it is an identifier list.
4317 Otherwise, it is either a prototype list or an empty list. */
4318 if (id_list_ok
4319 && !attrs
4320 && c_parser_next_token_is (parser, CPP_NAME)
4321 && c_parser_peek_token (parser)->id_kind == C_ID_ID
4322
4323 /* Look ahead to detect typos in type names. */
4324 && c_parser_peek_2nd_token (parser)->type != CPP_NAME
4325 && c_parser_peek_2nd_token (parser)->type != CPP_MULT
4326 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
4327 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_SQUARE
4328 && c_parser_peek_2nd_token (parser)->type != CPP_KEYWORD)
4329 {
4330 tree list = NULL_TREE, *nextp = &list;
4331 while (c_parser_next_token_is (parser, CPP_NAME)
4332 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
4333 {
4334 *nextp = build_tree_list (NULL_TREE,
4335 c_parser_peek_token (parser)->value);
4336 nextp = & TREE_CHAIN (*nextp);
4337 c_parser_consume_token (parser);
4338 if (c_parser_next_token_is_not (parser, CPP_COMMA))
4339 break;
4340 c_parser_consume_token (parser);
4341 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4342 {
4343 c_parser_error (parser, "expected identifier");
4344 break;
4345 }
4346 }
4347 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4348 {
4349 struct c_arg_info *ret = build_arg_info ();
4350 ret->types = list;
4351 c_parser_consume_token (parser);
4352 pop_scope ();
4353 return ret;
4354 }
4355 else
4356 {
4357 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4358 "expected %<)%>");
4359 pop_scope ();
4360 return NULL;
4361 }
4362 }
4363 else
4364 {
4365 struct c_arg_info *ret
4366 = c_parser_parms_list_declarator (parser, attrs, NULL, have_gnu_attrs);
4367 pop_scope ();
4368 return ret;
4369 }
4370 }
4371
4372 /* Parse a parameter list (possibly empty), including the closing
4373 parenthesis but not the opening one. ATTRS are the gnu-attributes
4374 at the start of the list; if HAVE_GNU_ATTRS, there were some such
4375 attributes (possibly empty, in which case ATTRS is NULL_TREE),
4376 which means standard attributes cannot start the list. EXPR is
4377 NULL or an expression that needs to be evaluated for the side
4378 effects of array size expressions in the parameters. */
4379
4380 static struct c_arg_info *
4381 c_parser_parms_list_declarator (c_parser *parser, tree attrs, tree expr,
4382 bool have_gnu_attrs)
4383 {
4384 bool bad_parm = false;
4385
4386 /* ??? Following the old parser, forward parameter declarations may
4387 use abstract declarators, and if no real parameter declarations
4388 follow the forward declarations then this is not diagnosed. Also
4389 note as above that gnu-attributes are ignored as the only contents of
4390 the parentheses, or as the only contents after forward
4391 declarations. */
4392 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4393 {
4394 struct c_arg_info *ret = build_arg_info ();
4395 c_parser_consume_token (parser);
4396 return ret;
4397 }
4398 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4399 {
4400 struct c_arg_info *ret = build_arg_info ();
4401
4402 if (flag_allow_parameterless_variadic_functions)
4403 {
4404 /* F (...) is allowed. */
4405 ret->types = NULL_TREE;
4406 }
4407 else
4408 {
4409 /* Suppress -Wold-style-definition for this case. */
4410 ret->types = error_mark_node;
4411 error_at (c_parser_peek_token (parser)->location,
4412 "ISO C requires a named argument before %<...%>");
4413 }
4414 c_parser_consume_token (parser);
4415 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4416 {
4417 c_parser_consume_token (parser);
4418 return ret;
4419 }
4420 else
4421 {
4422 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4423 "expected %<)%>");
4424 return NULL;
4425 }
4426 }
4427 /* Nonempty list of parameters, either terminated with semicolon
4428 (forward declarations; recurse) or with close parenthesis (normal
4429 function) or with ", ... )" (variadic function). */
4430 while (true)
4431 {
4432 /* Parse a parameter. */
4433 struct c_parm *parm = c_parser_parameter_declaration (parser, attrs,
4434 have_gnu_attrs);
4435 attrs = NULL_TREE;
4436 have_gnu_attrs = false;
4437 if (parm == NULL)
4438 bad_parm = true;
4439 else
4440 push_parm_decl (parm, &expr);
4441 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4442 {
4443 tree new_attrs;
4444 c_parser_consume_token (parser);
4445 mark_forward_parm_decls ();
4446 bool new_have_gnu_attrs
4447 = c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE);
4448 new_attrs = c_parser_gnu_attributes (parser);
4449 return c_parser_parms_list_declarator (parser, new_attrs, expr,
4450 new_have_gnu_attrs);
4451 }
4452 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4453 {
4454 c_parser_consume_token (parser);
4455 if (bad_parm)
4456 return NULL;
4457 else
4458 return get_parm_info (false, expr);
4459 }
4460 if (!c_parser_require (parser, CPP_COMMA,
4461 "expected %<;%>, %<,%> or %<)%>",
4462 UNKNOWN_LOCATION, false))
4463 {
4464 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4465 return NULL;
4466 }
4467 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4468 {
4469 c_parser_consume_token (parser);
4470 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4471 {
4472 c_parser_consume_token (parser);
4473 if (bad_parm)
4474 return NULL;
4475 else
4476 return get_parm_info (true, expr);
4477 }
4478 else
4479 {
4480 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4481 "expected %<)%>");
4482 return NULL;
4483 }
4484 }
4485 }
4486 }
4487
4488 /* Parse a parameter declaration. ATTRS are the gnu-attributes at the
4489 start of the declaration if it is the first parameter;
4490 HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even
4491 empty) there. */
4492
4493 static struct c_parm *
4494 c_parser_parameter_declaration (c_parser *parser, tree attrs,
4495 bool have_gnu_attrs)
4496 {
4497 struct c_declspecs *specs;
4498 struct c_declarator *declarator;
4499 tree prefix_attrs;
4500 tree postfix_attrs = NULL_TREE;
4501 bool dummy = false;
4502
4503 /* Accept #pragmas between parameter declarations. */
4504 while (c_parser_next_token_is (parser, CPP_PRAGMA))
4505 c_parser_pragma (parser, pragma_param, NULL);
4506
4507 if (!c_parser_next_token_starts_declspecs (parser)
4508 && !c_parser_nth_token_starts_std_attributes (parser, 1))
4509 {
4510 c_token *token = c_parser_peek_token (parser);
4511 if (parser->error)
4512 return NULL;
4513 c_parser_set_source_position_from_token (token);
4514 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
4515 {
4516 auto_diagnostic_group d;
4517 name_hint hint = lookup_name_fuzzy (token->value,
4518 FUZZY_LOOKUP_TYPENAME,
4519 token->location);
4520 if (const char *suggestion = hint.suggestion ())
4521 {
4522 gcc_rich_location richloc (token->location);
4523 richloc.add_fixit_replace (suggestion);
4524 error_at (&richloc,
4525 "unknown type name %qE; did you mean %qs?",
4526 token->value, suggestion);
4527 }
4528 else
4529 error_at (token->location, "unknown type name %qE", token->value);
4530 parser->error = true;
4531 }
4532 /* ??? In some Objective-C cases '...' isn't applicable so there
4533 should be a different message. */
4534 else
4535 c_parser_error (parser,
4536 "expected declaration specifiers or %<...%>");
4537 c_parser_skip_to_end_of_parameter (parser);
4538 return NULL;
4539 }
4540
4541 location_t start_loc = c_parser_peek_token (parser)->location;
4542
4543 specs = build_null_declspecs ();
4544 if (attrs)
4545 {
4546 declspecs_add_attrs (input_location, specs, attrs);
4547 attrs = NULL_TREE;
4548 }
4549 c_parser_declspecs (parser, specs, true, true, true, true, false,
4550 !have_gnu_attrs, true, cla_nonabstract_decl);
4551 finish_declspecs (specs);
4552 pending_xref_error ();
4553 prefix_attrs = specs->attrs;
4554 specs->attrs = NULL_TREE;
4555 declarator = c_parser_declarator (parser,
4556 specs->typespec_kind != ctsk_none,
4557 C_DTR_PARM, &dummy);
4558 if (declarator == NULL)
4559 {
4560 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
4561 return NULL;
4562 }
4563 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4564 postfix_attrs = c_parser_gnu_attributes (parser);
4565
4566 /* Generate a location for the parameter, ranging from the start of the
4567 initial token to the end of the final token.
4568
4569 If we have a identifier, then use it for the caret location, e.g.
4570
4571 extern int callee (int one, int (*two)(int, int), float three);
4572 ~~~~~~^~~~~~~~~~~~~~
4573
4574 otherwise, reuse the start location for the caret location e.g.:
4575
4576 extern int callee (int one, int (*)(int, int), float three);
4577 ^~~~~~~~~~~~~~~~~
4578 */
4579 location_t end_loc = parser->last_token_location;
4580
4581 /* Find any cdk_id declarator; determine if we have an identifier. */
4582 c_declarator *id_declarator = declarator;
4583 while (id_declarator && id_declarator->kind != cdk_id)
4584 id_declarator = id_declarator->declarator;
4585 location_t caret_loc = (id_declarator->u.id.id
4586 ? id_declarator->id_loc
4587 : start_loc);
4588 location_t param_loc = make_location (caret_loc, start_loc, end_loc);
4589
4590 return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
4591 declarator, param_loc);
4592 }
4593
4594 /* Parse a string literal in an asm expression. It should not be
4595 translated, and wide string literals are an error although
4596 permitted by the syntax. This is a GNU extension.
4597
4598 asm-string-literal:
4599 string-literal
4600 */
4601
4602 static tree
4603 c_parser_asm_string_literal (c_parser *parser)
4604 {
4605 tree str;
4606 int save_flag = warn_overlength_strings;
4607 warn_overlength_strings = 0;
4608 str = c_parser_string_literal (parser, false, false).value;
4609 warn_overlength_strings = save_flag;
4610 return str;
4611 }
4612
4613 /* Parse a simple asm expression. This is used in restricted
4614 contexts, where a full expression with inputs and outputs does not
4615 make sense. This is a GNU extension.
4616
4617 simple-asm-expr:
4618 asm ( asm-string-literal )
4619 */
4620
4621 static tree
4622 c_parser_simple_asm_expr (c_parser *parser)
4623 {
4624 tree str;
4625 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
4626 c_parser_consume_token (parser);
4627 matching_parens parens;
4628 if (!parens.require_open (parser))
4629 return NULL_TREE;
4630 str = c_parser_asm_string_literal (parser);
4631 if (!parens.require_close (parser))
4632 {
4633 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4634 return NULL_TREE;
4635 }
4636 return str;
4637 }
4638
4639 static tree
4640 c_parser_gnu_attribute_any_word (c_parser *parser)
4641 {
4642 tree attr_name = NULL_TREE;
4643
4644 if (c_parser_next_token_is (parser, CPP_KEYWORD))
4645 {
4646 /* ??? See comment above about what keywords are accepted here. */
4647 bool ok;
4648 switch (c_parser_peek_token (parser)->keyword)
4649 {
4650 case RID_STATIC:
4651 case RID_UNSIGNED:
4652 case RID_LONG:
4653 case RID_CONST:
4654 case RID_EXTERN:
4655 case RID_REGISTER:
4656 case RID_TYPEDEF:
4657 case RID_SHORT:
4658 case RID_INLINE:
4659 case RID_NORETURN:
4660 case RID_VOLATILE:
4661 case RID_SIGNED:
4662 case RID_AUTO:
4663 case RID_RESTRICT:
4664 case RID_COMPLEX:
4665 case RID_THREAD:
4666 case RID_INT:
4667 case RID_CHAR:
4668 case RID_FLOAT:
4669 case RID_DOUBLE:
4670 case RID_VOID:
4671 case RID_DFLOAT32:
4672 case RID_DFLOAT64:
4673 case RID_DFLOAT128:
4674 CASE_RID_FLOATN_NX:
4675 case RID_BOOL:
4676 case RID_FRACT:
4677 case RID_ACCUM:
4678 case RID_SAT:
4679 case RID_TRANSACTION_ATOMIC:
4680 case RID_TRANSACTION_CANCEL:
4681 case RID_ATOMIC:
4682 case RID_AUTO_TYPE:
4683 case RID_INT_N_0:
4684 case RID_INT_N_1:
4685 case RID_INT_N_2:
4686 case RID_INT_N_3:
4687 ok = true;
4688 break;
4689 default:
4690 ok = false;
4691 break;
4692 }
4693 if (!ok)
4694 return NULL_TREE;
4695
4696 /* Accept __attribute__((__const)) as __attribute__((const)) etc. */
4697 attr_name = ridpointers[(int) c_parser_peek_token (parser)->keyword];
4698 }
4699 else if (c_parser_next_token_is (parser, CPP_NAME))
4700 attr_name = c_parser_peek_token (parser)->value;
4701
4702 return attr_name;
4703 }
4704
4705 /* Parse attribute arguments. This is a common form of syntax
4706 covering all currently valid GNU and standard attributes.
4707
4708 gnu-attribute-arguments:
4709 identifier
4710 identifier , nonempty-expr-list
4711 expr-list
4712
4713 where the "identifier" must not be declared as a type. ??? Why not
4714 allow identifiers declared as types to start the arguments? */
4715
4716 static tree
4717 c_parser_attribute_arguments (c_parser *parser, bool takes_identifier,
4718 bool require_string, bool assume_attr,
4719 bool allow_empty_args)
4720 {
4721 vec<tree, va_gc> *expr_list;
4722 tree attr_args;
4723 /* Parse the attribute contents. If they start with an
4724 identifier which is followed by a comma or close
4725 parenthesis, then the arguments start with that
4726 identifier; otherwise they are an expression list.
4727 In objective-c the identifier may be a classname. */
4728 if (c_parser_next_token_is (parser, CPP_NAME)
4729 && (c_parser_peek_token (parser)->id_kind == C_ID_ID
4730 || (c_dialect_objc ()
4731 && c_parser_peek_token (parser)->id_kind
4732 == C_ID_CLASSNAME))
4733 && ((c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
4734 || (c_parser_peek_2nd_token (parser)->type
4735 == CPP_CLOSE_PAREN))
4736 && (takes_identifier
4737 || (c_dialect_objc ()
4738 && !assume_attr
4739 && c_parser_peek_token (parser)->id_kind
4740 == C_ID_CLASSNAME)))
4741 {
4742 tree arg1 = c_parser_peek_token (parser)->value;
4743 c_parser_consume_token (parser);
4744 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4745 attr_args = build_tree_list (NULL_TREE, arg1);
4746 else
4747 {
4748 tree tree_list;
4749 c_parser_consume_token (parser);
4750 expr_list = c_parser_expr_list (parser, false, true,
4751 NULL, NULL, NULL, NULL);
4752 tree_list = build_tree_list_vec (expr_list);
4753 attr_args = tree_cons (NULL_TREE, arg1, tree_list);
4754 release_tree_vector (expr_list);
4755 }
4756 }
4757 else
4758 {
4759 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4760 {
4761 if (!allow_empty_args)
4762 error_at (c_parser_peek_token (parser)->location,
4763 "parentheses must be omitted if "
4764 "attribute argument list is empty");
4765 attr_args = NULL_TREE;
4766 }
4767 else if (require_string)
4768 {
4769 /* The only valid argument for this attribute is a string
4770 literal. Handle this specially here to avoid accepting
4771 string literals with excess parentheses. */
4772 tree string = c_parser_string_literal (parser, false, true).value;
4773 attr_args = build_tree_list (NULL_TREE, string);
4774 }
4775 else if (assume_attr)
4776 {
4777 tree cond
4778 = c_parser_conditional_expression (parser, NULL, NULL_TREE).value;
4779 if (!c_parser_next_token_is (parser, CPP_COMMA))
4780 attr_args = build_tree_list (NULL_TREE, cond);
4781 else
4782 {
4783 tree tree_list;
4784 c_parser_consume_token (parser);
4785 expr_list = c_parser_expr_list (parser, false, true,
4786 NULL, NULL, NULL, NULL);
4787 tree_list = build_tree_list_vec (expr_list);
4788 attr_args = tree_cons (NULL_TREE, cond, tree_list);
4789 release_tree_vector (expr_list);
4790 }
4791 }
4792 else
4793 {
4794 expr_list = c_parser_expr_list (parser, false, true,
4795 NULL, NULL, NULL, NULL);
4796 attr_args = build_tree_list_vec (expr_list);
4797 release_tree_vector (expr_list);
4798 }
4799 }
4800 return attr_args;
4801 }
4802
4803 /* Parse (possibly empty) gnu-attributes. This is a GNU extension.
4804
4805 gnu-attributes:
4806 empty
4807 gnu-attributes gnu-attribute
4808
4809 gnu-attribute:
4810 __attribute__ ( ( gnu-attribute-list ) )
4811
4812 gnu-attribute-list:
4813 gnu-attrib
4814 gnu-attribute_list , gnu-attrib
4815
4816 gnu-attrib:
4817 empty
4818 any-word
4819 any-word ( gnu-attribute-arguments )
4820
4821 where "any-word" may be any identifier (including one declared as a
4822 type), a reserved word storage class specifier, type specifier or
4823 type qualifier. ??? This still leaves out most reserved keywords
4824 (following the old parser), shouldn't we include them?
4825 When EXPECT_COMMA is true, expect the attribute to be preceded
4826 by a comma and fail if it isn't.
4827 When EMPTY_OK is true, allow and consume any number of consecutive
4828 commas with no attributes in between. */
4829
4830 static tree
4831 c_parser_gnu_attribute (c_parser *parser, tree attrs,
4832 bool expect_comma = false, bool empty_ok = true)
4833 {
4834 bool comma_first = c_parser_next_token_is (parser, CPP_COMMA);
4835 if (!comma_first
4836 && !c_parser_next_token_is (parser, CPP_NAME)
4837 && !c_parser_next_token_is (parser, CPP_KEYWORD))
4838 return NULL_TREE;
4839
4840 while (c_parser_next_token_is (parser, CPP_COMMA))
4841 {
4842 c_parser_consume_token (parser);
4843 if (!empty_ok)
4844 return attrs;
4845 }
4846
4847 tree attr_name = c_parser_gnu_attribute_any_word (parser);
4848 if (attr_name == NULL_TREE)
4849 return NULL_TREE;
4850
4851 attr_name = canonicalize_attr_name (attr_name);
4852 c_parser_consume_token (parser);
4853
4854 tree attr;
4855 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
4856 {
4857 if (expect_comma && !comma_first)
4858 {
4859 /* A comma is missing between the last attribute on the chain
4860 and this one. */
4861 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4862 "expected %<)%>");
4863 return error_mark_node;
4864 }
4865 attr = build_tree_list (attr_name, NULL_TREE);
4866 /* Add this attribute to the list. */
4867 attrs = chainon (attrs, attr);
4868 return attrs;
4869 }
4870 c_parser_consume_token (parser);
4871
4872 tree attr_args
4873 = c_parser_attribute_arguments (parser,
4874 attribute_takes_identifier_p (attr_name),
4875 false,
4876 is_attribute_p ("assume", attr_name),
4877 true);
4878
4879 attr = build_tree_list (attr_name, attr_args);
4880 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4881 c_parser_consume_token (parser);
4882 else
4883 {
4884 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4885 "expected %<)%>");
4886 return error_mark_node;
4887 }
4888
4889 if (expect_comma && !comma_first)
4890 {
4891 /* A comma is missing between the last attribute on the chain
4892 and this one. */
4893 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4894 "expected %<)%>");
4895 return error_mark_node;
4896 }
4897
4898 /* Add this attribute to the list. */
4899 attrs = chainon (attrs, attr);
4900 return attrs;
4901 }
4902
4903 static tree
4904 c_parser_gnu_attributes (c_parser *parser)
4905 {
4906 tree attrs = NULL_TREE;
4907 while (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4908 {
4909 bool save_translate_strings_p = parser->translate_strings_p;
4910 parser->translate_strings_p = false;
4911 /* Consume the `__attribute__' keyword. */
4912 c_parser_consume_token (parser);
4913 /* Look for the two `(' tokens. */
4914 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4915 {
4916 parser->translate_strings_p = save_translate_strings_p;
4917 return attrs;
4918 }
4919 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4920 {
4921 parser->translate_strings_p = save_translate_strings_p;
4922 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4923 return attrs;
4924 }
4925 /* Parse the attribute list. Require a comma between successive
4926 (possibly empty) attributes. */
4927 for (bool expect_comma = false; ; expect_comma = true)
4928 {
4929 /* Parse a single attribute. */
4930 tree attr = c_parser_gnu_attribute (parser, attrs, expect_comma);
4931 if (attr == error_mark_node)
4932 return attrs;
4933 if (!attr)
4934 break;
4935 attrs = attr;
4936 }
4937
4938 /* Look for the two `)' tokens. */
4939 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4940 c_parser_consume_token (parser);
4941 else
4942 {
4943 parser->translate_strings_p = save_translate_strings_p;
4944 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4945 "expected %<)%>");
4946 return attrs;
4947 }
4948 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4949 c_parser_consume_token (parser);
4950 else
4951 {
4952 parser->translate_strings_p = save_translate_strings_p;
4953 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4954 "expected %<)%>");
4955 return attrs;
4956 }
4957 parser->translate_strings_p = save_translate_strings_p;
4958 }
4959
4960 return attrs;
4961 }
4962
4963 /* Parse an optional balanced token sequence.
4964
4965 balanced-token-sequence:
4966 balanced-token
4967 balanced-token-sequence balanced-token
4968
4969 balanced-token:
4970 ( balanced-token-sequence[opt] )
4971 [ balanced-token-sequence[opt] ]
4972 { balanced-token-sequence[opt] }
4973 any token other than ()[]{}
4974 */
4975
4976 static void
4977 c_parser_balanced_token_sequence (c_parser *parser)
4978 {
4979 while (true)
4980 {
4981 c_token *token = c_parser_peek_token (parser);
4982 switch (token->type)
4983 {
4984 case CPP_OPEN_BRACE:
4985 {
4986 matching_braces braces;
4987 braces.consume_open (parser);
4988 c_parser_balanced_token_sequence (parser);
4989 braces.require_close (parser);
4990 break;
4991 }
4992
4993 case CPP_OPEN_PAREN:
4994 {
4995 matching_parens parens;
4996 parens.consume_open (parser);
4997 c_parser_balanced_token_sequence (parser);
4998 parens.require_close (parser);
4999 break;
5000 }
5001
5002 case CPP_OPEN_SQUARE:
5003 c_parser_consume_token (parser);
5004 c_parser_balanced_token_sequence (parser);
5005 c_parser_require (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5006 break;
5007
5008 case CPP_CLOSE_BRACE:
5009 case CPP_CLOSE_PAREN:
5010 case CPP_CLOSE_SQUARE:
5011 case CPP_EOF:
5012 return;
5013
5014 case CPP_PRAGMA:
5015 c_parser_consume_pragma (parser);
5016 c_parser_skip_to_pragma_eol (parser, false);
5017 break;
5018
5019 default:
5020 c_parser_consume_token (parser);
5021 break;
5022 }
5023 }
5024 }
5025
5026 /* Parse standard (C2X) attributes (including GNU attributes in the
5027 gnu:: namespace).
5028
5029 attribute-specifier-sequence:
5030 attribute-specifier-sequence[opt] attribute-specifier
5031
5032 attribute-specifier:
5033 [ [ attribute-list ] ]
5034
5035 attribute-list:
5036 attribute[opt]
5037 attribute-list, attribute[opt]
5038
5039 attribute:
5040 attribute-token attribute-argument-clause[opt]
5041
5042 attribute-token:
5043 standard-attribute
5044 attribute-prefixed-token
5045
5046 standard-attribute:
5047 identifier
5048
5049 attribute-prefixed-token:
5050 attribute-prefix :: identifier
5051
5052 attribute-prefix:
5053 identifier
5054
5055 attribute-argument-clause:
5056 ( balanced-token-sequence[opt] )
5057
5058 Keywords are accepted as identifiers for this purpose.
5059 */
5060
5061 static tree
5062 c_parser_std_attribute (c_parser *parser, bool for_tm)
5063 {
5064 c_token *token = c_parser_peek_token (parser);
5065 tree ns, name, attribute;
5066
5067 /* Parse the attribute-token. */
5068 if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
5069 {
5070 c_parser_error (parser, "expected identifier");
5071 return error_mark_node;
5072 }
5073 name = canonicalize_attr_name (token->value);
5074 c_parser_consume_token (parser);
5075 if (c_parser_next_token_is (parser, CPP_SCOPE))
5076 {
5077 ns = name;
5078 c_parser_consume_token (parser);
5079 token = c_parser_peek_token (parser);
5080 if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
5081 {
5082 c_parser_error (parser, "expected identifier");
5083 return error_mark_node;
5084 }
5085 name = canonicalize_attr_name (token->value);
5086 c_parser_consume_token (parser);
5087 }
5088 else
5089 ns = NULL_TREE;
5090 attribute = build_tree_list (build_tree_list (ns, name), NULL_TREE);
5091
5092 /* Parse the arguments, if any. */
5093 const attribute_spec *as = lookup_attribute_spec (TREE_PURPOSE (attribute));
5094 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
5095 goto out;
5096 {
5097 location_t open_loc = c_parser_peek_token (parser)->location;
5098 matching_parens parens;
5099 parens.consume_open (parser);
5100 if ((as && as->max_length == 0)
5101 /* Special-case the transactional-memory attribute "outer",
5102 which is specially handled but not registered as an
5103 attribute, to avoid allowing arbitrary balanced token
5104 sequences as arguments. */
5105 || is_attribute_p ("outer", name))
5106 {
5107 error_at (open_loc, "%qE attribute does not take any arguments", name);
5108 parens.skip_until_found_close (parser);
5109 return error_mark_node;
5110 }
5111 /* If this is a fake attribute created to handle -Wno-attributes,
5112 we must skip parsing the arguments. */
5113 if (as && !attribute_ignored_p (as))
5114 {
5115 bool takes_identifier
5116 = (ns != NULL_TREE
5117 && strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0
5118 && attribute_takes_identifier_p (name));
5119 bool require_string
5120 = (ns == NULL_TREE
5121 && (strcmp (IDENTIFIER_POINTER (name), "deprecated") == 0
5122 || strcmp (IDENTIFIER_POINTER (name), "nodiscard") == 0));
5123 bool assume_attr
5124 = (ns != NULL_TREE
5125 && strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0
5126 && strcmp (IDENTIFIER_POINTER (name), "assume") == 0);
5127 TREE_VALUE (attribute)
5128 = c_parser_attribute_arguments (parser, takes_identifier,
5129 require_string, assume_attr, false);
5130 }
5131 else
5132 c_parser_balanced_token_sequence (parser);
5133 parens.require_close (parser);
5134 }
5135 out:
5136 if (ns == NULL_TREE && !for_tm && !as)
5137 {
5138 /* An attribute with standard syntax and no namespace specified
5139 is a constraint violation if it is not one of the known
5140 standard attributes. Diagnose it here with a pedwarn and
5141 then discard it to prevent a duplicate warning later. */
5142 pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored",
5143 name);
5144 return error_mark_node;
5145 }
5146 return attribute;
5147 }
5148
5149 static tree
5150 c_parser_std_attribute_specifier (c_parser *parser, bool for_tm)
5151 {
5152 location_t loc = c_parser_peek_token (parser)->location;
5153 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
5154 return NULL_TREE;
5155 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
5156 {
5157 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5158 return NULL_TREE;
5159 }
5160 if (!for_tm)
5161 pedwarn_c11 (loc, OPT_Wpedantic,
5162 "ISO C does not support %<[[]]%> attributes before C2X");
5163 tree attributes = NULL_TREE;
5164 while (true)
5165 {
5166 c_token *token = c_parser_peek_token (parser);
5167 if (token->type == CPP_CLOSE_SQUARE)
5168 break;
5169 if (token->type == CPP_COMMA)
5170 {
5171 c_parser_consume_token (parser);
5172 continue;
5173 }
5174 tree attribute = c_parser_std_attribute (parser, for_tm);
5175 if (attribute != error_mark_node)
5176 {
5177 TREE_CHAIN (attribute) = attributes;
5178 attributes = attribute;
5179 }
5180 if (c_parser_next_token_is_not (parser, CPP_COMMA))
5181 break;
5182 }
5183 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5184 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5185 return nreverse (attributes);
5186 }
5187
5188 /* Look past an optional balanced token sequence of raw look-ahead
5189 tokens starting with the *Nth token. *N is updated to point to the
5190 following token. Return true if such a sequence was found, false
5191 if the tokens parsed were not balanced. */
5192
5193 static bool
5194 c_parser_check_balanced_raw_token_sequence (c_parser *parser, unsigned int *n)
5195 {
5196 while (true)
5197 {
5198 c_token *token = c_parser_peek_nth_token_raw (parser, *n);
5199 switch (token->type)
5200 {
5201 case CPP_OPEN_BRACE:
5202 {
5203 ++*n;
5204 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5205 {
5206 token = c_parser_peek_nth_token_raw (parser, *n);
5207 if (token->type == CPP_CLOSE_BRACE)
5208 ++*n;
5209 else
5210 return false;
5211 }
5212 else
5213 return false;
5214 break;
5215 }
5216
5217 case CPP_OPEN_PAREN:
5218 {
5219 ++*n;
5220 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5221 {
5222 token = c_parser_peek_nth_token_raw (parser, *n);
5223 if (token->type == CPP_CLOSE_PAREN)
5224 ++*n;
5225 else
5226 return false;
5227 }
5228 else
5229 return false;
5230 break;
5231 }
5232
5233 case CPP_OPEN_SQUARE:
5234 {
5235 ++*n;
5236 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5237 {
5238 token = c_parser_peek_nth_token_raw (parser, *n);
5239 if (token->type == CPP_CLOSE_SQUARE)
5240 ++*n;
5241 else
5242 return false;
5243 }
5244 else
5245 return false;
5246 break;
5247 }
5248
5249 case CPP_CLOSE_BRACE:
5250 case CPP_CLOSE_PAREN:
5251 case CPP_CLOSE_SQUARE:
5252 case CPP_EOF:
5253 return true;
5254
5255 default:
5256 ++*n;
5257 break;
5258 }
5259 }
5260 }
5261
5262 /* Return whether standard attributes start with the Nth token. */
5263
5264 static bool
5265 c_parser_nth_token_starts_std_attributes (c_parser *parser, unsigned int n)
5266 {
5267 if (!(c_parser_peek_nth_token (parser, n)->type == CPP_OPEN_SQUARE
5268 && c_parser_peek_nth_token (parser, n + 1)->type == CPP_OPEN_SQUARE))
5269 return false;
5270 /* In C, '[[' must start attributes. In Objective-C, we need to
5271 check whether '[[' is matched by ']]'. */
5272 if (!c_dialect_objc ())
5273 return true;
5274 n += 2;
5275 if (!c_parser_check_balanced_raw_token_sequence (parser, &n))
5276 return false;
5277 c_token *token = c_parser_peek_nth_token_raw (parser, n);
5278 if (token->type != CPP_CLOSE_SQUARE)
5279 return false;
5280 token = c_parser_peek_nth_token_raw (parser, n + 1);
5281 return token->type == CPP_CLOSE_SQUARE;
5282 }
5283
5284 static tree
5285 c_parser_std_attribute_specifier_sequence (c_parser *parser)
5286 {
5287 tree attributes = NULL_TREE;
5288 do
5289 {
5290 tree attrs = c_parser_std_attribute_specifier (parser, false);
5291 attributes = chainon (attributes, attrs);
5292 }
5293 while (c_parser_nth_token_starts_std_attributes (parser, 1));
5294 return attributes;
5295 }
5296
5297 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK
5298 says whether alignment specifiers are OK (only in cases that might
5299 be the type name of a compound literal).
5300
5301 type-name:
5302 specifier-qualifier-list abstract-declarator[opt]
5303 */
5304
5305 struct c_type_name *
5306 c_parser_type_name (c_parser *parser, bool alignas_ok)
5307 {
5308 struct c_declspecs *specs = build_null_declspecs ();
5309 struct c_declarator *declarator;
5310 struct c_type_name *ret;
5311 bool dummy = false;
5312 c_parser_declspecs (parser, specs, false, true, true, alignas_ok, false,
5313 false, true, cla_prefer_type);
5314 if (!specs->declspecs_seen_p)
5315 {
5316 c_parser_error (parser, "expected specifier-qualifier-list");
5317 return NULL;
5318 }
5319 if (specs->type != error_mark_node)
5320 {
5321 pending_xref_error ();
5322 finish_declspecs (specs);
5323 }
5324 declarator = c_parser_declarator (parser,
5325 specs->typespec_kind != ctsk_none,
5326 C_DTR_ABSTRACT, &dummy);
5327 if (declarator == NULL)
5328 return NULL;
5329 ret = XOBNEW (&parser_obstack, struct c_type_name);
5330 ret->specs = specs;
5331 ret->declarator = declarator;
5332 return ret;
5333 }
5334
5335 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
5336
5337 initializer:
5338 assignment-expression
5339 { initializer-list }
5340 { initializer-list , }
5341
5342 initializer-list:
5343 designation[opt] initializer
5344 initializer-list , designation[opt] initializer
5345
5346 designation:
5347 designator-list =
5348
5349 designator-list:
5350 designator
5351 designator-list designator
5352
5353 designator:
5354 array-designator
5355 . identifier
5356
5357 array-designator:
5358 [ constant-expression ]
5359
5360 GNU extensions:
5361
5362 initializer:
5363 { }
5364
5365 designation:
5366 array-designator
5367 identifier :
5368
5369 array-designator:
5370 [ constant-expression ... constant-expression ]
5371
5372 Any expression without commas is accepted in the syntax for the
5373 constant-expressions, with non-constant expressions rejected later.
5374
5375 DECL is the declaration we're parsing this initializer for.
5376
5377 This function is only used for top-level initializers; for nested
5378 ones, see c_parser_initval. */
5379
5380 static struct c_expr
5381 c_parser_initializer (c_parser *parser, tree decl)
5382 {
5383 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
5384 return c_parser_braced_init (parser, NULL_TREE, false, NULL, decl);
5385 else
5386 {
5387 struct c_expr ret;
5388 location_t loc = c_parser_peek_token (parser)->location;
5389 if (decl != error_mark_node && C_DECL_VARIABLE_SIZE (decl))
5390 error_at (loc,
5391 "variable-sized object may not be initialized except "
5392 "with an empty initializer");
5393 ret = c_parser_expr_no_commas (parser, NULL);
5394 /* This is handled mostly by gimplify.cc, but we have to deal with
5395 not warning about int x = x; as it is a GCC extension to turn off
5396 this warning but only if warn_init_self is zero. */
5397 if (VAR_P (decl)
5398 && !DECL_EXTERNAL (decl)
5399 && !TREE_STATIC (decl)
5400 && ret.value == decl
5401 && !warn_init_self)
5402 suppress_warning (decl, OPT_Winit_self);
5403 if (TREE_CODE (ret.value) != STRING_CST
5404 && TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR)
5405 ret = convert_lvalue_to_rvalue (loc, ret, true, true);
5406 return ret;
5407 }
5408 }
5409
5410 /* The location of the last comma within the current initializer list,
5411 or UNKNOWN_LOCATION if not within one. */
5412
5413 location_t last_init_list_comma;
5414
5415 /* Parse a braced initializer list. TYPE is the type specified for a
5416 compound literal, and NULL_TREE for other initializers and for
5417 nested braced lists. NESTED_P is true for nested braced lists,
5418 false for the list of a compound literal or the list that is the
5419 top-level initializer in a declaration. DECL is the declaration for
5420 the top-level initializer for a declaration, otherwise NULL_TREE. */
5421
5422 static struct c_expr
5423 c_parser_braced_init (c_parser *parser, tree type, bool nested_p,
5424 struct obstack *outer_obstack, tree decl)
5425 {
5426 struct c_expr ret;
5427 struct obstack braced_init_obstack;
5428 location_t brace_loc = c_parser_peek_token (parser)->location;
5429 gcc_obstack_init (&braced_init_obstack);
5430 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
5431 matching_braces braces;
5432 braces.consume_open (parser);
5433 if (nested_p)
5434 {
5435 finish_implicit_inits (brace_loc, outer_obstack);
5436 push_init_level (brace_loc, 0, &braced_init_obstack);
5437 }
5438 else
5439 really_start_incremental_init (type);
5440 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5441 {
5442 pedwarn_c11 (brace_loc, OPT_Wpedantic,
5443 "ISO C forbids empty initializer braces before C2X");
5444 }
5445 else
5446 {
5447 if (decl && decl != error_mark_node && C_DECL_VARIABLE_SIZE (decl))
5448 error_at (brace_loc,
5449 "variable-sized object may not be initialized except "
5450 "with an empty initializer");
5451 /* Parse a non-empty initializer list, possibly with a trailing
5452 comma. */
5453 while (true)
5454 {
5455 c_parser_initelt (parser, &braced_init_obstack);
5456 if (parser->error)
5457 break;
5458 if (c_parser_next_token_is (parser, CPP_COMMA))
5459 {
5460 last_init_list_comma = c_parser_peek_token (parser)->location;
5461 c_parser_consume_token (parser);
5462 }
5463 else
5464 break;
5465 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5466 break;
5467 }
5468 }
5469 c_token *next_tok = c_parser_peek_token (parser);
5470 if (next_tok->type != CPP_CLOSE_BRACE)
5471 {
5472 ret.set_error ();
5473 ret.original_code = ERROR_MARK;
5474 ret.original_type = NULL;
5475 braces.skip_until_found_close (parser);
5476 pop_init_level (brace_loc, 0, &braced_init_obstack, last_init_list_comma);
5477 obstack_free (&braced_init_obstack, NULL);
5478 return ret;
5479 }
5480 location_t close_loc = next_tok->location;
5481 c_parser_consume_token (parser);
5482 ret = pop_init_level (brace_loc, 0, &braced_init_obstack, close_loc);
5483 obstack_free (&braced_init_obstack, NULL);
5484 set_c_expr_source_range (&ret, brace_loc, close_loc);
5485 return ret;
5486 }
5487
5488 /* Parse a nested initializer, including designators. */
5489
5490 static void
5491 c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
5492 {
5493 /* Parse any designator or designator list. A single array
5494 designator may have the subsequent "=" omitted in GNU C, but a
5495 longer list or a structure member designator may not. */
5496 if (c_parser_next_token_is (parser, CPP_NAME)
5497 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
5498 {
5499 /* Old-style structure member designator. */
5500 set_init_label (c_parser_peek_token (parser)->location,
5501 c_parser_peek_token (parser)->value,
5502 c_parser_peek_token (parser)->location,
5503 braced_init_obstack);
5504 /* Use the colon as the error location. */
5505 pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_Wpedantic,
5506 "obsolete use of designated initializer with %<:%>");
5507 c_parser_consume_token (parser);
5508 c_parser_consume_token (parser);
5509 }
5510 else
5511 {
5512 /* des_seen is 0 if there have been no designators, 1 if there
5513 has been a single array designator and 2 otherwise. */
5514 int des_seen = 0;
5515 /* Location of a designator. */
5516 location_t des_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5517 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
5518 || c_parser_next_token_is (parser, CPP_DOT))
5519 {
5520 int des_prev = des_seen;
5521 if (!des_seen)
5522 des_loc = c_parser_peek_token (parser)->location;
5523 if (des_seen < 2)
5524 des_seen++;
5525 if (c_parser_next_token_is (parser, CPP_DOT))
5526 {
5527 des_seen = 2;
5528 c_parser_consume_token (parser);
5529 if (c_parser_next_token_is (parser, CPP_NAME))
5530 {
5531 set_init_label (des_loc, c_parser_peek_token (parser)->value,
5532 c_parser_peek_token (parser)->location,
5533 braced_init_obstack);
5534 c_parser_consume_token (parser);
5535 }
5536 else
5537 {
5538 struct c_expr init;
5539 init.set_error ();
5540 init.original_code = ERROR_MARK;
5541 init.original_type = NULL;
5542 c_parser_error (parser, "expected identifier");
5543 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
5544 process_init_element (input_location, init, false,
5545 braced_init_obstack);
5546 return;
5547 }
5548 }
5549 else
5550 {
5551 tree first, second;
5552 location_t ellipsis_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5553 location_t array_index_loc = UNKNOWN_LOCATION;
5554 /* ??? Following the old parser, [ objc-receiver
5555 objc-message-args ] is accepted as an initializer,
5556 being distinguished from a designator by what follows
5557 the first assignment expression inside the square
5558 brackets, but after a first array designator a
5559 subsequent square bracket is for Objective-C taken to
5560 start an expression, using the obsolete form of
5561 designated initializer without '=', rather than
5562 possibly being a second level of designation: in LALR
5563 terms, the '[' is shifted rather than reducing
5564 designator to designator-list. */
5565 if (des_prev == 1 && c_dialect_objc ())
5566 {
5567 des_seen = des_prev;
5568 break;
5569 }
5570 if (des_prev == 0 && c_dialect_objc ())
5571 {
5572 /* This might be an array designator or an
5573 Objective-C message expression. If the former,
5574 continue parsing here; if the latter, parse the
5575 remainder of the initializer given the starting
5576 primary-expression. ??? It might make sense to
5577 distinguish when des_prev == 1 as well; see
5578 previous comment. */
5579 tree rec, args;
5580 struct c_expr mexpr;
5581 c_parser_consume_token (parser);
5582 if (c_parser_peek_token (parser)->type == CPP_NAME
5583 && ((c_parser_peek_token (parser)->id_kind
5584 == C_ID_TYPENAME)
5585 || (c_parser_peek_token (parser)->id_kind
5586 == C_ID_CLASSNAME)))
5587 {
5588 /* Type name receiver. */
5589 tree id = c_parser_peek_token (parser)->value;
5590 c_parser_consume_token (parser);
5591 rec = objc_get_class_reference (id);
5592 goto parse_message_args;
5593 }
5594 first = c_parser_expr_no_commas (parser, NULL).value;
5595 mark_exp_read (first);
5596 if (c_parser_next_token_is (parser, CPP_ELLIPSIS)
5597 || c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
5598 goto array_desig_after_first;
5599 /* Expression receiver. So far only one part
5600 without commas has been parsed; there might be
5601 more of the expression. */
5602 rec = first;
5603 while (c_parser_next_token_is (parser, CPP_COMMA))
5604 {
5605 struct c_expr next;
5606 location_t comma_loc, exp_loc;
5607 comma_loc = c_parser_peek_token (parser)->location;
5608 c_parser_consume_token (parser);
5609 exp_loc = c_parser_peek_token (parser)->location;
5610 next = c_parser_expr_no_commas (parser, NULL);
5611 next = convert_lvalue_to_rvalue (exp_loc, next,
5612 true, true);
5613 rec = build_compound_expr (comma_loc, rec, next.value);
5614 }
5615 parse_message_args:
5616 /* Now parse the objc-message-args. */
5617 args = c_parser_objc_message_args (parser);
5618 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5619 "expected %<]%>");
5620 mexpr.value
5621 = objc_build_message_expr (rec, args);
5622 mexpr.original_code = ERROR_MARK;
5623 mexpr.original_type = NULL;
5624 mexpr.m_decimal = 0;
5625 /* Now parse and process the remainder of the
5626 initializer, starting with this message
5627 expression as a primary-expression. */
5628 c_parser_initval (parser, &mexpr, braced_init_obstack);
5629 return;
5630 }
5631 c_parser_consume_token (parser);
5632 array_index_loc = c_parser_peek_token (parser)->location;
5633 first = c_parser_expr_no_commas (parser, NULL).value;
5634 mark_exp_read (first);
5635 array_desig_after_first:
5636 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
5637 {
5638 ellipsis_loc = c_parser_peek_token (parser)->location;
5639 c_parser_consume_token (parser);
5640 second = c_parser_expr_no_commas (parser, NULL).value;
5641 mark_exp_read (second);
5642 }
5643 else
5644 second = NULL_TREE;
5645 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
5646 {
5647 c_parser_consume_token (parser);
5648 set_init_index (array_index_loc, first, second,
5649 braced_init_obstack);
5650 if (second)
5651 pedwarn (ellipsis_loc, OPT_Wpedantic,
5652 "ISO C forbids specifying range of elements to initialize");
5653 }
5654 else
5655 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5656 "expected %<]%>");
5657 }
5658 }
5659 if (des_seen >= 1)
5660 {
5661 if (c_parser_next_token_is (parser, CPP_EQ))
5662 {
5663 pedwarn_c90 (des_loc, OPT_Wpedantic,
5664 "ISO C90 forbids specifying subobject "
5665 "to initialize");
5666 c_parser_consume_token (parser);
5667 }
5668 else
5669 {
5670 if (des_seen == 1)
5671 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
5672 "obsolete use of designated initializer without %<=%>");
5673 else
5674 {
5675 struct c_expr init;
5676 init.set_error ();
5677 init.original_code = ERROR_MARK;
5678 init.original_type = NULL;
5679 c_parser_error (parser, "expected %<=%>");
5680 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
5681 process_init_element (input_location, init, false,
5682 braced_init_obstack);
5683 return;
5684 }
5685 }
5686 }
5687 }
5688 c_parser_initval (parser, NULL, braced_init_obstack);
5689 }
5690
5691 /* Parse a nested initializer; as c_parser_initializer but parses
5692 initializers within braced lists, after any designators have been
5693 applied. If AFTER is not NULL then it is an Objective-C message
5694 expression which is the primary-expression starting the
5695 initializer. */
5696
5697 static void
5698 c_parser_initval (c_parser *parser, struct c_expr *after,
5699 struct obstack * braced_init_obstack)
5700 {
5701 struct c_expr init;
5702 gcc_assert (!after || c_dialect_objc ());
5703 location_t loc = c_parser_peek_token (parser)->location;
5704
5705 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after)
5706 init = c_parser_braced_init (parser, NULL_TREE, true,
5707 braced_init_obstack, NULL_TREE);
5708 else
5709 {
5710 init = c_parser_expr_no_commas (parser, after);
5711 if (init.value != NULL_TREE
5712 && TREE_CODE (init.value) != STRING_CST
5713 && TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR)
5714 init = convert_lvalue_to_rvalue (loc, init, true, true);
5715 }
5716 process_init_element (loc, init, false, braced_init_obstack);
5717 }
5718
5719 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
5720 C99 6.8.2, C11 6.8.2, C2X 6.8.2).
5721
5722 compound-statement:
5723 { block-item-list[opt] }
5724 { label-declarations block-item-list }
5725
5726 block-item-list:
5727 block-item
5728 block-item-list block-item
5729
5730 block-item:
5731 label
5732 nested-declaration
5733 statement
5734
5735 nested-declaration:
5736 declaration
5737
5738 GNU extensions:
5739
5740 compound-statement:
5741 { label-declarations block-item-list }
5742
5743 nested-declaration:
5744 __extension__ nested-declaration
5745 nested-function-definition
5746
5747 label-declarations:
5748 label-declaration
5749 label-declarations label-declaration
5750
5751 label-declaration:
5752 __label__ identifier-list ;
5753
5754 Allowing the mixing of declarations and code is new in C99. The
5755 GNU syntax also permits (not shown above) labels at the end of
5756 compound statements, which yield an error. We don't allow labels
5757 on declarations; this might seem like a natural extension, but
5758 there would be a conflict between gnu-attributes on the label and
5759 prefix gnu-attributes on the declaration. ??? The syntax follows the
5760 old parser in requiring something after label declarations.
5761 Although they are erroneous if the labels declared aren't defined,
5762 is it useful for the syntax to be this way?
5763
5764 OpenACC:
5765
5766 block-item:
5767 openacc-directive
5768
5769 openacc-directive:
5770 update-directive
5771
5772 OpenMP:
5773
5774 block-item:
5775 openmp-directive
5776
5777 openmp-directive:
5778 barrier-directive
5779 flush-directive
5780 taskwait-directive
5781 taskyield-directive
5782 cancel-directive
5783 cancellation-point-directive */
5784
5785 static tree
5786 c_parser_compound_statement (c_parser *parser, location_t *endlocp)
5787 {
5788 tree stmt;
5789 location_t brace_loc;
5790 brace_loc = c_parser_peek_token (parser)->location;
5791 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
5792 {
5793 /* Ensure a scope is entered and left anyway to avoid confusion
5794 if we have just prepared to enter a function body. */
5795 stmt = c_begin_compound_stmt (true);
5796 c_end_compound_stmt (brace_loc, stmt, true);
5797 return error_mark_node;
5798 }
5799 stmt = c_begin_compound_stmt (true);
5800 location_t end_loc = c_parser_compound_statement_nostart (parser);
5801 if (endlocp)
5802 *endlocp = end_loc;
5803
5804 return c_end_compound_stmt (brace_loc, stmt, true);
5805 }
5806
5807 /* Parse a compound statement except for the opening brace. This is
5808 used for parsing both compound statements and statement expressions
5809 (which follow different paths to handling the opening). */
5810
5811 static location_t
5812 c_parser_compound_statement_nostart (c_parser *parser)
5813 {
5814 bool last_stmt = false;
5815 bool last_label = false;
5816 bool save_valid_for_pragma = valid_location_for_stdc_pragma_p ();
5817 location_t label_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5818 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5819 {
5820 location_t endloc = c_parser_peek_token (parser)->location;
5821 add_debug_begin_stmt (endloc);
5822 c_parser_consume_token (parser);
5823 return endloc;
5824 }
5825 mark_valid_location_for_stdc_pragma (true);
5826 if (c_parser_next_token_is_keyword (parser, RID_LABEL))
5827 {
5828 /* Read zero or more forward-declarations for labels that nested
5829 functions can jump to. */
5830 mark_valid_location_for_stdc_pragma (false);
5831 while (c_parser_next_token_is_keyword (parser, RID_LABEL))
5832 {
5833 label_loc = c_parser_peek_token (parser)->location;
5834 c_parser_consume_token (parser);
5835 /* Any identifiers, including those declared as type names,
5836 are OK here. */
5837 while (true)
5838 {
5839 tree label;
5840 if (c_parser_next_token_is_not (parser, CPP_NAME))
5841 {
5842 c_parser_error (parser, "expected identifier");
5843 break;
5844 }
5845 label
5846 = declare_label (c_parser_peek_token (parser)->value);
5847 C_DECLARED_LABEL_FLAG (label) = 1;
5848 add_stmt (build_stmt (label_loc, DECL_EXPR, label));
5849 c_parser_consume_token (parser);
5850 if (c_parser_next_token_is (parser, CPP_COMMA))
5851 c_parser_consume_token (parser);
5852 else
5853 break;
5854 }
5855 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
5856 }
5857 pedwarn (label_loc, OPT_Wpedantic, "ISO C forbids label declarations");
5858 }
5859 /* We must now have at least one statement, label or declaration. */
5860 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5861 {
5862 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5863 c_parser_error (parser, "expected declaration or statement");
5864 location_t endloc = c_parser_peek_token (parser)->location;
5865 c_parser_consume_token (parser);
5866 return endloc;
5867 }
5868 while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
5869 {
5870 location_t loc = c_parser_peek_token (parser)->location;
5871 loc = expansion_point_location_if_in_system_header (loc);
5872 /* Standard attributes may start a label, statement or declaration. */
5873 bool have_std_attrs
5874 = c_parser_nth_token_starts_std_attributes (parser, 1);
5875 tree std_attrs = NULL_TREE;
5876 if (have_std_attrs)
5877 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5878 if (c_parser_next_token_is_keyword (parser, RID_CASE)
5879 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
5880 || (c_parser_next_token_is (parser, CPP_NAME)
5881 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5882 {
5883 if (c_parser_next_token_is_keyword (parser, RID_CASE))
5884 label_loc = c_parser_peek_2nd_token (parser)->location;
5885 else
5886 label_loc = c_parser_peek_token (parser)->location;
5887 last_label = true;
5888 last_stmt = false;
5889 mark_valid_location_for_stdc_pragma (false);
5890 c_parser_label (parser, std_attrs);
5891 }
5892 else if (c_parser_next_tokens_start_declaration (parser)
5893 || (have_std_attrs
5894 && c_parser_next_token_is (parser, CPP_SEMICOLON)))
5895 {
5896 if (last_label)
5897 pedwarn_c11 (c_parser_peek_token (parser)->location, OPT_Wpedantic,
5898 "a label can only be part of a statement and "
5899 "a declaration is not a statement");
5900
5901 mark_valid_location_for_stdc_pragma (false);
5902 bool fallthru_attr_p = false;
5903 c_parser_declaration_or_fndef (parser, true, !have_std_attrs,
5904 true, true, true, NULL,
5905 NULL, have_std_attrs, std_attrs,
5906 NULL, &fallthru_attr_p);
5907
5908 if (last_stmt && !fallthru_attr_p)
5909 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
5910 "ISO C90 forbids mixed declarations and code");
5911 last_stmt = fallthru_attr_p;
5912 last_label = false;
5913 }
5914 else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
5915 {
5916 /* __extension__ can start a declaration, but is also an
5917 unary operator that can start an expression. Consume all
5918 but the last of a possible series of __extension__ to
5919 determine which. If standard attributes have already
5920 been seen, it must start a statement, not a declaration,
5921 but standard attributes starting a declaration may appear
5922 after __extension__. */
5923 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
5924 && (c_parser_peek_2nd_token (parser)->keyword
5925 == RID_EXTENSION))
5926 c_parser_consume_token (parser);
5927 if (!have_std_attrs
5928 && (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
5929 || c_parser_nth_token_starts_std_attributes (parser, 2)))
5930 {
5931 int ext;
5932 ext = disable_extension_diagnostics ();
5933 c_parser_consume_token (parser);
5934 last_label = false;
5935 mark_valid_location_for_stdc_pragma (false);
5936 c_parser_declaration_or_fndef (parser, true, true, true, true,
5937 true);
5938 /* Following the old parser, __extension__ does not
5939 disable this diagnostic. */
5940 restore_extension_diagnostics (ext);
5941 if (last_stmt)
5942 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
5943 "ISO C90 forbids mixed declarations and code");
5944 last_stmt = false;
5945 }
5946 else
5947 goto statement;
5948 }
5949 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
5950 {
5951 if (have_std_attrs)
5952 c_parser_error (parser, "expected declaration or statement");
5953 /* External pragmas, and some omp pragmas, are not associated
5954 with regular c code, and so are not to be considered statements
5955 syntactically. This ensures that the user doesn't put them
5956 places that would turn into syntax errors if the directive
5957 were ignored. */
5958 if (c_parser_pragma (parser,
5959 last_label ? pragma_stmt : pragma_compound,
5960 NULL))
5961 last_label = false, last_stmt = true;
5962 }
5963 else if (c_parser_next_token_is (parser, CPP_EOF))
5964 {
5965 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5966 c_parser_error (parser, "expected declaration or statement");
5967 return c_parser_peek_token (parser)->location;
5968 }
5969 else if (c_parser_next_token_is_keyword (parser, RID_ELSE))
5970 {
5971 if (parser->in_if_block)
5972 {
5973 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5974 error_at (loc, "expected %<}%> before %<else%>");
5975 return c_parser_peek_token (parser)->location;
5976 }
5977 else
5978 {
5979 error_at (loc, "%<else%> without a previous %<if%>");
5980 c_parser_consume_token (parser);
5981 continue;
5982 }
5983 }
5984 else
5985 {
5986 statement:
5987 c_warn_unused_attributes (std_attrs);
5988 last_label = false;
5989 last_stmt = true;
5990 mark_valid_location_for_stdc_pragma (false);
5991 c_parser_statement_after_labels (parser, NULL);
5992 }
5993
5994 parser->error = false;
5995 }
5996 if (last_label)
5997 pedwarn_c11 (label_loc, OPT_Wpedantic, "label at end of compound statement");
5998 location_t endloc = c_parser_peek_token (parser)->location;
5999 c_parser_consume_token (parser);
6000 /* Restore the value we started with. */
6001 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
6002 return endloc;
6003 }
6004
6005 /* Parse all consecutive labels, possibly preceded by standard
6006 attributes. In this context, a statement is required, not a
6007 declaration, so attributes must be followed by a statement that is
6008 not just a semicolon. */
6009
6010 static void
6011 c_parser_all_labels (c_parser *parser)
6012 {
6013 tree std_attrs = NULL;
6014 if (c_parser_nth_token_starts_std_attributes (parser, 1))
6015 {
6016 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
6017 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6018 c_parser_error (parser, "expected statement");
6019 }
6020 while (c_parser_next_token_is_keyword (parser, RID_CASE)
6021 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
6022 || (c_parser_next_token_is (parser, CPP_NAME)
6023 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
6024 {
6025 c_parser_label (parser, std_attrs);
6026 std_attrs = NULL;
6027 if (c_parser_nth_token_starts_std_attributes (parser, 1))
6028 {
6029 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
6030 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6031 c_parser_error (parser, "expected statement");
6032 }
6033 }
6034 if (std_attrs)
6035 c_warn_unused_attributes (std_attrs);
6036 }
6037
6038 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
6039
6040 label:
6041 identifier : gnu-attributes[opt]
6042 case constant-expression :
6043 default :
6044
6045 GNU extensions:
6046
6047 label:
6048 case constant-expression ... constant-expression :
6049
6050 The use of gnu-attributes on labels is a GNU extension. The syntax in
6051 GNU C accepts any expressions without commas, non-constant
6052 expressions being rejected later. Any standard
6053 attribute-specifier-sequence before the first label has been parsed
6054 in the caller, to distinguish statements from declarations. Any
6055 attribute-specifier-sequence after the label is parsed in this
6056 function. */
6057 static void
6058 c_parser_label (c_parser *parser, tree std_attrs)
6059 {
6060 location_t loc1 = c_parser_peek_token (parser)->location;
6061 tree label = NULL_TREE;
6062
6063 /* Remember whether this case or a user-defined label is allowed to fall
6064 through to. */
6065 bool fallthrough_p = c_parser_peek_token (parser)->flags & PREV_FALLTHROUGH;
6066
6067 if (c_parser_next_token_is_keyword (parser, RID_CASE))
6068 {
6069 tree exp1, exp2;
6070 c_parser_consume_token (parser);
6071 exp1 = c_parser_expr_no_commas (parser, NULL).value;
6072 if (c_parser_next_token_is (parser, CPP_COLON))
6073 {
6074 c_parser_consume_token (parser);
6075 label = do_case (loc1, exp1, NULL_TREE, std_attrs);
6076 }
6077 else if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
6078 {
6079 c_parser_consume_token (parser);
6080 exp2 = c_parser_expr_no_commas (parser, NULL).value;
6081 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
6082 label = do_case (loc1, exp1, exp2, std_attrs);
6083 }
6084 else
6085 c_parser_error (parser, "expected %<:%> or %<...%>");
6086 }
6087 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
6088 {
6089 c_parser_consume_token (parser);
6090 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
6091 label = do_case (loc1, NULL_TREE, NULL_TREE, std_attrs);
6092 }
6093 else
6094 {
6095 tree name = c_parser_peek_token (parser)->value;
6096 tree tlab;
6097 tree attrs;
6098 location_t loc2 = c_parser_peek_token (parser)->location;
6099 gcc_assert (c_parser_next_token_is (parser, CPP_NAME));
6100 c_parser_consume_token (parser);
6101 gcc_assert (c_parser_next_token_is (parser, CPP_COLON));
6102 c_parser_consume_token (parser);
6103 attrs = c_parser_gnu_attributes (parser);
6104 tlab = define_label (loc2, name);
6105 if (tlab)
6106 {
6107 decl_attributes (&tlab, attrs, 0);
6108 decl_attributes (&tlab, std_attrs, 0);
6109 label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab));
6110 }
6111 if (attrs
6112 && c_parser_next_tokens_start_declaration (parser))
6113 warning_at (loc2, OPT_Wattributes, "GNU-style attribute between"
6114 " label and declaration appertains to the label");
6115 }
6116 if (label)
6117 {
6118 if (TREE_CODE (label) == LABEL_EXPR)
6119 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label)) = fallthrough_p;
6120 else
6121 FALLTHROUGH_LABEL_P (CASE_LABEL (label)) = fallthrough_p;
6122 }
6123 }
6124
6125 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
6126
6127 statement:
6128 labeled-statement
6129 attribute-specifier-sequence[opt] compound-statement
6130 expression-statement
6131 attribute-specifier-sequence[opt] selection-statement
6132 attribute-specifier-sequence[opt] iteration-statement
6133 attribute-specifier-sequence[opt] jump-statement
6134
6135 labeled-statement:
6136 attribute-specifier-sequence[opt] label statement
6137
6138 expression-statement:
6139 expression[opt] ;
6140 attribute-specifier-sequence expression ;
6141
6142 selection-statement:
6143 if-statement
6144 switch-statement
6145
6146 iteration-statement:
6147 while-statement
6148 do-statement
6149 for-statement
6150
6151 jump-statement:
6152 goto identifier ;
6153 continue ;
6154 break ;
6155 return expression[opt] ;
6156
6157 GNU extensions:
6158
6159 statement:
6160 attribute-specifier-sequence[opt] asm-statement
6161
6162 jump-statement:
6163 goto * expression ;
6164
6165 expression-statement:
6166 gnu-attributes ;
6167
6168 Objective-C:
6169
6170 statement:
6171 attribute-specifier-sequence[opt] objc-throw-statement
6172 attribute-specifier-sequence[opt] objc-try-catch-statement
6173 attribute-specifier-sequence[opt] objc-synchronized-statement
6174
6175 objc-throw-statement:
6176 @throw expression ;
6177 @throw ;
6178
6179 OpenACC:
6180
6181 statement:
6182 attribute-specifier-sequence[opt] openacc-construct
6183
6184 openacc-construct:
6185 parallel-construct
6186 kernels-construct
6187 data-construct
6188 loop-construct
6189
6190 parallel-construct:
6191 parallel-directive structured-block
6192
6193 kernels-construct:
6194 kernels-directive structured-block
6195
6196 data-construct:
6197 data-directive structured-block
6198
6199 loop-construct:
6200 loop-directive structured-block
6201
6202 OpenMP:
6203
6204 statement:
6205 attribute-specifier-sequence[opt] openmp-construct
6206
6207 openmp-construct:
6208 parallel-construct
6209 for-construct
6210 simd-construct
6211 for-simd-construct
6212 sections-construct
6213 single-construct
6214 parallel-for-construct
6215 parallel-for-simd-construct
6216 parallel-sections-construct
6217 master-construct
6218 critical-construct
6219 atomic-construct
6220 ordered-construct
6221
6222 parallel-construct:
6223 parallel-directive structured-block
6224
6225 for-construct:
6226 for-directive iteration-statement
6227
6228 simd-construct:
6229 simd-directive iteration-statements
6230
6231 for-simd-construct:
6232 for-simd-directive iteration-statements
6233
6234 sections-construct:
6235 sections-directive section-scope
6236
6237 single-construct:
6238 single-directive structured-block
6239
6240 parallel-for-construct:
6241 parallel-for-directive iteration-statement
6242
6243 parallel-for-simd-construct:
6244 parallel-for-simd-directive iteration-statement
6245
6246 parallel-sections-construct:
6247 parallel-sections-directive section-scope
6248
6249 master-construct:
6250 master-directive structured-block
6251
6252 critical-construct:
6253 critical-directive structured-block
6254
6255 atomic-construct:
6256 atomic-directive expression-statement
6257
6258 ordered-construct:
6259 ordered-directive structured-block
6260
6261 Transactional Memory:
6262
6263 statement:
6264 attribute-specifier-sequence[opt] transaction-statement
6265 attribute-specifier-sequence[opt] transaction-cancel-statement
6266
6267 IF_P is used to track whether there's a (possibly labeled) if statement
6268 which is not enclosed in braces and has an else clause. This is used to
6269 implement -Wparentheses. */
6270
6271 static void
6272 c_parser_statement (c_parser *parser, bool *if_p, location_t *loc_after_labels)
6273 {
6274 c_parser_all_labels (parser);
6275 if (loc_after_labels)
6276 *loc_after_labels = c_parser_peek_token (parser)->location;
6277 c_parser_statement_after_labels (parser, if_p, NULL);
6278 }
6279
6280 /* Parse a statement, other than a labeled statement. CHAIN is a vector
6281 of if-else-if conditions. All labels and standard attributes have
6282 been parsed in the caller.
6283
6284 IF_P is used to track whether there's a (possibly labeled) if statement
6285 which is not enclosed in braces and has an else clause. This is used to
6286 implement -Wparentheses. */
6287
6288 static void
6289 c_parser_statement_after_labels (c_parser *parser, bool *if_p,
6290 vec<tree> *chain)
6291 {
6292 location_t loc = c_parser_peek_token (parser)->location;
6293 tree stmt = NULL_TREE;
6294 bool in_if_block = parser->in_if_block;
6295 parser->in_if_block = false;
6296 if (if_p != NULL)
6297 *if_p = false;
6298
6299 if (c_parser_peek_token (parser)->type != CPP_OPEN_BRACE)
6300 add_debug_begin_stmt (loc);
6301
6302 restart:
6303 switch (c_parser_peek_token (parser)->type)
6304 {
6305 case CPP_OPEN_BRACE:
6306 add_stmt (c_parser_compound_statement (parser));
6307 break;
6308 case CPP_KEYWORD:
6309 switch (c_parser_peek_token (parser)->keyword)
6310 {
6311 case RID_IF:
6312 c_parser_if_statement (parser, if_p, chain);
6313 break;
6314 case RID_SWITCH:
6315 c_parser_switch_statement (parser, if_p);
6316 break;
6317 case RID_WHILE:
6318 c_parser_while_statement (parser, false, 0, if_p);
6319 break;
6320 case RID_DO:
6321 c_parser_do_statement (parser, false, 0);
6322 break;
6323 case RID_FOR:
6324 c_parser_for_statement (parser, false, 0, if_p);
6325 break;
6326 case RID_GOTO:
6327 c_parser_consume_token (parser);
6328 if (c_parser_next_token_is (parser, CPP_NAME))
6329 {
6330 stmt = c_finish_goto_label (loc,
6331 c_parser_peek_token (parser)->value);
6332 c_parser_consume_token (parser);
6333 }
6334 else if (c_parser_next_token_is (parser, CPP_MULT))
6335 {
6336 struct c_expr val;
6337
6338 c_parser_consume_token (parser);
6339 val = c_parser_expression (parser);
6340 val = convert_lvalue_to_rvalue (loc, val, false, true);
6341 stmt = c_finish_goto_ptr (loc, val);
6342 }
6343 else
6344 c_parser_error (parser, "expected identifier or %<*%>");
6345 goto expect_semicolon;
6346 case RID_CONTINUE:
6347 c_parser_consume_token (parser);
6348 stmt = c_finish_bc_stmt (loc, objc_foreach_continue_label, false);
6349 goto expect_semicolon;
6350 case RID_BREAK:
6351 c_parser_consume_token (parser);
6352 stmt = c_finish_bc_stmt (loc, objc_foreach_break_label, true);
6353 goto expect_semicolon;
6354 case RID_RETURN:
6355 c_parser_consume_token (parser);
6356 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6357 {
6358 stmt = c_finish_return (loc, NULL_TREE, NULL_TREE);
6359 c_parser_consume_token (parser);
6360 }
6361 else
6362 {
6363 location_t xloc = c_parser_peek_token (parser)->location;
6364 struct c_expr expr = c_parser_expression_conv (parser);
6365 mark_exp_read (expr.value);
6366 stmt = c_finish_return (EXPR_LOC_OR_LOC (expr.value, xloc),
6367 expr.value, expr.original_type);
6368 goto expect_semicolon;
6369 }
6370 break;
6371 case RID_ASM:
6372 stmt = c_parser_asm_statement (parser);
6373 break;
6374 case RID_TRANSACTION_ATOMIC:
6375 case RID_TRANSACTION_RELAXED:
6376 stmt = c_parser_transaction (parser,
6377 c_parser_peek_token (parser)->keyword);
6378 break;
6379 case RID_TRANSACTION_CANCEL:
6380 stmt = c_parser_transaction_cancel (parser);
6381 goto expect_semicolon;
6382 case RID_AT_THROW:
6383 gcc_assert (c_dialect_objc ());
6384 c_parser_consume_token (parser);
6385 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6386 {
6387 stmt = objc_build_throw_stmt (loc, NULL_TREE);
6388 c_parser_consume_token (parser);
6389 }
6390 else
6391 {
6392 struct c_expr expr = c_parser_expression (parser);
6393 expr = convert_lvalue_to_rvalue (loc, expr, false, false);
6394 expr.value = c_fully_fold (expr.value, false, NULL);
6395 stmt = objc_build_throw_stmt (loc, expr.value);
6396 goto expect_semicolon;
6397 }
6398 break;
6399 case RID_AT_TRY:
6400 gcc_assert (c_dialect_objc ());
6401 c_parser_objc_try_catch_finally_statement (parser);
6402 break;
6403 case RID_AT_SYNCHRONIZED:
6404 gcc_assert (c_dialect_objc ());
6405 c_parser_objc_synchronized_statement (parser);
6406 break;
6407 case RID_ATTRIBUTE:
6408 {
6409 /* Allow '__attribute__((fallthrough));' or
6410 '__attribute__((assume(cond)));'. */
6411 tree attrs = c_parser_gnu_attributes (parser);
6412 bool has_assume = lookup_attribute ("assume", attrs);
6413 if (has_assume)
6414 {
6415 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6416 attrs = handle_assume_attribute (loc, attrs, true);
6417 else
6418 {
6419 warning_at (loc, OPT_Wattributes,
6420 "%<assume%> attribute not followed by %<;%>");
6421 has_assume = false;
6422 }
6423 }
6424 if (attribute_fallthrough_p (attrs))
6425 {
6426 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6427 {
6428 tree fn = build_call_expr_internal_loc (loc,
6429 IFN_FALLTHROUGH,
6430 void_type_node, 0);
6431 add_stmt (fn);
6432 /* Eat the ';'. */
6433 c_parser_consume_token (parser);
6434 }
6435 else
6436 warning_at (loc, OPT_Wattributes,
6437 "%<fallthrough%> attribute not followed "
6438 "by %<;%>");
6439 }
6440 else if (has_assume)
6441 /* Eat the ';'. */
6442 c_parser_consume_token (parser);
6443 else if (attrs != NULL_TREE)
6444 warning_at (loc, OPT_Wattributes,
6445 "only attribute %<fallthrough%> or %<assume%> can "
6446 "be applied to a null statement");
6447 break;
6448 }
6449 default:
6450 goto expr_stmt;
6451 }
6452 break;
6453 case CPP_SEMICOLON:
6454 c_parser_consume_token (parser);
6455 break;
6456 case CPP_CLOSE_PAREN:
6457 case CPP_CLOSE_SQUARE:
6458 /* Avoid infinite loop in error recovery:
6459 c_parser_skip_until_found stops at a closing nesting
6460 delimiter without consuming it, but here we need to consume
6461 it to proceed further. */
6462 c_parser_error (parser, "expected statement");
6463 c_parser_consume_token (parser);
6464 break;
6465 case CPP_PRAGMA:
6466 if (!c_parser_pragma (parser, pragma_stmt, if_p))
6467 goto restart;
6468 break;
6469 default:
6470 expr_stmt:
6471 stmt = c_finish_expr_stmt (loc, c_parser_expression_conv (parser).value);
6472 expect_semicolon:
6473 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
6474 break;
6475 }
6476 /* Two cases cannot and do not have line numbers associated: If stmt
6477 is degenerate, such as "2;", then stmt is an INTEGER_CST, which
6478 cannot hold line numbers. But that's OK because the statement
6479 will either be changed to a MODIFY_EXPR during gimplification of
6480 the statement expr, or discarded. If stmt was compound, but
6481 without new variables, we will have skipped the creation of a
6482 BIND and will have a bare STATEMENT_LIST. But that's OK because
6483 (recursively) all of the component statements should already have
6484 line numbers assigned. ??? Can we discard no-op statements
6485 earlier? */
6486 if (EXPR_LOCATION (stmt) == UNKNOWN_LOCATION)
6487 protected_set_expr_location (stmt, loc);
6488
6489 parser->in_if_block = in_if_block;
6490 }
6491
6492 /* Parse the condition from an if, do, while or for statements. */
6493
6494 static tree
6495 c_parser_condition (c_parser *parser)
6496 {
6497 location_t loc = c_parser_peek_token (parser)->location;
6498 tree cond;
6499 cond = c_parser_expression_conv (parser).value;
6500 cond = c_objc_common_truthvalue_conversion (loc, cond);
6501 cond = c_fully_fold (cond, false, NULL);
6502 if (warn_sequence_point)
6503 verify_sequence_points (cond);
6504 return cond;
6505 }
6506
6507 /* Parse a parenthesized condition from an if, do or while statement.
6508
6509 condition:
6510 ( expression )
6511 */
6512 static tree
6513 c_parser_paren_condition (c_parser *parser)
6514 {
6515 tree cond;
6516 matching_parens parens;
6517 if (!parens.require_open (parser))
6518 return error_mark_node;
6519 cond = c_parser_condition (parser);
6520 parens.skip_until_found_close (parser);
6521 return cond;
6522 }
6523
6524 /* Parse a statement which is a block in C99.
6525
6526 IF_P is used to track whether there's a (possibly labeled) if statement
6527 which is not enclosed in braces and has an else clause. This is used to
6528 implement -Wparentheses. */
6529
6530 static tree
6531 c_parser_c99_block_statement (c_parser *parser, bool *if_p,
6532 location_t *loc_after_labels)
6533 {
6534 tree block = c_begin_compound_stmt (flag_isoc99);
6535 location_t loc = c_parser_peek_token (parser)->location;
6536 c_parser_statement (parser, if_p, loc_after_labels);
6537 return c_end_compound_stmt (loc, block, flag_isoc99);
6538 }
6539
6540 /* Parse the body of an if statement. This is just parsing a
6541 statement but (a) it is a block in C99, (b) we track whether the
6542 body is an if statement for the sake of -Wparentheses warnings, (c)
6543 we handle an empty body specially for the sake of -Wempty-body
6544 warnings, and (d) we call parser_compound_statement directly
6545 because c_parser_statement_after_labels resets
6546 parser->in_if_block.
6547
6548 IF_P is used to track whether there's a (possibly labeled) if statement
6549 which is not enclosed in braces and has an else clause. This is used to
6550 implement -Wparentheses. */
6551
6552 static tree
6553 c_parser_if_body (c_parser *parser, bool *if_p,
6554 const token_indent_info &if_tinfo)
6555 {
6556 tree block = c_begin_compound_stmt (flag_isoc99);
6557 location_t body_loc = c_parser_peek_token (parser)->location;
6558 location_t body_loc_after_labels = UNKNOWN_LOCATION;
6559 token_indent_info body_tinfo
6560 = get_token_indent_info (c_parser_peek_token (parser));
6561
6562 c_parser_all_labels (parser);
6563 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6564 {
6565 location_t loc = c_parser_peek_token (parser)->location;
6566 add_stmt (build_empty_stmt (loc));
6567 c_parser_consume_token (parser);
6568 if (!c_parser_next_token_is_keyword (parser, RID_ELSE))
6569 warning_at (loc, OPT_Wempty_body,
6570 "suggest braces around empty body in an %<if%> statement");
6571 }
6572 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6573 add_stmt (c_parser_compound_statement (parser));
6574 else
6575 {
6576 body_loc_after_labels = c_parser_peek_token (parser)->location;
6577 c_parser_statement_after_labels (parser, if_p);
6578 }
6579
6580 token_indent_info next_tinfo
6581 = get_token_indent_info (c_parser_peek_token (parser));
6582 warn_for_misleading_indentation (if_tinfo, body_tinfo, next_tinfo);
6583 if (body_loc_after_labels != UNKNOWN_LOCATION
6584 && next_tinfo.type != CPP_SEMICOLON)
6585 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
6586 if_tinfo.location, RID_IF);
6587
6588 return c_end_compound_stmt (body_loc, block, flag_isoc99);
6589 }
6590
6591 /* Parse the else body of an if statement. This is just parsing a
6592 statement but (a) it is a block in C99, (b) we handle an empty body
6593 specially for the sake of -Wempty-body warnings. CHAIN is a vector
6594 of if-else-if conditions. */
6595
6596 static tree
6597 c_parser_else_body (c_parser *parser, const token_indent_info &else_tinfo,
6598 vec<tree> *chain)
6599 {
6600 location_t body_loc = c_parser_peek_token (parser)->location;
6601 tree block = c_begin_compound_stmt (flag_isoc99);
6602 token_indent_info body_tinfo
6603 = get_token_indent_info (c_parser_peek_token (parser));
6604 location_t body_loc_after_labels = UNKNOWN_LOCATION;
6605
6606 c_parser_all_labels (parser);
6607 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6608 {
6609 location_t loc = c_parser_peek_token (parser)->location;
6610 warning_at (loc,
6611 OPT_Wempty_body,
6612 "suggest braces around empty body in an %<else%> statement");
6613 add_stmt (build_empty_stmt (loc));
6614 c_parser_consume_token (parser);
6615 }
6616 else
6617 {
6618 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6619 body_loc_after_labels = c_parser_peek_token (parser)->location;
6620 c_parser_statement_after_labels (parser, NULL, chain);
6621 }
6622
6623 token_indent_info next_tinfo
6624 = get_token_indent_info (c_parser_peek_token (parser));
6625 warn_for_misleading_indentation (else_tinfo, body_tinfo, next_tinfo);
6626 if (body_loc_after_labels != UNKNOWN_LOCATION
6627 && next_tinfo.type != CPP_SEMICOLON)
6628 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
6629 else_tinfo.location, RID_ELSE);
6630
6631 return c_end_compound_stmt (body_loc, block, flag_isoc99);
6632 }
6633
6634 /* We might need to reclassify any previously-lexed identifier, e.g.
6635 when we've left a for loop with an if-statement without else in the
6636 body - we might have used a wrong scope for the token. See PR67784. */
6637
6638 static void
6639 c_parser_maybe_reclassify_token (c_parser *parser)
6640 {
6641 if (c_parser_next_token_is (parser, CPP_NAME))
6642 {
6643 c_token *token = c_parser_peek_token (parser);
6644
6645 if (token->id_kind != C_ID_CLASSNAME)
6646 {
6647 tree decl = lookup_name (token->value);
6648
6649 token->id_kind = C_ID_ID;
6650 if (decl)
6651 {
6652 if (TREE_CODE (decl) == TYPE_DECL)
6653 token->id_kind = C_ID_TYPENAME;
6654 }
6655 else if (c_dialect_objc ())
6656 {
6657 tree objc_interface_decl = objc_is_class_name (token->value);
6658 /* Objective-C class names are in the same namespace as
6659 variables and typedefs, and hence are shadowed by local
6660 declarations. */
6661 if (objc_interface_decl)
6662 {
6663 token->value = objc_interface_decl;
6664 token->id_kind = C_ID_CLASSNAME;
6665 }
6666 }
6667 }
6668 }
6669 }
6670
6671 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6672
6673 if-statement:
6674 if ( expression ) statement
6675 if ( expression ) statement else statement
6676
6677 CHAIN is a vector of if-else-if conditions.
6678 IF_P is used to track whether there's a (possibly labeled) if statement
6679 which is not enclosed in braces and has an else clause. This is used to
6680 implement -Wparentheses. */
6681
6682 static void
6683 c_parser_if_statement (c_parser *parser, bool *if_p, vec<tree> *chain)
6684 {
6685 tree block;
6686 location_t loc;
6687 tree cond;
6688 bool nested_if = false;
6689 tree first_body, second_body;
6690 bool in_if_block;
6691
6692 gcc_assert (c_parser_next_token_is_keyword (parser, RID_IF));
6693 token_indent_info if_tinfo
6694 = get_token_indent_info (c_parser_peek_token (parser));
6695 c_parser_consume_token (parser);
6696 block = c_begin_compound_stmt (flag_isoc99);
6697 loc = c_parser_peek_token (parser)->location;
6698 cond = c_parser_paren_condition (parser);
6699 in_if_block = parser->in_if_block;
6700 parser->in_if_block = true;
6701 first_body = c_parser_if_body (parser, &nested_if, if_tinfo);
6702 parser->in_if_block = in_if_block;
6703
6704 if (warn_duplicated_cond)
6705 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond), cond, &chain);
6706
6707 if (c_parser_next_token_is_keyword (parser, RID_ELSE))
6708 {
6709 token_indent_info else_tinfo
6710 = get_token_indent_info (c_parser_peek_token (parser));
6711 c_parser_consume_token (parser);
6712 if (warn_duplicated_cond)
6713 {
6714 if (c_parser_next_token_is_keyword (parser, RID_IF)
6715 && chain == NULL)
6716 {
6717 /* We've got "if (COND) else if (COND2)". Start the
6718 condition chain and add COND as the first element. */
6719 chain = new vec<tree> ();
6720 if (!CONSTANT_CLASS_P (cond) && !TREE_SIDE_EFFECTS (cond))
6721 chain->safe_push (cond);
6722 }
6723 else if (!c_parser_next_token_is_keyword (parser, RID_IF))
6724 /* This is if-else without subsequent if. Zap the condition
6725 chain; we would have already warned at this point. */
6726 vec_free (chain);
6727 }
6728 second_body = c_parser_else_body (parser, else_tinfo, chain);
6729 /* Set IF_P to true to indicate that this if statement has an
6730 else clause. This may trigger the Wparentheses warning
6731 below when we get back up to the parent if statement. */
6732 if (if_p != NULL)
6733 *if_p = true;
6734 }
6735 else
6736 {
6737 second_body = NULL_TREE;
6738
6739 /* Diagnose an ambiguous else if if-then-else is nested inside
6740 if-then. */
6741 if (nested_if)
6742 warning_at (loc, OPT_Wdangling_else,
6743 "suggest explicit braces to avoid ambiguous %<else%>");
6744
6745 if (warn_duplicated_cond)
6746 /* This if statement does not have an else clause. We don't
6747 need the condition chain anymore. */
6748 vec_free (chain);
6749 }
6750 c_finish_if_stmt (loc, cond, first_body, second_body);
6751 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6752
6753 c_parser_maybe_reclassify_token (parser);
6754 }
6755
6756 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6757
6758 switch-statement:
6759 switch (expression) statement
6760 */
6761
6762 static void
6763 c_parser_switch_statement (c_parser *parser, bool *if_p)
6764 {
6765 struct c_expr ce;
6766 tree block, expr, body;
6767 unsigned char save_in_statement;
6768 location_t switch_loc = c_parser_peek_token (parser)->location;
6769 location_t switch_cond_loc;
6770 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH));
6771 c_parser_consume_token (parser);
6772 block = c_begin_compound_stmt (flag_isoc99);
6773 bool explicit_cast_p = false;
6774 matching_parens parens;
6775 if (parens.require_open (parser))
6776 {
6777 switch_cond_loc = c_parser_peek_token (parser)->location;
6778 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
6779 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
6780 explicit_cast_p = true;
6781 ce = c_parser_expression (parser);
6782 ce = convert_lvalue_to_rvalue (switch_cond_loc, ce, true, true);
6783 expr = ce.value;
6784 /* ??? expr has no valid location? */
6785 parens.skip_until_found_close (parser);
6786 }
6787 else
6788 {
6789 switch_cond_loc = UNKNOWN_LOCATION;
6790 expr = error_mark_node;
6791 ce.original_type = error_mark_node;
6792 }
6793 c_start_switch (switch_loc, switch_cond_loc, expr, explicit_cast_p);
6794 save_in_statement = in_statement;
6795 in_statement |= IN_SWITCH_STMT;
6796 location_t loc_after_labels;
6797 bool open_brace_p = c_parser_peek_token (parser)->type == CPP_OPEN_BRACE;
6798 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6799 location_t next_loc = c_parser_peek_token (parser)->location;
6800 if (!open_brace_p && c_parser_peek_token (parser)->type != CPP_SEMICOLON)
6801 warn_for_multistatement_macros (loc_after_labels, next_loc, switch_loc,
6802 RID_SWITCH);
6803 c_finish_switch (body, ce.original_type);
6804 in_statement = save_in_statement;
6805 add_stmt (c_end_compound_stmt (switch_loc, block, flag_isoc99));
6806 c_parser_maybe_reclassify_token (parser);
6807 }
6808
6809 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6810
6811 while-statement:
6812 while (expression) statement
6813
6814 IF_P is used to track whether there's a (possibly labeled) if statement
6815 which is not enclosed in braces and has an else clause. This is used to
6816 implement -Wparentheses. */
6817
6818 static void
6819 c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6820 bool *if_p)
6821 {
6822 tree block, cond, body;
6823 unsigned char save_in_statement;
6824 location_t loc;
6825 gcc_assert (c_parser_next_token_is_keyword (parser, RID_WHILE));
6826 token_indent_info while_tinfo
6827 = get_token_indent_info (c_parser_peek_token (parser));
6828 c_parser_consume_token (parser);
6829 block = c_begin_compound_stmt (flag_isoc99);
6830 loc = c_parser_peek_token (parser)->location;
6831 cond = c_parser_paren_condition (parser);
6832 if (ivdep && cond != error_mark_node)
6833 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6834 build_int_cst (integer_type_node,
6835 annot_expr_ivdep_kind),
6836 integer_zero_node);
6837 if (unroll && cond != error_mark_node)
6838 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6839 build_int_cst (integer_type_node,
6840 annot_expr_unroll_kind),
6841 build_int_cst (integer_type_node, unroll));
6842 save_in_statement = in_statement;
6843 in_statement = IN_ITERATION_STMT;
6844
6845 token_indent_info body_tinfo
6846 = get_token_indent_info (c_parser_peek_token (parser));
6847
6848 location_t loc_after_labels;
6849 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
6850 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6851 add_stmt (build_stmt (loc, WHILE_STMT, cond, body));
6852 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6853 c_parser_maybe_reclassify_token (parser);
6854
6855 token_indent_info next_tinfo
6856 = get_token_indent_info (c_parser_peek_token (parser));
6857 warn_for_misleading_indentation (while_tinfo, body_tinfo, next_tinfo);
6858
6859 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
6860 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
6861 while_tinfo.location, RID_WHILE);
6862
6863 in_statement = save_in_statement;
6864 }
6865
6866 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6867
6868 do-statement:
6869 do statement while ( expression ) ;
6870 */
6871
6872 static void
6873 c_parser_do_statement (c_parser *parser, bool ivdep, unsigned short unroll)
6874 {
6875 tree block, cond, body;
6876 unsigned char save_in_statement;
6877 location_t loc;
6878 gcc_assert (c_parser_next_token_is_keyword (parser, RID_DO));
6879 c_parser_consume_token (parser);
6880 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6881 warning_at (c_parser_peek_token (parser)->location,
6882 OPT_Wempty_body,
6883 "suggest braces around empty body in %<do%> statement");
6884 block = c_begin_compound_stmt (flag_isoc99);
6885 loc = c_parser_peek_token (parser)->location;
6886 save_in_statement = in_statement;
6887 in_statement = IN_ITERATION_STMT;
6888 body = c_parser_c99_block_statement (parser, NULL);
6889 c_parser_require_keyword (parser, RID_WHILE, "expected %<while%>");
6890 in_statement = save_in_statement;
6891 cond = c_parser_paren_condition (parser);
6892 if (ivdep && cond != error_mark_node)
6893 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6894 build_int_cst (integer_type_node,
6895 annot_expr_ivdep_kind),
6896 integer_zero_node);
6897 if (unroll && cond != error_mark_node)
6898 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6899 build_int_cst (integer_type_node,
6900 annot_expr_unroll_kind),
6901 build_int_cst (integer_type_node, unroll));
6902 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
6903 c_parser_skip_to_end_of_block_or_statement (parser);
6904
6905 add_stmt (build_stmt (loc, DO_STMT, cond, body));
6906 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6907 }
6908
6909 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6910
6911 for-statement:
6912 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
6913 for ( nested-declaration expression[opt] ; expression[opt] ) statement
6914
6915 The form with a declaration is new in C99.
6916
6917 ??? In accordance with the old parser, the declaration may be a
6918 nested function, which is then rejected in check_for_loop_decls,
6919 but does it make any sense for this to be included in the grammar?
6920 Note in particular that the nested function does not include a
6921 trailing ';', whereas the "declaration" production includes one.
6922 Also, can we reject bad declarations earlier and cheaper than
6923 check_for_loop_decls?
6924
6925 In Objective-C, there are two additional variants:
6926
6927 foreach-statement:
6928 for ( expression in expresssion ) statement
6929 for ( declaration in expression ) statement
6930
6931 This is inconsistent with C, because the second variant is allowed
6932 even if c99 is not enabled.
6933
6934 The rest of the comment documents these Objective-C foreach-statement.
6935
6936 Here is the canonical example of the first variant:
6937 for (object in array) { do something with object }
6938 we call the first expression ("object") the "object_expression" and
6939 the second expression ("array") the "collection_expression".
6940 object_expression must be an lvalue of type "id" (a generic Objective-C
6941 object) because the loop works by assigning to object_expression the
6942 various objects from the collection_expression. collection_expression
6943 must evaluate to something of type "id" which responds to the method
6944 countByEnumeratingWithState:objects:count:.
6945
6946 The canonical example of the second variant is:
6947 for (id object in array) { do something with object }
6948 which is completely equivalent to
6949 {
6950 id object;
6951 for (object in array) { do something with object }
6952 }
6953 Note that initizializing 'object' in some way (eg, "for ((object =
6954 xxx) in array) { do something with object }") is possibly
6955 technically valid, but completely pointless as 'object' will be
6956 assigned to something else as soon as the loop starts. We should
6957 most likely reject it (TODO).
6958
6959 The beginning of the Objective-C foreach-statement looks exactly
6960 like the beginning of the for-statement, and we can tell it is a
6961 foreach-statement only because the initial declaration or
6962 expression is terminated by 'in' instead of ';'.
6963
6964 IF_P is used to track whether there's a (possibly labeled) if statement
6965 which is not enclosed in braces and has an else clause. This is used to
6966 implement -Wparentheses. */
6967
6968 static void
6969 c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6970 bool *if_p)
6971 {
6972 tree block, cond, incr, body;
6973 unsigned char save_in_statement;
6974 tree save_objc_foreach_break_label, save_objc_foreach_continue_label;
6975 /* The following are only used when parsing an ObjC foreach statement. */
6976 tree object_expression;
6977 /* Silence the bogus uninitialized warning. */
6978 tree collection_expression = NULL;
6979 location_t loc = c_parser_peek_token (parser)->location;
6980 location_t for_loc = loc;
6981 bool is_foreach_statement = false;
6982 gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
6983 token_indent_info for_tinfo
6984 = get_token_indent_info (c_parser_peek_token (parser));
6985 c_parser_consume_token (parser);
6986 /* Open a compound statement in Objective-C as well, just in case this is
6987 as foreach expression. */
6988 block = c_begin_compound_stmt (flag_isoc99 || c_dialect_objc ());
6989 cond = error_mark_node;
6990 incr = error_mark_node;
6991 matching_parens parens;
6992 if (parens.require_open (parser))
6993 {
6994 /* Parse the initialization declaration or expression. */
6995 object_expression = error_mark_node;
6996 parser->objc_could_be_foreach_context = c_dialect_objc ();
6997 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6998 {
6999 parser->objc_could_be_foreach_context = false;
7000 c_parser_consume_token (parser);
7001 c_finish_expr_stmt (loc, NULL_TREE);
7002 }
7003 else if (c_parser_next_tokens_start_declaration (parser)
7004 || c_parser_nth_token_starts_std_attributes (parser, 1))
7005 {
7006 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
7007 &object_expression);
7008 parser->objc_could_be_foreach_context = false;
7009
7010 if (c_parser_next_token_is_keyword (parser, RID_IN))
7011 {
7012 c_parser_consume_token (parser);
7013 is_foreach_statement = true;
7014 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
7015 c_parser_error (parser, "multiple iterating variables in "
7016 "fast enumeration");
7017 }
7018 else
7019 check_for_loop_decls (for_loc, flag_isoc99);
7020 }
7021 else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
7022 {
7023 /* __extension__ can start a declaration, but is also an
7024 unary operator that can start an expression. Consume all
7025 but the last of a possible series of __extension__ to
7026 determine which. */
7027 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
7028 && (c_parser_peek_2nd_token (parser)->keyword
7029 == RID_EXTENSION))
7030 c_parser_consume_token (parser);
7031 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
7032 || c_parser_nth_token_starts_std_attributes (parser, 2))
7033 {
7034 int ext;
7035 ext = disable_extension_diagnostics ();
7036 c_parser_consume_token (parser);
7037 c_parser_declaration_or_fndef (parser, true, true, true, true,
7038 true, &object_expression);
7039 parser->objc_could_be_foreach_context = false;
7040
7041 restore_extension_diagnostics (ext);
7042 if (c_parser_next_token_is_keyword (parser, RID_IN))
7043 {
7044 c_parser_consume_token (parser);
7045 is_foreach_statement = true;
7046 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
7047 c_parser_error (parser, "multiple iterating variables in "
7048 "fast enumeration");
7049 }
7050 else
7051 check_for_loop_decls (for_loc, flag_isoc99);
7052 }
7053 else
7054 goto init_expr;
7055 }
7056 else
7057 {
7058 init_expr:
7059 {
7060 struct c_expr ce;
7061 tree init_expression;
7062 ce = c_parser_expression (parser);
7063 init_expression = ce.value;
7064 parser->objc_could_be_foreach_context = false;
7065 if (c_parser_next_token_is_keyword (parser, RID_IN))
7066 {
7067 c_parser_consume_token (parser);
7068 is_foreach_statement = true;
7069 if (! lvalue_p (init_expression))
7070 c_parser_error (parser, "invalid iterating variable in "
7071 "fast enumeration");
7072 object_expression
7073 = c_fully_fold (init_expression, false, NULL);
7074 }
7075 else
7076 {
7077 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
7078 init_expression = ce.value;
7079 c_finish_expr_stmt (loc, init_expression);
7080 c_parser_skip_until_found (parser, CPP_SEMICOLON,
7081 "expected %<;%>");
7082 }
7083 }
7084 }
7085 /* Parse the loop condition. In the case of a foreach
7086 statement, there is no loop condition. */
7087 gcc_assert (!parser->objc_could_be_foreach_context);
7088 if (!is_foreach_statement)
7089 {
7090 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
7091 {
7092 if (ivdep)
7093 {
7094 c_parser_error (parser, "missing loop condition in loop "
7095 "with %<GCC ivdep%> pragma");
7096 cond = error_mark_node;
7097 }
7098 else if (unroll)
7099 {
7100 c_parser_error (parser, "missing loop condition in loop "
7101 "with %<GCC unroll%> pragma");
7102 cond = error_mark_node;
7103 }
7104 else
7105 {
7106 c_parser_consume_token (parser);
7107 cond = NULL_TREE;
7108 }
7109 }
7110 else
7111 {
7112 cond = c_parser_condition (parser);
7113 c_parser_skip_until_found (parser, CPP_SEMICOLON,
7114 "expected %<;%>");
7115 }
7116 if (ivdep && cond != error_mark_node)
7117 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
7118 build_int_cst (integer_type_node,
7119 annot_expr_ivdep_kind),
7120 integer_zero_node);
7121 if (unroll && cond != error_mark_node)
7122 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
7123 build_int_cst (integer_type_node,
7124 annot_expr_unroll_kind),
7125 build_int_cst (integer_type_node, unroll));
7126 }
7127 /* Parse the increment expression (the third expression in a
7128 for-statement). In the case of a foreach-statement, this is
7129 the expression that follows the 'in'. */
7130 loc = c_parser_peek_token (parser)->location;
7131 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
7132 {
7133 if (is_foreach_statement)
7134 {
7135 c_parser_error (parser,
7136 "missing collection in fast enumeration");
7137 collection_expression = error_mark_node;
7138 }
7139 else
7140 incr = c_process_expr_stmt (loc, NULL_TREE);
7141 }
7142 else
7143 {
7144 if (is_foreach_statement)
7145 collection_expression
7146 = c_fully_fold (c_parser_expression (parser).value, false, NULL);
7147 else
7148 {
7149 struct c_expr ce = c_parser_expression (parser);
7150 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
7151 incr = c_process_expr_stmt (loc, ce.value);
7152 }
7153 }
7154 parens.skip_until_found_close (parser);
7155 }
7156 save_in_statement = in_statement;
7157 if (is_foreach_statement)
7158 {
7159 in_statement = IN_OBJC_FOREACH;
7160 save_objc_foreach_break_label = objc_foreach_break_label;
7161 save_objc_foreach_continue_label = objc_foreach_continue_label;
7162 objc_foreach_break_label = create_artificial_label (loc);
7163 objc_foreach_continue_label = create_artificial_label (loc);
7164 }
7165 else
7166 in_statement = IN_ITERATION_STMT;
7167
7168 token_indent_info body_tinfo
7169 = get_token_indent_info (c_parser_peek_token (parser));
7170
7171 location_t loc_after_labels;
7172 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
7173 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
7174
7175 if (is_foreach_statement)
7176 objc_finish_foreach_loop (for_loc, object_expression,
7177 collection_expression, body,
7178 objc_foreach_break_label,
7179 objc_foreach_continue_label);
7180 else
7181 add_stmt (build_stmt (for_loc, FOR_STMT, NULL_TREE, cond, incr,
7182 body, NULL_TREE));
7183 add_stmt (c_end_compound_stmt (for_loc, block,
7184 flag_isoc99 || c_dialect_objc ()));
7185 c_parser_maybe_reclassify_token (parser);
7186
7187 token_indent_info next_tinfo
7188 = get_token_indent_info (c_parser_peek_token (parser));
7189 warn_for_misleading_indentation (for_tinfo, body_tinfo, next_tinfo);
7190
7191 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
7192 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
7193 for_tinfo.location, RID_FOR);
7194
7195 in_statement = save_in_statement;
7196 if (is_foreach_statement)
7197 {
7198 objc_foreach_break_label = save_objc_foreach_break_label;
7199 objc_foreach_continue_label = save_objc_foreach_continue_label;
7200 }
7201 }
7202
7203 /* Parse an asm statement, a GNU extension. This is a full-blown asm
7204 statement with inputs, outputs, clobbers, and volatile, inline, and goto
7205 tags allowed.
7206
7207 asm-qualifier:
7208 volatile
7209 inline
7210 goto
7211
7212 asm-qualifier-list:
7213 asm-qualifier-list asm-qualifier
7214 asm-qualifier
7215
7216 asm-statement:
7217 asm asm-qualifier-list[opt] ( asm-argument ) ;
7218
7219 asm-argument:
7220 asm-string-literal
7221 asm-string-literal : asm-operands[opt]
7222 asm-string-literal : asm-operands[opt] : asm-operands[opt]
7223 asm-string-literal : asm-operands[opt] : asm-operands[opt] \
7224 : asm-clobbers[opt]
7225 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
7226 : asm-goto-operands
7227
7228 The form with asm-goto-operands is valid if and only if the
7229 asm-qualifier-list contains goto, and is the only allowed form in that case.
7230 Duplicate asm-qualifiers are not allowed.
7231
7232 The :: token is considered equivalent to two consecutive : tokens. */
7233
7234 static tree
7235 c_parser_asm_statement (c_parser *parser)
7236 {
7237 tree str, outputs, inputs, clobbers, labels, ret;
7238 bool simple;
7239 location_t asm_loc = c_parser_peek_token (parser)->location;
7240 int section, nsections;
7241
7242 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
7243 c_parser_consume_token (parser);
7244
7245 /* Handle the asm-qualifier-list. */
7246 location_t volatile_loc = UNKNOWN_LOCATION;
7247 location_t inline_loc = UNKNOWN_LOCATION;
7248 location_t goto_loc = UNKNOWN_LOCATION;
7249 for (;;)
7250 {
7251 c_token *token = c_parser_peek_token (parser);
7252 location_t loc = token->location;
7253 switch (token->keyword)
7254 {
7255 case RID_VOLATILE:
7256 if (volatile_loc)
7257 {
7258 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7259 inform (volatile_loc, "first seen here");
7260 }
7261 else
7262 volatile_loc = loc;
7263 c_parser_consume_token (parser);
7264 continue;
7265
7266 case RID_INLINE:
7267 if (inline_loc)
7268 {
7269 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7270 inform (inline_loc, "first seen here");
7271 }
7272 else
7273 inline_loc = loc;
7274 c_parser_consume_token (parser);
7275 continue;
7276
7277 case RID_GOTO:
7278 if (goto_loc)
7279 {
7280 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7281 inform (goto_loc, "first seen here");
7282 }
7283 else
7284 goto_loc = loc;
7285 c_parser_consume_token (parser);
7286 continue;
7287
7288 case RID_CONST:
7289 case RID_RESTRICT:
7290 error_at (loc, "%qE is not a valid %<asm%> qualifier", token->value);
7291 c_parser_consume_token (parser);
7292 continue;
7293
7294 default:
7295 break;
7296 }
7297 break;
7298 }
7299
7300 bool is_volatile = (volatile_loc != UNKNOWN_LOCATION);
7301 bool is_inline = (inline_loc != UNKNOWN_LOCATION);
7302 bool is_goto = (goto_loc != UNKNOWN_LOCATION);
7303
7304 ret = NULL;
7305
7306 matching_parens parens;
7307 if (!parens.require_open (parser))
7308 goto error;
7309
7310 str = c_parser_asm_string_literal (parser);
7311 if (str == NULL_TREE)
7312 goto error_close_paren;
7313
7314 simple = true;
7315 outputs = NULL_TREE;
7316 inputs = NULL_TREE;
7317 clobbers = NULL_TREE;
7318 labels = NULL_TREE;
7319
7320 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
7321 goto done_asm;
7322
7323 /* Parse each colon-delimited section of operands. */
7324 nsections = 3 + is_goto;
7325 for (section = 0; section < nsections; ++section)
7326 {
7327 if (c_parser_next_token_is (parser, CPP_SCOPE))
7328 {
7329 ++section;
7330 if (section == nsections)
7331 {
7332 c_parser_error (parser, "expected %<)%>");
7333 goto error_close_paren;
7334 }
7335 c_parser_consume_token (parser);
7336 }
7337 else if (!c_parser_require (parser, CPP_COLON,
7338 is_goto
7339 ? G_("expected %<:%>")
7340 : G_("expected %<:%> or %<)%>"),
7341 UNKNOWN_LOCATION, is_goto))
7342 goto error_close_paren;
7343
7344 /* Once past any colon, we're no longer a simple asm. */
7345 simple = false;
7346
7347 if ((!c_parser_next_token_is (parser, CPP_COLON)
7348 && !c_parser_next_token_is (parser, CPP_SCOPE)
7349 && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
7350 || section == 3)
7351 switch (section)
7352 {
7353 case 0:
7354 outputs = c_parser_asm_operands (parser);
7355 break;
7356 case 1:
7357 inputs = c_parser_asm_operands (parser);
7358 break;
7359 case 2:
7360 clobbers = c_parser_asm_clobbers (parser);
7361 break;
7362 case 3:
7363 labels = c_parser_asm_goto_operands (parser);
7364 break;
7365 default:
7366 gcc_unreachable ();
7367 }
7368
7369 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
7370 goto done_asm;
7371 }
7372
7373 done_asm:
7374 if (!parens.require_close (parser))
7375 {
7376 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7377 goto error;
7378 }
7379
7380 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
7381 c_parser_skip_to_end_of_block_or_statement (parser);
7382
7383 ret = build_asm_stmt (is_volatile,
7384 build_asm_expr (asm_loc, str, outputs, inputs,
7385 clobbers, labels, simple, is_inline));
7386
7387 error:
7388 return ret;
7389
7390 error_close_paren:
7391 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7392 goto error;
7393 }
7394
7395 /* Parse asm operands, a GNU extension.
7396
7397 asm-operands:
7398 asm-operand
7399 asm-operands , asm-operand
7400
7401 asm-operand:
7402 asm-string-literal ( expression )
7403 [ identifier ] asm-string-literal ( expression )
7404 */
7405
7406 static tree
7407 c_parser_asm_operands (c_parser *parser)
7408 {
7409 tree list = NULL_TREE;
7410 while (true)
7411 {
7412 tree name, str;
7413 struct c_expr expr;
7414 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
7415 {
7416 c_parser_consume_token (parser);
7417 if (c_parser_next_token_is (parser, CPP_NAME))
7418 {
7419 tree id = c_parser_peek_token (parser)->value;
7420 c_parser_consume_token (parser);
7421 name = build_string (IDENTIFIER_LENGTH (id),
7422 IDENTIFIER_POINTER (id));
7423 }
7424 else
7425 {
7426 c_parser_error (parser, "expected identifier");
7427 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
7428 return NULL_TREE;
7429 }
7430 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
7431 "expected %<]%>");
7432 }
7433 else
7434 name = NULL_TREE;
7435 str = c_parser_asm_string_literal (parser);
7436 if (str == NULL_TREE)
7437 return NULL_TREE;
7438 matching_parens parens;
7439 if (!parens.require_open (parser))
7440 return NULL_TREE;
7441 expr = c_parser_expression (parser);
7442 mark_exp_read (expr.value);
7443 if (!parens.require_close (parser))
7444 {
7445 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7446 return NULL_TREE;
7447 }
7448 list = chainon (list, build_tree_list (build_tree_list (name, str),
7449 expr.value));
7450 if (c_parser_next_token_is (parser, CPP_COMMA))
7451 c_parser_consume_token (parser);
7452 else
7453 break;
7454 }
7455 return list;
7456 }
7457
7458 /* Parse asm clobbers, a GNU extension.
7459
7460 asm-clobbers:
7461 asm-string-literal
7462 asm-clobbers , asm-string-literal
7463 */
7464
7465 static tree
7466 c_parser_asm_clobbers (c_parser *parser)
7467 {
7468 tree list = NULL_TREE;
7469 while (true)
7470 {
7471 tree str = c_parser_asm_string_literal (parser);
7472 if (str)
7473 list = tree_cons (NULL_TREE, str, list);
7474 else
7475 return NULL_TREE;
7476 if (c_parser_next_token_is (parser, CPP_COMMA))
7477 c_parser_consume_token (parser);
7478 else
7479 break;
7480 }
7481 return list;
7482 }
7483
7484 /* Parse asm goto labels, a GNU extension.
7485
7486 asm-goto-operands:
7487 identifier
7488 asm-goto-operands , identifier
7489 */
7490
7491 static tree
7492 c_parser_asm_goto_operands (c_parser *parser)
7493 {
7494 tree list = NULL_TREE;
7495 while (true)
7496 {
7497 tree name, label;
7498
7499 if (c_parser_next_token_is (parser, CPP_NAME))
7500 {
7501 c_token *tok = c_parser_peek_token (parser);
7502 name = tok->value;
7503 label = lookup_label_for_goto (tok->location, name);
7504 c_parser_consume_token (parser);
7505 TREE_USED (label) = 1;
7506 }
7507 else
7508 {
7509 c_parser_error (parser, "expected identifier");
7510 return NULL_TREE;
7511 }
7512
7513 name = build_string (IDENTIFIER_LENGTH (name),
7514 IDENTIFIER_POINTER (name));
7515 list = tree_cons (name, label, list);
7516 if (c_parser_next_token_is (parser, CPP_COMMA))
7517 c_parser_consume_token (parser);
7518 else
7519 return nreverse (list);
7520 }
7521 }
7522
7523 /* Parse a possibly concatenated sequence of string literals.
7524 TRANSLATE says whether to translate them to the execution character
7525 set; WIDE_OK says whether any kind of prefixed string literal is
7526 permitted in this context. This code is based on that in
7527 lex_string. */
7528
7529 struct c_expr
7530 c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok)
7531 {
7532 struct c_expr ret;
7533 size_t count;
7534 struct obstack str_ob;
7535 struct obstack loc_ob;
7536 cpp_string str, istr, *strs;
7537 c_token *tok;
7538 location_t loc, last_tok_loc;
7539 enum cpp_ttype type;
7540 tree value, string_tree;
7541
7542 tok = c_parser_peek_token (parser);
7543 loc = tok->location;
7544 last_tok_loc = linemap_resolve_location (line_table, loc,
7545 LRK_MACRO_DEFINITION_LOCATION,
7546 NULL);
7547 type = tok->type;
7548 switch (type)
7549 {
7550 case CPP_STRING:
7551 case CPP_WSTRING:
7552 case CPP_STRING16:
7553 case CPP_STRING32:
7554 case CPP_UTF8STRING:
7555 string_tree = tok->value;
7556 break;
7557
7558 default:
7559 c_parser_error (parser, "expected string literal");
7560 ret.set_error ();
7561 ret.value = NULL_TREE;
7562 ret.original_code = ERROR_MARK;
7563 ret.original_type = NULL_TREE;
7564 return ret;
7565 }
7566
7567 /* Try to avoid the overhead of creating and destroying an obstack
7568 for the common case of just one string. */
7569 switch (c_parser_peek_2nd_token (parser)->type)
7570 {
7571 default:
7572 c_parser_consume_token (parser);
7573 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
7574 str.len = TREE_STRING_LENGTH (string_tree);
7575 count = 1;
7576 strs = &str;
7577 break;
7578
7579 case CPP_STRING:
7580 case CPP_WSTRING:
7581 case CPP_STRING16:
7582 case CPP_STRING32:
7583 case CPP_UTF8STRING:
7584 gcc_obstack_init (&str_ob);
7585 gcc_obstack_init (&loc_ob);
7586 count = 0;
7587 do
7588 {
7589 c_parser_consume_token (parser);
7590 count++;
7591 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
7592 str.len = TREE_STRING_LENGTH (string_tree);
7593 if (type != tok->type)
7594 {
7595 if (type == CPP_STRING)
7596 type = tok->type;
7597 else if (tok->type != CPP_STRING)
7598 error ("unsupported non-standard concatenation "
7599 "of string literals");
7600 }
7601 obstack_grow (&str_ob, &str, sizeof (cpp_string));
7602 obstack_grow (&loc_ob, &last_tok_loc, sizeof (location_t));
7603 tok = c_parser_peek_token (parser);
7604 string_tree = tok->value;
7605 last_tok_loc
7606 = linemap_resolve_location (line_table, tok->location,
7607 LRK_MACRO_DEFINITION_LOCATION, NULL);
7608 }
7609 while (tok->type == CPP_STRING
7610 || tok->type == CPP_WSTRING
7611 || tok->type == CPP_STRING16
7612 || tok->type == CPP_STRING32
7613 || tok->type == CPP_UTF8STRING);
7614 strs = (cpp_string *) obstack_finish (&str_ob);
7615 }
7616
7617 if (count > 1 && !in_system_header_at (input_location))
7618 warning (OPT_Wtraditional,
7619 "traditional C rejects string constant concatenation");
7620
7621 if ((type == CPP_STRING || wide_ok)
7622 && ((translate
7623 ? cpp_interpret_string : cpp_interpret_string_notranslate)
7624 (parse_in, strs, count, &istr, type)))
7625 {
7626 value = build_string (istr.len, (const char *) istr.text);
7627 free (CONST_CAST (unsigned char *, istr.text));
7628 if (count > 1)
7629 {
7630 location_t *locs = (location_t *) obstack_finish (&loc_ob);
7631 gcc_assert (g_string_concat_db);
7632 g_string_concat_db->record_string_concatenation (count, locs);
7633 }
7634 }
7635 else
7636 {
7637 if (type != CPP_STRING && !wide_ok)
7638 {
7639 error_at (loc, "a wide string is invalid in this context");
7640 type = CPP_STRING;
7641 }
7642 /* Callers cannot generally handle error_mark_node in this
7643 context, so return the empty string instead. An error has
7644 been issued, either above or from cpp_interpret_string. */
7645 switch (type)
7646 {
7647 default:
7648 case CPP_STRING:
7649 case CPP_UTF8STRING:
7650 if (type == CPP_UTF8STRING && flag_char8_t)
7651 {
7652 value = build_string (TYPE_PRECISION (char8_type_node)
7653 / TYPE_PRECISION (char_type_node),
7654 ""); /* char8_t is 8 bits */
7655 }
7656 else
7657 value = build_string (1, "");
7658 break;
7659 case CPP_STRING16:
7660 value = build_string (TYPE_PRECISION (char16_type_node)
7661 / TYPE_PRECISION (char_type_node),
7662 "\0"); /* char16_t is 16 bits */
7663 break;
7664 case CPP_STRING32:
7665 value = build_string (TYPE_PRECISION (char32_type_node)
7666 / TYPE_PRECISION (char_type_node),
7667 "\0\0\0"); /* char32_t is 32 bits */
7668 break;
7669 case CPP_WSTRING:
7670 value = build_string (TYPE_PRECISION (wchar_type_node)
7671 / TYPE_PRECISION (char_type_node),
7672 "\0\0\0"); /* widest supported wchar_t
7673 is 32 bits */
7674 break;
7675 }
7676 }
7677
7678 switch (type)
7679 {
7680 default:
7681 case CPP_STRING:
7682 TREE_TYPE (value) = char_array_type_node;
7683 break;
7684 case CPP_UTF8STRING:
7685 if (flag_char8_t)
7686 TREE_TYPE (value) = char8_array_type_node;
7687 else
7688 TREE_TYPE (value) = char_array_type_node;
7689 break;
7690 case CPP_STRING16:
7691 TREE_TYPE (value) = char16_array_type_node;
7692 break;
7693 case CPP_STRING32:
7694 TREE_TYPE (value) = char32_array_type_node;
7695 break;
7696 case CPP_WSTRING:
7697 TREE_TYPE (value) = wchar_array_type_node;
7698 }
7699 value = fix_string_type (value);
7700
7701 if (count > 1)
7702 {
7703 obstack_free (&str_ob, 0);
7704 obstack_free (&loc_ob, 0);
7705 }
7706
7707 ret.value = value;
7708 ret.original_code = STRING_CST;
7709 ret.original_type = NULL_TREE;
7710 set_c_expr_source_range (&ret, get_range_from_loc (line_table, loc));
7711 ret.m_decimal = 0;
7712 parser->seen_string_literal = true;
7713 return ret;
7714 }
7715
7716 /* Parse an expression other than a compound expression; that is, an
7717 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If
7718 AFTER is not NULL then it is an Objective-C message expression which
7719 is the primary-expression starting the expression as an initializer.
7720
7721 assignment-expression:
7722 conditional-expression
7723 unary-expression assignment-operator assignment-expression
7724
7725 assignment-operator: one of
7726 = *= /= %= += -= <<= >>= &= ^= |=
7727
7728 In GNU C we accept any conditional expression on the LHS and
7729 diagnose the invalid lvalue rather than producing a syntax
7730 error. */
7731
7732 static struct c_expr
7733 c_parser_expr_no_commas (c_parser *parser, struct c_expr *after,
7734 tree omp_atomic_lhs)
7735 {
7736 struct c_expr lhs, rhs, ret;
7737 enum tree_code code;
7738 location_t op_location, exp_location;
7739 bool save_in_omp_for = c_in_omp_for;
7740 c_in_omp_for = false;
7741 gcc_assert (!after || c_dialect_objc ());
7742 lhs = c_parser_conditional_expression (parser, after, omp_atomic_lhs);
7743 op_location = c_parser_peek_token (parser)->location;
7744 switch (c_parser_peek_token (parser)->type)
7745 {
7746 case CPP_EQ:
7747 code = NOP_EXPR;
7748 break;
7749 case CPP_MULT_EQ:
7750 code = MULT_EXPR;
7751 break;
7752 case CPP_DIV_EQ:
7753 code = TRUNC_DIV_EXPR;
7754 break;
7755 case CPP_MOD_EQ:
7756 code = TRUNC_MOD_EXPR;
7757 break;
7758 case CPP_PLUS_EQ:
7759 code = PLUS_EXPR;
7760 break;
7761 case CPP_MINUS_EQ:
7762 code = MINUS_EXPR;
7763 break;
7764 case CPP_LSHIFT_EQ:
7765 code = LSHIFT_EXPR;
7766 break;
7767 case CPP_RSHIFT_EQ:
7768 code = RSHIFT_EXPR;
7769 break;
7770 case CPP_AND_EQ:
7771 code = BIT_AND_EXPR;
7772 break;
7773 case CPP_XOR_EQ:
7774 code = BIT_XOR_EXPR;
7775 break;
7776 case CPP_OR_EQ:
7777 code = BIT_IOR_EXPR;
7778 break;
7779 default:
7780 c_in_omp_for = save_in_omp_for;
7781 return lhs;
7782 }
7783 c_parser_consume_token (parser);
7784 exp_location = c_parser_peek_token (parser)->location;
7785 rhs = c_parser_expr_no_commas (parser, NULL);
7786 rhs = convert_lvalue_to_rvalue (exp_location, rhs, true, true);
7787
7788 ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
7789 code, exp_location, rhs.value,
7790 rhs.original_type);
7791 ret.m_decimal = 0;
7792 set_c_expr_source_range (&ret, lhs.get_start (), rhs.get_finish ());
7793 if (code == NOP_EXPR)
7794 ret.original_code = MODIFY_EXPR;
7795 else
7796 {
7797 suppress_warning (ret.value, OPT_Wparentheses);
7798 ret.original_code = ERROR_MARK;
7799 }
7800 ret.original_type = NULL;
7801 c_in_omp_for = save_in_omp_for;
7802 return ret;
7803 }
7804
7805 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If
7806 AFTER is not NULL then it is an Objective-C message expression which is
7807 the primary-expression starting the expression as an initializer.
7808
7809 conditional-expression:
7810 logical-OR-expression
7811 logical-OR-expression ? expression : conditional-expression
7812
7813 GNU extensions:
7814
7815 conditional-expression:
7816 logical-OR-expression ? : conditional-expression
7817 */
7818
7819 static struct c_expr
7820 c_parser_conditional_expression (c_parser *parser, struct c_expr *after,
7821 tree omp_atomic_lhs)
7822 {
7823 struct c_expr cond, exp1, exp2, ret;
7824 location_t start, cond_loc, colon_loc;
7825
7826 gcc_assert (!after || c_dialect_objc ());
7827
7828 cond = c_parser_binary_expression (parser, after, omp_atomic_lhs);
7829
7830 if (c_parser_next_token_is_not (parser, CPP_QUERY))
7831 return cond;
7832 if (cond.value != error_mark_node)
7833 start = cond.get_start ();
7834 else
7835 start = UNKNOWN_LOCATION;
7836 cond_loc = c_parser_peek_token (parser)->location;
7837 cond = convert_lvalue_to_rvalue (cond_loc, cond, true, true);
7838 c_parser_consume_token (parser);
7839 if (c_parser_next_token_is (parser, CPP_COLON))
7840 {
7841 tree eptype = NULL_TREE;
7842
7843 location_t middle_loc = c_parser_peek_token (parser)->location;
7844 pedwarn (middle_loc, OPT_Wpedantic,
7845 "ISO C forbids omitting the middle term of a %<?:%> expression");
7846 if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR)
7847 {
7848 eptype = TREE_TYPE (cond.value);
7849 cond.value = TREE_OPERAND (cond.value, 0);
7850 }
7851 tree e = cond.value;
7852 while (TREE_CODE (e) == COMPOUND_EXPR)
7853 e = TREE_OPERAND (e, 1);
7854 warn_for_omitted_condop (middle_loc, e);
7855 /* Make sure first operand is calculated only once. */
7856 exp1.value = save_expr (default_conversion (cond.value));
7857 if (eptype)
7858 exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value);
7859 exp1.original_type = NULL;
7860 exp1.src_range = cond.src_range;
7861 cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value);
7862 c_inhibit_evaluation_warnings += cond.value == truthvalue_true_node;
7863 }
7864 else
7865 {
7866 cond.value
7867 = c_objc_common_truthvalue_conversion
7868 (cond_loc, default_conversion (cond.value));
7869 c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node;
7870 exp1 = c_parser_expression_conv (parser);
7871 mark_exp_read (exp1.value);
7872 c_inhibit_evaluation_warnings +=
7873 ((cond.value == truthvalue_true_node)
7874 - (cond.value == truthvalue_false_node));
7875 }
7876
7877 colon_loc = c_parser_peek_token (parser)->location;
7878 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
7879 {
7880 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
7881 ret.set_error ();
7882 ret.original_code = ERROR_MARK;
7883 ret.original_type = NULL;
7884 return ret;
7885 }
7886 {
7887 location_t exp2_loc = c_parser_peek_token (parser)->location;
7888 exp2 = c_parser_conditional_expression (parser, NULL, NULL_TREE);
7889 exp2 = convert_lvalue_to_rvalue (exp2_loc, exp2, true, true);
7890 }
7891 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
7892 location_t loc1 = make_location (exp1.get_start (), exp1.src_range);
7893 location_t loc2 = make_location (exp2.get_start (), exp2.src_range);
7894 if (UNLIKELY (omp_atomic_lhs != NULL)
7895 && (TREE_CODE (cond.value) == GT_EXPR
7896 || TREE_CODE (cond.value) == LT_EXPR
7897 || TREE_CODE (cond.value) == EQ_EXPR)
7898 && c_tree_equal (exp2.value, omp_atomic_lhs)
7899 && (c_tree_equal (TREE_OPERAND (cond.value, 0), omp_atomic_lhs)
7900 || c_tree_equal (TREE_OPERAND (cond.value, 1), omp_atomic_lhs)))
7901 ret.value = build3_loc (colon_loc, COND_EXPR, TREE_TYPE (omp_atomic_lhs),
7902 cond.value, exp1.value, exp2.value);
7903 else
7904 ret.value
7905 = build_conditional_expr (colon_loc, cond.value,
7906 cond.original_code == C_MAYBE_CONST_EXPR,
7907 exp1.value, exp1.original_type, loc1,
7908 exp2.value, exp2.original_type, loc2);
7909 ret.original_code = ERROR_MARK;
7910 if (exp1.value == error_mark_node || exp2.value == error_mark_node)
7911 ret.original_type = NULL;
7912 else
7913 {
7914 tree t1, t2;
7915
7916 /* If both sides are enum type, the default conversion will have
7917 made the type of the result be an integer type. We want to
7918 remember the enum types we started with. */
7919 t1 = exp1.original_type ? exp1.original_type : TREE_TYPE (exp1.value);
7920 t2 = exp2.original_type ? exp2.original_type : TREE_TYPE (exp2.value);
7921 ret.original_type = ((t1 != error_mark_node
7922 && t2 != error_mark_node
7923 && (TYPE_MAIN_VARIANT (t1)
7924 == TYPE_MAIN_VARIANT (t2)))
7925 ? t1
7926 : NULL);
7927 }
7928 set_c_expr_source_range (&ret, start, exp2.get_finish ());
7929 ret.m_decimal = 0;
7930 return ret;
7931 }
7932
7933 /* Parse a binary expression; that is, a logical-OR-expression (C90
7934 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not
7935 NULL then it is an Objective-C message expression which is the
7936 primary-expression starting the expression as an initializer.
7937
7938 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
7939 when it should be the unfolded lhs. In a valid OpenMP source,
7940 one of the operands of the toplevel binary expression must be equal
7941 to it. In that case, just return a build2 created binary operation
7942 rather than result of parser_build_binary_op.
7943
7944 multiplicative-expression:
7945 cast-expression
7946 multiplicative-expression * cast-expression
7947 multiplicative-expression / cast-expression
7948 multiplicative-expression % cast-expression
7949
7950 additive-expression:
7951 multiplicative-expression
7952 additive-expression + multiplicative-expression
7953 additive-expression - multiplicative-expression
7954
7955 shift-expression:
7956 additive-expression
7957 shift-expression << additive-expression
7958 shift-expression >> additive-expression
7959
7960 relational-expression:
7961 shift-expression
7962 relational-expression < shift-expression
7963 relational-expression > shift-expression
7964 relational-expression <= shift-expression
7965 relational-expression >= shift-expression
7966
7967 equality-expression:
7968 relational-expression
7969 equality-expression == relational-expression
7970 equality-expression != relational-expression
7971
7972 AND-expression:
7973 equality-expression
7974 AND-expression & equality-expression
7975
7976 exclusive-OR-expression:
7977 AND-expression
7978 exclusive-OR-expression ^ AND-expression
7979
7980 inclusive-OR-expression:
7981 exclusive-OR-expression
7982 inclusive-OR-expression | exclusive-OR-expression
7983
7984 logical-AND-expression:
7985 inclusive-OR-expression
7986 logical-AND-expression && inclusive-OR-expression
7987
7988 logical-OR-expression:
7989 logical-AND-expression
7990 logical-OR-expression || logical-AND-expression
7991 */
7992
7993 static struct c_expr
7994 c_parser_binary_expression (c_parser *parser, struct c_expr *after,
7995 tree omp_atomic_lhs)
7996 {
7997 /* A binary expression is parsed using operator-precedence parsing,
7998 with the operands being cast expressions. All the binary
7999 operators are left-associative. Thus a binary expression is of
8000 form:
8001
8002 E0 op1 E1 op2 E2 ...
8003
8004 which we represent on a stack. On the stack, the precedence
8005 levels are strictly increasing. When a new operator is
8006 encountered of higher precedence than that at the top of the
8007 stack, it is pushed; its LHS is the top expression, and its RHS
8008 is everything parsed until it is popped. When a new operator is
8009 encountered with precedence less than or equal to that at the top
8010 of the stack, triples E[i-1] op[i] E[i] are popped and replaced
8011 by the result of the operation until the operator at the top of
8012 the stack has lower precedence than the new operator or there is
8013 only one element on the stack; then the top expression is the LHS
8014 of the new operator. In the case of logical AND and OR
8015 expressions, we also need to adjust c_inhibit_evaluation_warnings
8016 as appropriate when the operators are pushed and popped. */
8017
8018 struct {
8019 /* The expression at this stack level. */
8020 struct c_expr expr;
8021 /* The precedence of the operator on its left, PREC_NONE at the
8022 bottom of the stack. */
8023 enum c_parser_prec prec;
8024 /* The operation on its left. */
8025 enum tree_code op;
8026 /* The source location of this operation. */
8027 location_t loc;
8028 /* The sizeof argument if expr.original_code == {PAREN_,}SIZEOF_EXPR. */
8029 tree sizeof_arg;
8030 } stack[NUM_PRECS];
8031 int sp;
8032 /* Location of the binary operator. */
8033 location_t binary_loc = UNKNOWN_LOCATION; /* Quiet warning. */
8034 #define POP \
8035 do { \
8036 switch (stack[sp].op) \
8037 { \
8038 case TRUTH_ANDIF_EXPR: \
8039 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
8040 == truthvalue_false_node); \
8041 break; \
8042 case TRUTH_ORIF_EXPR: \
8043 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
8044 == truthvalue_true_node); \
8045 break; \
8046 case TRUNC_DIV_EXPR: \
8047 if ((stack[sp - 1].expr.original_code == SIZEOF_EXPR \
8048 || stack[sp - 1].expr.original_code == PAREN_SIZEOF_EXPR) \
8049 && (stack[sp].expr.original_code == SIZEOF_EXPR \
8050 || stack[sp].expr.original_code == PAREN_SIZEOF_EXPR)) \
8051 { \
8052 tree type0 = stack[sp - 1].sizeof_arg; \
8053 tree type1 = stack[sp].sizeof_arg; \
8054 tree first_arg = type0; \
8055 if (!TYPE_P (type0)) \
8056 type0 = TREE_TYPE (type0); \
8057 if (!TYPE_P (type1)) \
8058 type1 = TREE_TYPE (type1); \
8059 if (POINTER_TYPE_P (type0) \
8060 && comptypes (TREE_TYPE (type0), type1) \
8061 && !(TREE_CODE (first_arg) == PARM_DECL \
8062 && C_ARRAY_PARAMETER (first_arg) \
8063 && warn_sizeof_array_argument)) \
8064 { \
8065 auto_diagnostic_group d; \
8066 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
8067 "division %<sizeof (%T) / sizeof (%T)%> " \
8068 "does not compute the number of array " \
8069 "elements", \
8070 type0, type1)) \
8071 if (DECL_P (first_arg)) \
8072 inform (DECL_SOURCE_LOCATION (first_arg), \
8073 "first %<sizeof%> operand was declared here"); \
8074 } \
8075 else if (TREE_CODE (type0) == ARRAY_TYPE \
8076 && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0))) \
8077 && stack[sp].expr.original_code != PAREN_SIZEOF_EXPR) \
8078 maybe_warn_sizeof_array_div (stack[sp].loc, first_arg, type0, \
8079 stack[sp].sizeof_arg, type1); \
8080 } \
8081 break; \
8082 default: \
8083 break; \
8084 } \
8085 stack[sp - 1].expr \
8086 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \
8087 stack[sp - 1].expr, true, true); \
8088 stack[sp].expr \
8089 = convert_lvalue_to_rvalue (stack[sp].loc, \
8090 stack[sp].expr, true, true); \
8091 if (UNLIKELY (omp_atomic_lhs != NULL_TREE) && sp == 1 \
8092 && ((c_parser_next_token_is (parser, CPP_SEMICOLON) \
8093 && ((1 << stack[sp].prec) \
8094 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) \
8095 | (1 << PREC_BITAND) | (1 << PREC_SHIFT) \
8096 | (1 << PREC_ADD) | (1 << PREC_MULT) \
8097 | (1 << PREC_EQ)))) \
8098 || ((c_parser_next_token_is (parser, CPP_QUERY) \
8099 || (omp_atomic_lhs == void_list_node \
8100 && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))) \
8101 && (stack[sp].prec == PREC_REL || stack[sp].prec == PREC_EQ)))\
8102 && stack[sp].op != TRUNC_MOD_EXPR \
8103 && stack[sp].op != GE_EXPR \
8104 && stack[sp].op != LE_EXPR \
8105 && stack[sp].op != NE_EXPR \
8106 && stack[0].expr.value != error_mark_node \
8107 && stack[1].expr.value != error_mark_node \
8108 && (omp_atomic_lhs == void_list_node \
8109 || c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
8110 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs) \
8111 || (stack[sp].op == EQ_EXPR \
8112 && c_parser_peek_2nd_token (parser)->keyword == RID_IF))) \
8113 { \
8114 tree t = make_node (stack[1].op); \
8115 TREE_TYPE (t) = TREE_TYPE (stack[0].expr.value); \
8116 TREE_OPERAND (t, 0) = stack[0].expr.value; \
8117 TREE_OPERAND (t, 1) = stack[1].expr.value; \
8118 stack[0].expr.value = t; \
8119 stack[0].expr.m_decimal = 0; \
8120 } \
8121 else \
8122 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
8123 stack[sp].op, \
8124 stack[sp - 1].expr, \
8125 stack[sp].expr); \
8126 sp--; \
8127 } while (0)
8128 gcc_assert (!after || c_dialect_objc ());
8129 stack[0].loc = c_parser_peek_token (parser)->location;
8130 stack[0].expr = c_parser_cast_expression (parser, after);
8131 stack[0].prec = PREC_NONE;
8132 stack[0].sizeof_arg = c_last_sizeof_arg;
8133 sp = 0;
8134 while (true)
8135 {
8136 enum c_parser_prec oprec;
8137 enum tree_code ocode;
8138 source_range src_range;
8139 if (parser->error)
8140 goto out;
8141 switch (c_parser_peek_token (parser)->type)
8142 {
8143 case CPP_MULT:
8144 oprec = PREC_MULT;
8145 ocode = MULT_EXPR;
8146 break;
8147 case CPP_DIV:
8148 oprec = PREC_MULT;
8149 ocode = TRUNC_DIV_EXPR;
8150 break;
8151 case CPP_MOD:
8152 oprec = PREC_MULT;
8153 ocode = TRUNC_MOD_EXPR;
8154 break;
8155 case CPP_PLUS:
8156 oprec = PREC_ADD;
8157 ocode = PLUS_EXPR;
8158 break;
8159 case CPP_MINUS:
8160 oprec = PREC_ADD;
8161 ocode = MINUS_EXPR;
8162 break;
8163 case CPP_LSHIFT:
8164 oprec = PREC_SHIFT;
8165 ocode = LSHIFT_EXPR;
8166 break;
8167 case CPP_RSHIFT:
8168 oprec = PREC_SHIFT;
8169 ocode = RSHIFT_EXPR;
8170 break;
8171 case CPP_LESS:
8172 oprec = PREC_REL;
8173 ocode = LT_EXPR;
8174 break;
8175 case CPP_GREATER:
8176 oprec = PREC_REL;
8177 ocode = GT_EXPR;
8178 break;
8179 case CPP_LESS_EQ:
8180 oprec = PREC_REL;
8181 ocode = LE_EXPR;
8182 break;
8183 case CPP_GREATER_EQ:
8184 oprec = PREC_REL;
8185 ocode = GE_EXPR;
8186 break;
8187 case CPP_EQ_EQ:
8188 oprec = PREC_EQ;
8189 ocode = EQ_EXPR;
8190 break;
8191 case CPP_NOT_EQ:
8192 oprec = PREC_EQ;
8193 ocode = NE_EXPR;
8194 break;
8195 case CPP_AND:
8196 oprec = PREC_BITAND;
8197 ocode = BIT_AND_EXPR;
8198 break;
8199 case CPP_XOR:
8200 oprec = PREC_BITXOR;
8201 ocode = BIT_XOR_EXPR;
8202 break;
8203 case CPP_OR:
8204 oprec = PREC_BITOR;
8205 ocode = BIT_IOR_EXPR;
8206 break;
8207 case CPP_AND_AND:
8208 oprec = PREC_LOGAND;
8209 ocode = TRUTH_ANDIF_EXPR;
8210 break;
8211 case CPP_OR_OR:
8212 oprec = PREC_LOGOR;
8213 ocode = TRUTH_ORIF_EXPR;
8214 break;
8215 default:
8216 /* Not a binary operator, so end of the binary
8217 expression. */
8218 goto out;
8219 }
8220 binary_loc = c_parser_peek_token (parser)->location;
8221 while (oprec <= stack[sp].prec)
8222 POP;
8223 c_parser_consume_token (parser);
8224 switch (ocode)
8225 {
8226 case TRUTH_ANDIF_EXPR:
8227 src_range = stack[sp].expr.src_range;
8228 stack[sp].expr
8229 = convert_lvalue_to_rvalue (stack[sp].loc,
8230 stack[sp].expr, true, true);
8231 stack[sp].expr.value = c_objc_common_truthvalue_conversion
8232 (stack[sp].loc, default_conversion (stack[sp].expr.value));
8233 c_inhibit_evaluation_warnings += (stack[sp].expr.value
8234 == truthvalue_false_node);
8235 set_c_expr_source_range (&stack[sp].expr, src_range);
8236 break;
8237 case TRUTH_ORIF_EXPR:
8238 src_range = stack[sp].expr.src_range;
8239 stack[sp].expr
8240 = convert_lvalue_to_rvalue (stack[sp].loc,
8241 stack[sp].expr, true, true);
8242 stack[sp].expr.value = c_objc_common_truthvalue_conversion
8243 (stack[sp].loc, default_conversion (stack[sp].expr.value));
8244 c_inhibit_evaluation_warnings += (stack[sp].expr.value
8245 == truthvalue_true_node);
8246 set_c_expr_source_range (&stack[sp].expr, src_range);
8247 break;
8248 default:
8249 break;
8250 }
8251 sp++;
8252 stack[sp].loc = binary_loc;
8253 stack[sp].expr = c_parser_cast_expression (parser, NULL);
8254 stack[sp].prec = oprec;
8255 stack[sp].op = ocode;
8256 stack[sp].sizeof_arg = c_last_sizeof_arg;
8257 }
8258 out:
8259 while (sp > 0)
8260 POP;
8261 return stack[0].expr;
8262 #undef POP
8263 }
8264
8265 /* Parse any storage class specifiers after an open parenthesis in a
8266 context where a compound literal is permitted. */
8267
8268 static struct c_declspecs *
8269 c_parser_compound_literal_scspecs (c_parser *parser)
8270 {
8271 bool seen_scspec = false;
8272 struct c_declspecs *specs = build_null_declspecs ();
8273 while (c_parser_next_token_is (parser, CPP_KEYWORD))
8274 {
8275 switch (c_parser_peek_token (parser)->keyword)
8276 {
8277 case RID_REGISTER:
8278 case RID_STATIC:
8279 case RID_THREAD:
8280 seen_scspec = true;
8281 declspecs_add_scspec (c_parser_peek_token (parser)->location,
8282 specs, c_parser_peek_token (parser)->value);
8283 c_parser_consume_token (parser);
8284 break;
8285 default:
8286 goto out;
8287 }
8288 }
8289 out:
8290 return seen_scspec ? specs : NULL;
8291 }
8292
8293 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER
8294 is not NULL then it is an Objective-C message expression which is the
8295 primary-expression starting the expression as an initializer.
8296
8297 cast-expression:
8298 unary-expression
8299 ( type-name ) unary-expression
8300 */
8301
8302 static struct c_expr
8303 c_parser_cast_expression (c_parser *parser, struct c_expr *after)
8304 {
8305 location_t cast_loc = c_parser_peek_token (parser)->location;
8306 gcc_assert (!after || c_dialect_objc ());
8307 if (after)
8308 return c_parser_postfix_expression_after_primary (parser,
8309 cast_loc, *after);
8310 /* If the expression begins with a parenthesized type name, it may
8311 be either a cast or a compound literal; we need to see whether
8312 the next character is '{' to tell the difference. If not, it is
8313 an unary expression. Full detection of unknown typenames here
8314 would require a 3-token lookahead. */
8315 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8316 && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser)))
8317 {
8318 struct c_declspecs *scspecs;
8319 struct c_type_name *type_name;
8320 struct c_expr ret;
8321 struct c_expr expr;
8322 matching_parens parens;
8323 parens.consume_open (parser);
8324 scspecs = c_parser_compound_literal_scspecs (parser);
8325 type_name = c_parser_type_name (parser, true);
8326 parens.skip_until_found_close (parser);
8327 if (type_name == NULL)
8328 {
8329 ret.set_error ();
8330 ret.original_code = ERROR_MARK;
8331 ret.original_type = NULL;
8332 return ret;
8333 }
8334
8335 /* Save casted types in the function's used types hash table. */
8336 used_types_insert (type_name->specs->type);
8337
8338 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8339 return c_parser_postfix_expression_after_paren_type (parser, scspecs,
8340 type_name,
8341 cast_loc);
8342 if (scspecs)
8343 error_at (cast_loc, "storage class specifier in cast");
8344 if (type_name->specs->alignas_p)
8345 error_at (type_name->specs->locations[cdw_alignas],
8346 "alignment specified for type name in cast");
8347 {
8348 location_t expr_loc = c_parser_peek_token (parser)->location;
8349 expr = c_parser_cast_expression (parser, NULL);
8350 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
8351 }
8352 ret.value = c_cast_expr (cast_loc, type_name, expr.value);
8353 if (ret.value && expr.value)
8354 set_c_expr_source_range (&ret, cast_loc, expr.get_finish ());
8355 ret.original_code = ERROR_MARK;
8356 ret.original_type = NULL;
8357 ret.m_decimal = 0;
8358 return ret;
8359 }
8360 else
8361 return c_parser_unary_expression (parser);
8362 }
8363
8364 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
8365
8366 unary-expression:
8367 postfix-expression
8368 ++ unary-expression
8369 -- unary-expression
8370 unary-operator cast-expression
8371 sizeof unary-expression
8372 sizeof ( type-name )
8373
8374 unary-operator: one of
8375 & * + - ~ !
8376
8377 GNU extensions:
8378
8379 unary-expression:
8380 __alignof__ unary-expression
8381 __alignof__ ( type-name )
8382 && identifier
8383
8384 (C11 permits _Alignof with type names only.)
8385
8386 unary-operator: one of
8387 __extension__ __real__ __imag__
8388
8389 Transactional Memory:
8390
8391 unary-expression:
8392 transaction-expression
8393
8394 In addition, the GNU syntax treats ++ and -- as unary operators, so
8395 they may be applied to cast expressions with errors for non-lvalues
8396 given later. */
8397
8398 static struct c_expr
8399 c_parser_unary_expression (c_parser *parser)
8400 {
8401 int ext;
8402 struct c_expr ret, op;
8403 location_t op_loc = c_parser_peek_token (parser)->location;
8404 location_t exp_loc;
8405 location_t finish;
8406 ret.original_code = ERROR_MARK;
8407 ret.original_type = NULL;
8408 switch (c_parser_peek_token (parser)->type)
8409 {
8410 case CPP_PLUS_PLUS:
8411 c_parser_consume_token (parser);
8412 exp_loc = c_parser_peek_token (parser)->location;
8413 op = c_parser_cast_expression (parser, NULL);
8414
8415 op = default_function_array_read_conversion (exp_loc, op);
8416 return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
8417 case CPP_MINUS_MINUS:
8418 c_parser_consume_token (parser);
8419 exp_loc = c_parser_peek_token (parser)->location;
8420 op = c_parser_cast_expression (parser, NULL);
8421
8422 op = default_function_array_read_conversion (exp_loc, op);
8423 return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
8424 case CPP_AND:
8425 c_parser_consume_token (parser);
8426 op = c_parser_cast_expression (parser, NULL);
8427 mark_exp_read (op.value);
8428 return parser_build_unary_op (op_loc, ADDR_EXPR, op);
8429 case CPP_MULT:
8430 {
8431 c_parser_consume_token (parser);
8432 exp_loc = c_parser_peek_token (parser)->location;
8433 op = c_parser_cast_expression (parser, NULL);
8434 finish = op.get_finish ();
8435 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8436 location_t combined_loc = make_location (op_loc, op_loc, finish);
8437 ret.value = build_indirect_ref (combined_loc, op.value, RO_UNARY_STAR);
8438 ret.src_range.m_start = op_loc;
8439 ret.src_range.m_finish = finish;
8440 ret.m_decimal = 0;
8441 return ret;
8442 }
8443 case CPP_PLUS:
8444 if (!c_dialect_objc () && !in_system_header_at (input_location))
8445 warning_at (op_loc,
8446 OPT_Wtraditional,
8447 "traditional C rejects the unary plus operator");
8448 c_parser_consume_token (parser);
8449 exp_loc = c_parser_peek_token (parser)->location;
8450 op = c_parser_cast_expression (parser, NULL);
8451 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8452 return parser_build_unary_op (op_loc, CONVERT_EXPR, op);
8453 case CPP_MINUS:
8454 c_parser_consume_token (parser);
8455 exp_loc = c_parser_peek_token (parser)->location;
8456 op = c_parser_cast_expression (parser, NULL);
8457 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8458 return parser_build_unary_op (op_loc, NEGATE_EXPR, op);
8459 case CPP_COMPL:
8460 c_parser_consume_token (parser);
8461 exp_loc = c_parser_peek_token (parser)->location;
8462 op = c_parser_cast_expression (parser, NULL);
8463 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8464 return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
8465 case CPP_NOT:
8466 c_parser_consume_token (parser);
8467 exp_loc = c_parser_peek_token (parser)->location;
8468 op = c_parser_cast_expression (parser, NULL);
8469 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8470 return parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op);
8471 case CPP_AND_AND:
8472 /* Refer to the address of a label as a pointer. */
8473 c_parser_consume_token (parser);
8474 if (c_parser_next_token_is (parser, CPP_NAME))
8475 {
8476 ret.value = finish_label_address_expr
8477 (c_parser_peek_token (parser)->value, op_loc);
8478 set_c_expr_source_range (&ret, op_loc,
8479 c_parser_peek_token (parser)->get_finish ());
8480 c_parser_consume_token (parser);
8481 }
8482 else
8483 {
8484 c_parser_error (parser, "expected identifier");
8485 ret.set_error ();
8486 }
8487 return ret;
8488 case CPP_KEYWORD:
8489 switch (c_parser_peek_token (parser)->keyword)
8490 {
8491 case RID_SIZEOF:
8492 return c_parser_sizeof_expression (parser);
8493 case RID_ALIGNOF:
8494 return c_parser_alignof_expression (parser);
8495 case RID_BUILTIN_HAS_ATTRIBUTE:
8496 return c_parser_has_attribute_expression (parser);
8497 case RID_EXTENSION:
8498 c_parser_consume_token (parser);
8499 ext = disable_extension_diagnostics ();
8500 ret = c_parser_cast_expression (parser, NULL);
8501 restore_extension_diagnostics (ext);
8502 return ret;
8503 case RID_REALPART:
8504 c_parser_consume_token (parser);
8505 exp_loc = c_parser_peek_token (parser)->location;
8506 op = c_parser_cast_expression (parser, NULL);
8507 op = default_function_array_conversion (exp_loc, op);
8508 return parser_build_unary_op (op_loc, REALPART_EXPR, op);
8509 case RID_IMAGPART:
8510 c_parser_consume_token (parser);
8511 exp_loc = c_parser_peek_token (parser)->location;
8512 op = c_parser_cast_expression (parser, NULL);
8513 op = default_function_array_conversion (exp_loc, op);
8514 return parser_build_unary_op (op_loc, IMAGPART_EXPR, op);
8515 case RID_TRANSACTION_ATOMIC:
8516 case RID_TRANSACTION_RELAXED:
8517 return c_parser_transaction_expression (parser,
8518 c_parser_peek_token (parser)->keyword);
8519 default:
8520 return c_parser_postfix_expression (parser);
8521 }
8522 default:
8523 return c_parser_postfix_expression (parser);
8524 }
8525 }
8526
8527 /* Parse a sizeof expression. */
8528
8529 static struct c_expr
8530 c_parser_sizeof_expression (c_parser *parser)
8531 {
8532 struct c_expr expr;
8533 struct c_expr result;
8534 location_t expr_loc;
8535 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF));
8536
8537 location_t start;
8538 location_t finish = UNKNOWN_LOCATION;
8539
8540 start = c_parser_peek_token (parser)->location;
8541
8542 c_parser_consume_token (parser);
8543 c_inhibit_evaluation_warnings++;
8544 in_sizeof++;
8545 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8546 && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser)))
8547 {
8548 /* Either sizeof ( type-name ) or sizeof unary-expression
8549 starting with a compound literal. */
8550 struct c_declspecs *scspecs;
8551 struct c_type_name *type_name;
8552 matching_parens parens;
8553 parens.consume_open (parser);
8554 expr_loc = c_parser_peek_token (parser)->location;
8555 scspecs = c_parser_compound_literal_scspecs (parser);
8556 type_name = c_parser_type_name (parser, true);
8557 parens.skip_until_found_close (parser);
8558 finish = parser->tokens_buf[0].location;
8559 if (type_name == NULL)
8560 {
8561 struct c_expr ret;
8562 c_inhibit_evaluation_warnings--;
8563 in_sizeof--;
8564 ret.set_error ();
8565 ret.original_code = ERROR_MARK;
8566 ret.original_type = NULL;
8567 return ret;
8568 }
8569 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8570 {
8571 expr = c_parser_postfix_expression_after_paren_type (parser, scspecs,
8572 type_name,
8573 expr_loc);
8574 finish = expr.get_finish ();
8575 goto sizeof_expr;
8576 }
8577 /* sizeof ( type-name ). */
8578 if (scspecs)
8579 error_at (expr_loc, "storage class specifier in %<sizeof%>");
8580 if (type_name->specs->alignas_p)
8581 error_at (type_name->specs->locations[cdw_alignas],
8582 "alignment specified for type name in %<sizeof%>");
8583 c_inhibit_evaluation_warnings--;
8584 in_sizeof--;
8585 result = c_expr_sizeof_type (expr_loc, type_name);
8586 }
8587 else
8588 {
8589 expr_loc = c_parser_peek_token (parser)->location;
8590 expr = c_parser_unary_expression (parser);
8591 finish = expr.get_finish ();
8592 sizeof_expr:
8593 c_inhibit_evaluation_warnings--;
8594 in_sizeof--;
8595 mark_exp_read (expr.value);
8596 if (TREE_CODE (expr.value) == COMPONENT_REF
8597 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
8598 error_at (expr_loc, "%<sizeof%> applied to a bit-field");
8599 result = c_expr_sizeof_expr (expr_loc, expr);
8600 }
8601 if (finish == UNKNOWN_LOCATION)
8602 finish = start;
8603 set_c_expr_source_range (&result, start, finish);
8604 return result;
8605 }
8606
8607 /* Parse an alignof expression. */
8608
8609 static struct c_expr
8610 c_parser_alignof_expression (c_parser *parser)
8611 {
8612 struct c_expr expr;
8613 location_t start_loc = c_parser_peek_token (parser)->location;
8614 location_t end_loc;
8615 tree alignof_spelling = c_parser_peek_token (parser)->value;
8616 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF));
8617 bool is_c11_alignof = (strcmp (IDENTIFIER_POINTER (alignof_spelling),
8618 "_Alignof") == 0
8619 || strcmp (IDENTIFIER_POINTER (alignof_spelling),
8620 "alignof") == 0);
8621 /* A diagnostic is not required for the use of this identifier in
8622 the implementation namespace; only diagnose it for the C11 or C2X
8623 spelling because of existing code using the other spellings. */
8624 if (is_c11_alignof)
8625 {
8626 if (flag_isoc99)
8627 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C99 does not support %qE",
8628 alignof_spelling);
8629 else
8630 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C90 does not support %qE",
8631 alignof_spelling);
8632 }
8633 c_parser_consume_token (parser);
8634 c_inhibit_evaluation_warnings++;
8635 in_alignof++;
8636 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8637 && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser)))
8638 {
8639 /* Either __alignof__ ( type-name ) or __alignof__
8640 unary-expression starting with a compound literal. */
8641 location_t loc;
8642 struct c_declspecs *scspecs;
8643 struct c_type_name *type_name;
8644 struct c_expr ret;
8645 matching_parens parens;
8646 parens.consume_open (parser);
8647 loc = c_parser_peek_token (parser)->location;
8648 scspecs = c_parser_compound_literal_scspecs (parser);
8649 type_name = c_parser_type_name (parser, true);
8650 end_loc = c_parser_peek_token (parser)->location;
8651 parens.skip_until_found_close (parser);
8652 if (type_name == NULL)
8653 {
8654 struct c_expr ret;
8655 c_inhibit_evaluation_warnings--;
8656 in_alignof--;
8657 ret.set_error ();
8658 ret.original_code = ERROR_MARK;
8659 ret.original_type = NULL;
8660 return ret;
8661 }
8662 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8663 {
8664 expr = c_parser_postfix_expression_after_paren_type (parser, scspecs,
8665 type_name,
8666 loc);
8667 goto alignof_expr;
8668 }
8669 /* alignof ( type-name ). */
8670 if (scspecs)
8671 error_at (loc, "storage class specifier in %qE", alignof_spelling);
8672 if (type_name->specs->alignas_p)
8673 error_at (type_name->specs->locations[cdw_alignas],
8674 "alignment specified for type name in %qE",
8675 alignof_spelling);
8676 c_inhibit_evaluation_warnings--;
8677 in_alignof--;
8678 ret.value = c_sizeof_or_alignof_type (loc, groktypename (type_name,
8679 NULL, NULL),
8680 false, is_c11_alignof, 1);
8681 ret.original_code = ERROR_MARK;
8682 ret.original_type = NULL;
8683 set_c_expr_source_range (&ret, start_loc, end_loc);
8684 ret.m_decimal = 0;
8685 return ret;
8686 }
8687 else
8688 {
8689 struct c_expr ret;
8690 expr = c_parser_unary_expression (parser);
8691 end_loc = expr.src_range.m_finish;
8692 alignof_expr:
8693 mark_exp_read (expr.value);
8694 c_inhibit_evaluation_warnings--;
8695 in_alignof--;
8696 if (is_c11_alignof)
8697 pedwarn (start_loc,
8698 OPT_Wpedantic, "ISO C does not allow %<%E (expression)%>",
8699 alignof_spelling);
8700 ret.value = c_alignof_expr (start_loc, expr.value);
8701 ret.original_code = ERROR_MARK;
8702 ret.original_type = NULL;
8703 set_c_expr_source_range (&ret, start_loc, end_loc);
8704 ret.m_decimal = 0;
8705 return ret;
8706 }
8707 }
8708
8709 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
8710 expression. */
8711
8712 static struct c_expr
8713 c_parser_has_attribute_expression (c_parser *parser)
8714 {
8715 gcc_assert (c_parser_next_token_is_keyword (parser,
8716 RID_BUILTIN_HAS_ATTRIBUTE));
8717 location_t start = c_parser_peek_token (parser)->location;
8718 c_parser_consume_token (parser);
8719
8720 c_inhibit_evaluation_warnings++;
8721
8722 matching_parens parens;
8723 if (!parens.require_open (parser))
8724 {
8725 c_inhibit_evaluation_warnings--;
8726 in_typeof--;
8727
8728 struct c_expr result;
8729 result.set_error ();
8730 result.original_code = ERROR_MARK;
8731 result.original_type = NULL;
8732 return result;
8733 }
8734
8735 /* Treat the type argument the same way as in typeof for the purposes
8736 of warnings. FIXME: Generalize this so the warning refers to
8737 __builtin_has_attribute rather than typeof. */
8738 in_typeof++;
8739
8740 /* The first operand: one of DECL, EXPR, or TYPE. */
8741 tree oper = NULL_TREE;
8742 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
8743 {
8744 struct c_type_name *tname = c_parser_type_name (parser);
8745 in_typeof--;
8746 if (tname)
8747 {
8748 oper = groktypename (tname, NULL, NULL);
8749 pop_maybe_used (variably_modified_type_p (oper, NULL_TREE));
8750 }
8751 }
8752 else
8753 {
8754 struct c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
8755 c_inhibit_evaluation_warnings--;
8756 in_typeof--;
8757 if (cexpr.value != error_mark_node)
8758 {
8759 mark_exp_read (cexpr.value);
8760 oper = cexpr.value;
8761 tree etype = TREE_TYPE (oper);
8762 bool was_vm = variably_modified_type_p (etype, NULL_TREE);
8763 /* This is returned with the type so that when the type is
8764 evaluated, this can be evaluated. */
8765 if (was_vm)
8766 oper = c_fully_fold (oper, false, NULL);
8767 pop_maybe_used (was_vm);
8768 }
8769 }
8770
8771 struct c_expr result;
8772 result.original_code = ERROR_MARK;
8773 result.original_type = NULL;
8774
8775 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8776 {
8777 /* Consume the closing parenthesis if that's the next token
8778 in the likely case the built-in was invoked with fewer
8779 than two arguments. */
8780 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8781 c_parser_consume_token (parser);
8782 c_inhibit_evaluation_warnings--;
8783 result.set_error ();
8784 return result;
8785 }
8786
8787 bool save_translate_strings_p = parser->translate_strings_p;
8788
8789 location_t atloc = c_parser_peek_token (parser)->location;
8790 /* Parse a single attribute. Require no leading comma and do not
8791 allow empty attributes. */
8792 tree attr = c_parser_gnu_attribute (parser, NULL_TREE, false, false);
8793
8794 parser->translate_strings_p = save_translate_strings_p;
8795
8796 location_t finish = c_parser_peek_token (parser)->location;
8797 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8798 c_parser_consume_token (parser);
8799 else
8800 {
8801 c_parser_error (parser, "expected identifier");
8802 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8803
8804 result.set_error ();
8805 return result;
8806 }
8807
8808 if (!attr)
8809 {
8810 error_at (atloc, "expected identifier");
8811 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
8812 "expected %<)%>");
8813 result.set_error ();
8814 return result;
8815 }
8816
8817 result.original_code = INTEGER_CST;
8818 result.original_type = boolean_type_node;
8819
8820 if (has_attribute (atloc, oper, attr, default_conversion))
8821 result.value = boolean_true_node;
8822 else
8823 result.value = boolean_false_node;
8824
8825 set_c_expr_source_range (&result, start, finish);
8826 result.m_decimal = 0;
8827 return result;
8828 }
8829
8830 /* Helper function to read arguments of builtins which are interfaces
8831 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
8832 others. The name of the builtin is passed using BNAME parameter.
8833 Function returns true if there were no errors while parsing and
8834 stores the arguments in CEXPR_LIST. If it returns true,
8835 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
8836 parenthesis. */
8837 static bool
8838 c_parser_get_builtin_args (c_parser *parser, const char *bname,
8839 vec<c_expr_t, va_gc> **ret_cexpr_list,
8840 bool choose_expr_p,
8841 location_t *out_close_paren_loc)
8842 {
8843 location_t loc = c_parser_peek_token (parser)->location;
8844 vec<c_expr_t, va_gc> *cexpr_list;
8845 c_expr_t expr;
8846 bool saved_force_folding_builtin_constant_p;
8847
8848 *ret_cexpr_list = NULL;
8849 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
8850 {
8851 error_at (loc, "cannot take address of %qs", bname);
8852 return false;
8853 }
8854
8855 c_parser_consume_token (parser);
8856
8857 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8858 {
8859 *out_close_paren_loc = c_parser_peek_token (parser)->location;
8860 c_parser_consume_token (parser);
8861 return true;
8862 }
8863
8864 saved_force_folding_builtin_constant_p
8865 = force_folding_builtin_constant_p;
8866 force_folding_builtin_constant_p |= choose_expr_p;
8867 expr = c_parser_expr_no_commas (parser, NULL);
8868 force_folding_builtin_constant_p
8869 = saved_force_folding_builtin_constant_p;
8870 vec_alloc (cexpr_list, 1);
8871 vec_safe_push (cexpr_list, expr);
8872 while (c_parser_next_token_is (parser, CPP_COMMA))
8873 {
8874 c_parser_consume_token (parser);
8875 expr = c_parser_expr_no_commas (parser, NULL);
8876 vec_safe_push (cexpr_list, expr);
8877 }
8878
8879 *out_close_paren_loc = c_parser_peek_token (parser)->location;
8880 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
8881 return false;
8882
8883 *ret_cexpr_list = cexpr_list;
8884 return true;
8885 }
8886
8887 /* This represents a single generic-association. */
8888
8889 struct c_generic_association
8890 {
8891 /* The location of the starting token of the type. */
8892 location_t type_location;
8893 /* The association's type, or NULL_TREE for 'default'. */
8894 tree type;
8895 /* The association's expression. */
8896 struct c_expr expression;
8897 };
8898
8899 /* Parse a generic-selection. (C11 6.5.1.1).
8900
8901 generic-selection:
8902 _Generic ( assignment-expression , generic-assoc-list )
8903
8904 generic-assoc-list:
8905 generic-association
8906 generic-assoc-list , generic-association
8907
8908 generic-association:
8909 type-name : assignment-expression
8910 default : assignment-expression
8911 */
8912
8913 static struct c_expr
8914 c_parser_generic_selection (c_parser *parser)
8915 {
8916 struct c_expr selector, error_expr;
8917 tree selector_type;
8918 struct c_generic_association matched_assoc;
8919 int match_found = -1;
8920 location_t generic_loc, selector_loc;
8921
8922 error_expr.original_code = ERROR_MARK;
8923 error_expr.original_type = NULL;
8924 error_expr.set_error ();
8925 matched_assoc.type_location = UNKNOWN_LOCATION;
8926 matched_assoc.type = NULL_TREE;
8927 matched_assoc.expression = error_expr;
8928
8929 gcc_assert (c_parser_next_token_is_keyword (parser, RID_GENERIC));
8930 generic_loc = c_parser_peek_token (parser)->location;
8931 c_parser_consume_token (parser);
8932 if (flag_isoc99)
8933 pedwarn_c99 (generic_loc, OPT_Wpedantic,
8934 "ISO C99 does not support %<_Generic%>");
8935 else
8936 pedwarn_c99 (generic_loc, OPT_Wpedantic,
8937 "ISO C90 does not support %<_Generic%>");
8938
8939 matching_parens parens;
8940 if (!parens.require_open (parser))
8941 return error_expr;
8942
8943 c_inhibit_evaluation_warnings++;
8944 selector_loc = c_parser_peek_token (parser)->location;
8945 selector = c_parser_expr_no_commas (parser, NULL);
8946 selector = default_function_array_conversion (selector_loc, selector);
8947 c_inhibit_evaluation_warnings--;
8948
8949 if (selector.value == error_mark_node)
8950 {
8951 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8952 return selector;
8953 }
8954 mark_exp_read (selector.value);
8955 selector_type = TREE_TYPE (selector.value);
8956 /* In ISO C terms, rvalues (including the controlling expression of
8957 _Generic) do not have qualified types. */
8958 if (TREE_CODE (selector_type) != ARRAY_TYPE)
8959 selector_type = TYPE_MAIN_VARIANT (selector_type);
8960 /* In ISO C terms, _Noreturn is not part of the type of expressions
8961 such as &abort, but in GCC it is represented internally as a type
8962 qualifier. */
8963 if (FUNCTION_POINTER_TYPE_P (selector_type)
8964 && TYPE_QUALS (TREE_TYPE (selector_type)) != TYPE_UNQUALIFIED)
8965 selector_type
8966 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type)));
8967
8968 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8969 {
8970 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8971 return error_expr;
8972 }
8973
8974 auto_vec<c_generic_association> associations;
8975 while (1)
8976 {
8977 struct c_generic_association assoc, *iter;
8978 unsigned int ix;
8979 c_token *token = c_parser_peek_token (parser);
8980
8981 assoc.type_location = token->location;
8982 if (token->type == CPP_KEYWORD && token->keyword == RID_DEFAULT)
8983 {
8984 c_parser_consume_token (parser);
8985 assoc.type = NULL_TREE;
8986 }
8987 else
8988 {
8989 struct c_type_name *type_name;
8990
8991 type_name = c_parser_type_name (parser);
8992 if (type_name == NULL)
8993 {
8994 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8995 return error_expr;
8996 }
8997 assoc.type = groktypename (type_name, NULL, NULL);
8998 if (assoc.type == error_mark_node)
8999 {
9000 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9001 return error_expr;
9002 }
9003
9004 if (TREE_CODE (assoc.type) == FUNCTION_TYPE)
9005 error_at (assoc.type_location,
9006 "%<_Generic%> association has function type");
9007 else if (!COMPLETE_TYPE_P (assoc.type))
9008 error_at (assoc.type_location,
9009 "%<_Generic%> association has incomplete type");
9010
9011 if (variably_modified_type_p (assoc.type, NULL_TREE))
9012 error_at (assoc.type_location,
9013 "%<_Generic%> association has "
9014 "variable length type");
9015 }
9016
9017 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
9018 {
9019 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9020 return error_expr;
9021 }
9022
9023 assoc.expression = c_parser_expr_no_commas (parser, NULL);
9024 if (assoc.expression.value == error_mark_node)
9025 {
9026 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9027 return error_expr;
9028 }
9029
9030 for (ix = 0; associations.iterate (ix, &iter); ++ix)
9031 {
9032 if (assoc.type == NULL_TREE)
9033 {
9034 if (iter->type == NULL_TREE)
9035 {
9036 error_at (assoc.type_location,
9037 "duplicate %<default%> case in %<_Generic%>");
9038 inform (iter->type_location, "original %<default%> is here");
9039 }
9040 }
9041 else if (iter->type != NULL_TREE)
9042 {
9043 if (comptypes (assoc.type, iter->type))
9044 {
9045 error_at (assoc.type_location,
9046 "%<_Generic%> specifies two compatible types");
9047 inform (iter->type_location, "compatible type is here");
9048 }
9049 }
9050 }
9051
9052 if (assoc.type == NULL_TREE)
9053 {
9054 if (match_found < 0)
9055 {
9056 matched_assoc = assoc;
9057 match_found = associations.length ();
9058 }
9059 }
9060 else if (comptypes (assoc.type, selector_type))
9061 {
9062 if (match_found < 0 || matched_assoc.type == NULL_TREE)
9063 {
9064 matched_assoc = assoc;
9065 match_found = associations.length ();
9066 }
9067 else
9068 {
9069 error_at (assoc.type_location,
9070 "%<_Generic%> selector matches multiple associations");
9071 inform (matched_assoc.type_location,
9072 "other match is here");
9073 }
9074 }
9075
9076 associations.safe_push (assoc);
9077
9078 if (c_parser_peek_token (parser)->type != CPP_COMMA)
9079 break;
9080 c_parser_consume_token (parser);
9081 }
9082
9083 unsigned int ix;
9084 struct c_generic_association *iter;
9085 FOR_EACH_VEC_ELT (associations, ix, iter)
9086 if (ix != (unsigned) match_found)
9087 mark_exp_read (iter->expression.value);
9088
9089 if (!parens.require_close (parser))
9090 {
9091 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9092 return error_expr;
9093 }
9094
9095 if (match_found < 0)
9096 {
9097 error_at (selector_loc, "%<_Generic%> selector of type %qT is not "
9098 "compatible with any association",
9099 selector_type);
9100 return error_expr;
9101 }
9102
9103 return matched_assoc.expression;
9104 }
9105
9106 /* Check the validity of a function pointer argument *EXPR (argument
9107 position POS) to __builtin_tgmath. Return the number of function
9108 arguments if possibly valid; return 0 having reported an error if
9109 not valid. */
9110
9111 static unsigned int
9112 check_tgmath_function (c_expr *expr, unsigned int pos)
9113 {
9114 tree type = TREE_TYPE (expr->value);
9115 if (!FUNCTION_POINTER_TYPE_P (type))
9116 {
9117 error_at (expr->get_location (),
9118 "argument %u of %<__builtin_tgmath%> is not a function pointer",
9119 pos);
9120 return 0;
9121 }
9122 type = TREE_TYPE (type);
9123 if (!prototype_p (type))
9124 {
9125 error_at (expr->get_location (),
9126 "argument %u of %<__builtin_tgmath%> is unprototyped", pos);
9127 return 0;
9128 }
9129 if (stdarg_p (type))
9130 {
9131 error_at (expr->get_location (),
9132 "argument %u of %<__builtin_tgmath%> has variable arguments",
9133 pos);
9134 return 0;
9135 }
9136 unsigned int nargs = 0;
9137 function_args_iterator iter;
9138 tree t;
9139 FOREACH_FUNCTION_ARGS (type, t, iter)
9140 {
9141 if (t == void_type_node)
9142 break;
9143 nargs++;
9144 }
9145 if (nargs == 0)
9146 {
9147 error_at (expr->get_location (),
9148 "argument %u of %<__builtin_tgmath%> has no arguments", pos);
9149 return 0;
9150 }
9151 return nargs;
9152 }
9153
9154 /* Ways in which a parameter or return value of a type-generic macro
9155 may vary between the different functions the macro may call. */
9156 enum tgmath_parm_kind
9157 {
9158 tgmath_fixed, tgmath_real, tgmath_complex
9159 };
9160
9161 /* Helper function for c_parser_postfix_expression. Parse predefined
9162 identifiers. */
9163
9164 static struct c_expr
9165 c_parser_predefined_identifier (c_parser *parser)
9166 {
9167 location_t loc = c_parser_peek_token (parser)->location;
9168 switch (c_parser_peek_token (parser)->keyword)
9169 {
9170 case RID_FUNCTION_NAME:
9171 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
9172 "identifier", "__FUNCTION__");
9173 break;
9174 case RID_PRETTY_FUNCTION_NAME:
9175 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
9176 "identifier", "__PRETTY_FUNCTION__");
9177 break;
9178 case RID_C99_FUNCTION_NAME:
9179 pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not support "
9180 "%<__func__%> predefined identifier");
9181 break;
9182 default:
9183 gcc_unreachable ();
9184 }
9185
9186 struct c_expr expr;
9187 expr.original_code = ERROR_MARK;
9188 expr.original_type = NULL;
9189 expr.value = fname_decl (loc, c_parser_peek_token (parser)->keyword,
9190 c_parser_peek_token (parser)->value);
9191 set_c_expr_source_range (&expr, loc, loc);
9192 expr.m_decimal = 0;
9193 c_parser_consume_token (parser);
9194 return expr;
9195 }
9196
9197 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
9198 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to
9199 call c_parser_postfix_expression_after_paren_type on encountering them.
9200
9201 postfix-expression:
9202 primary-expression
9203 postfix-expression [ expression ]
9204 postfix-expression ( argument-expression-list[opt] )
9205 postfix-expression . identifier
9206 postfix-expression -> identifier
9207 postfix-expression ++
9208 postfix-expression --
9209 ( storage-class-specifiers[opt] type-name ) { initializer-list[opt] }
9210 ( storage-class-specifiers[opt] type-name ) { initializer-list , }
9211
9212 argument-expression-list:
9213 argument-expression
9214 argument-expression-list , argument-expression
9215
9216 primary-expression:
9217 identifier
9218 constant
9219 string-literal
9220 ( expression )
9221 generic-selection
9222
9223 GNU extensions:
9224
9225 primary-expression:
9226 __func__
9227 (treated as a keyword in GNU C)
9228 __FUNCTION__
9229 __PRETTY_FUNCTION__
9230 ( compound-statement )
9231 __builtin_va_arg ( assignment-expression , type-name )
9232 __builtin_offsetof ( type-name , offsetof-member-designator )
9233 __builtin_choose_expr ( assignment-expression ,
9234 assignment-expression ,
9235 assignment-expression )
9236 __builtin_types_compatible_p ( type-name , type-name )
9237 __builtin_tgmath ( expr-list )
9238 __builtin_complex ( assignment-expression , assignment-expression )
9239 __builtin_shuffle ( assignment-expression , assignment-expression )
9240 __builtin_shuffle ( assignment-expression ,
9241 assignment-expression ,
9242 assignment-expression, )
9243 __builtin_convertvector ( assignment-expression , type-name )
9244 __builtin_assoc_barrier ( assignment-expression )
9245
9246 offsetof-member-designator:
9247 identifier
9248 offsetof-member-designator . identifier
9249 offsetof-member-designator [ expression ]
9250
9251 Objective-C:
9252
9253 primary-expression:
9254 [ objc-receiver objc-message-args ]
9255 @selector ( objc-selector-arg )
9256 @protocol ( identifier )
9257 @encode ( type-name )
9258 objc-string-literal
9259 Classname . identifier
9260 */
9261
9262 static struct c_expr
9263 c_parser_postfix_expression (c_parser *parser)
9264 {
9265 struct c_expr expr, e1;
9266 struct c_type_name *t1, *t2;
9267 location_t loc = c_parser_peek_token (parser)->location;
9268 source_range tok_range = c_parser_peek_token (parser)->get_range ();
9269 expr.original_code = ERROR_MARK;
9270 expr.original_type = NULL;
9271 expr.m_decimal = 0;
9272 switch (c_parser_peek_token (parser)->type)
9273 {
9274 case CPP_NUMBER:
9275 expr.value = c_parser_peek_token (parser)->value;
9276 set_c_expr_source_range (&expr, tok_range);
9277 loc = c_parser_peek_token (parser)->location;
9278 expr.m_decimal = c_parser_peek_token (parser)->flags & DECIMAL_INT;
9279 c_parser_consume_token (parser);
9280 if (TREE_CODE (expr.value) == FIXED_CST
9281 && !targetm.fixed_point_supported_p ())
9282 {
9283 error_at (loc, "fixed-point types not supported for this target");
9284 expr.set_error ();
9285 }
9286 break;
9287 case CPP_CHAR:
9288 case CPP_CHAR16:
9289 case CPP_CHAR32:
9290 case CPP_UTF8CHAR:
9291 case CPP_WCHAR:
9292 expr.value = c_parser_peek_token (parser)->value;
9293 /* For the purpose of warning when a pointer is compared with
9294 a zero character constant. */
9295 expr.original_type = char_type_node;
9296 set_c_expr_source_range (&expr, tok_range);
9297 c_parser_consume_token (parser);
9298 break;
9299 case CPP_STRING:
9300 case CPP_STRING16:
9301 case CPP_STRING32:
9302 case CPP_WSTRING:
9303 case CPP_UTF8STRING:
9304 expr = c_parser_string_literal (parser, parser->translate_strings_p,
9305 true);
9306 break;
9307 case CPP_OBJC_STRING:
9308 gcc_assert (c_dialect_objc ());
9309 expr.value
9310 = objc_build_string_object (c_parser_peek_token (parser)->value);
9311 set_c_expr_source_range (&expr, tok_range);
9312 c_parser_consume_token (parser);
9313 break;
9314 case CPP_NAME:
9315 switch (c_parser_peek_token (parser)->id_kind)
9316 {
9317 case C_ID_ID:
9318 {
9319 tree id = c_parser_peek_token (parser)->value;
9320 c_parser_consume_token (parser);
9321 expr.value = build_external_ref (loc, id,
9322 (c_parser_peek_token (parser)->type
9323 == CPP_OPEN_PAREN),
9324 &expr.original_type);
9325 set_c_expr_source_range (&expr, tok_range);
9326 break;
9327 }
9328 case C_ID_CLASSNAME:
9329 {
9330 /* Here we parse the Objective-C 2.0 Class.name dot
9331 syntax. */
9332 tree class_name = c_parser_peek_token (parser)->value;
9333 tree component;
9334 c_parser_consume_token (parser);
9335 gcc_assert (c_dialect_objc ());
9336 if (!c_parser_require (parser, CPP_DOT, "expected %<.%>"))
9337 {
9338 expr.set_error ();
9339 break;
9340 }
9341 if (c_parser_next_token_is_not (parser, CPP_NAME))
9342 {
9343 c_parser_error (parser, "expected identifier");
9344 expr.set_error ();
9345 break;
9346 }
9347 c_token *component_tok = c_parser_peek_token (parser);
9348 component = component_tok->value;
9349 location_t end_loc = component_tok->get_finish ();
9350 c_parser_consume_token (parser);
9351 expr.value = objc_build_class_component_ref (class_name,
9352 component);
9353 set_c_expr_source_range (&expr, loc, end_loc);
9354 break;
9355 }
9356 default:
9357 c_parser_error (parser, "expected expression");
9358 expr.set_error ();
9359 break;
9360 }
9361 break;
9362 case CPP_OPEN_PAREN:
9363 /* A parenthesized expression, statement expression or compound
9364 literal. */
9365 if (c_parser_peek_2nd_token (parser)->type == CPP_OPEN_BRACE)
9366 {
9367 /* A statement expression. */
9368 tree stmt;
9369 location_t brace_loc;
9370 c_parser_consume_token (parser);
9371 brace_loc = c_parser_peek_token (parser)->location;
9372 c_parser_consume_token (parser);
9373 /* If we've not yet started the current function's statement list,
9374 or we're in the parameter scope of an old-style function
9375 declaration, statement expressions are not allowed. */
9376 if (!building_stmt_list_p () || old_style_parameter_scope ())
9377 {
9378 error_at (loc, "braced-group within expression allowed "
9379 "only inside a function");
9380 parser->error = true;
9381 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
9382 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9383 expr.set_error ();
9384 break;
9385 }
9386 stmt = c_begin_stmt_expr ();
9387 c_parser_compound_statement_nostart (parser);
9388 location_t close_loc = c_parser_peek_token (parser)->location;
9389 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9390 "expected %<)%>");
9391 pedwarn (loc, OPT_Wpedantic,
9392 "ISO C forbids braced-groups within expressions");
9393 expr.value = c_finish_stmt_expr (brace_loc, stmt);
9394 set_c_expr_source_range (&expr, loc, close_loc);
9395 mark_exp_read (expr.value);
9396 }
9397 else
9398 {
9399 /* A parenthesized expression. */
9400 location_t loc_open_paren = c_parser_peek_token (parser)->location;
9401 c_parser_consume_token (parser);
9402 expr = c_parser_expression (parser);
9403 if (TREE_CODE (expr.value) == MODIFY_EXPR)
9404 suppress_warning (expr.value, OPT_Wparentheses);
9405 if (expr.original_code != C_MAYBE_CONST_EXPR
9406 && expr.original_code != SIZEOF_EXPR)
9407 expr.original_code = ERROR_MARK;
9408 /* Remember that we saw ( ) around the sizeof. */
9409 if (expr.original_code == SIZEOF_EXPR)
9410 expr.original_code = PAREN_SIZEOF_EXPR;
9411 /* Don't change EXPR.ORIGINAL_TYPE. */
9412 location_t loc_close_paren = c_parser_peek_token (parser)->location;
9413 set_c_expr_source_range (&expr, loc_open_paren, loc_close_paren);
9414 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9415 "expected %<)%>", loc_open_paren);
9416 }
9417 break;
9418 case CPP_KEYWORD:
9419 switch (c_parser_peek_token (parser)->keyword)
9420 {
9421 case RID_FUNCTION_NAME:
9422 case RID_PRETTY_FUNCTION_NAME:
9423 case RID_C99_FUNCTION_NAME:
9424 expr = c_parser_predefined_identifier (parser);
9425 break;
9426 case RID_VA_ARG:
9427 {
9428 location_t start_loc = loc;
9429 c_parser_consume_token (parser);
9430 matching_parens parens;
9431 if (!parens.require_open (parser))
9432 {
9433 expr.set_error ();
9434 break;
9435 }
9436 e1 = c_parser_expr_no_commas (parser, NULL);
9437 mark_exp_read (e1.value);
9438 e1.value = c_fully_fold (e1.value, false, NULL);
9439 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9440 {
9441 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9442 expr.set_error ();
9443 break;
9444 }
9445 loc = c_parser_peek_token (parser)->location;
9446 t1 = c_parser_type_name (parser);
9447 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
9448 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9449 "expected %<)%>");
9450 if (t1 == NULL)
9451 {
9452 expr.set_error ();
9453 }
9454 else
9455 {
9456 tree type_expr = NULL_TREE;
9457 expr.value = c_build_va_arg (start_loc, e1.value, loc,
9458 groktypename (t1, &type_expr, NULL));
9459 if (type_expr)
9460 {
9461 expr.value = build2 (C_MAYBE_CONST_EXPR,
9462 TREE_TYPE (expr.value), type_expr,
9463 expr.value);
9464 C_MAYBE_CONST_EXPR_NON_CONST (expr.value) = true;
9465 }
9466 set_c_expr_source_range (&expr, start_loc, end_loc);
9467 }
9468 }
9469 break;
9470 case RID_OFFSETOF:
9471 {
9472 c_parser_consume_token (parser);
9473 matching_parens parens;
9474 if (!parens.require_open (parser))
9475 {
9476 expr.set_error ();
9477 break;
9478 }
9479 t1 = c_parser_type_name (parser);
9480 if (t1 == NULL)
9481 parser->error = true;
9482 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9483 gcc_assert (parser->error);
9484 if (parser->error)
9485 {
9486 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9487 expr.set_error ();
9488 break;
9489 }
9490 tree type = groktypename (t1, NULL, NULL);
9491 tree offsetof_ref;
9492 if (type == error_mark_node)
9493 offsetof_ref = error_mark_node;
9494 else
9495 {
9496 offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
9497 SET_EXPR_LOCATION (offsetof_ref, loc);
9498 }
9499 /* Parse the second argument to __builtin_offsetof. We
9500 must have one identifier, and beyond that we want to
9501 accept sub structure and sub array references. */
9502 if (c_parser_next_token_is (parser, CPP_NAME))
9503 {
9504 c_token *comp_tok = c_parser_peek_token (parser);
9505 offsetof_ref
9506 = build_component_ref (loc, offsetof_ref, comp_tok->value,
9507 comp_tok->location, UNKNOWN_LOCATION);
9508 c_parser_consume_token (parser);
9509 while (c_parser_next_token_is (parser, CPP_DOT)
9510 || c_parser_next_token_is (parser,
9511 CPP_OPEN_SQUARE)
9512 || c_parser_next_token_is (parser,
9513 CPP_DEREF))
9514 {
9515 if (c_parser_next_token_is (parser, CPP_DEREF))
9516 {
9517 loc = c_parser_peek_token (parser)->location;
9518 offsetof_ref = build_array_ref (loc,
9519 offsetof_ref,
9520 integer_zero_node);
9521 goto do_dot;
9522 }
9523 else if (c_parser_next_token_is (parser, CPP_DOT))
9524 {
9525 do_dot:
9526 c_parser_consume_token (parser);
9527 if (c_parser_next_token_is_not (parser,
9528 CPP_NAME))
9529 {
9530 c_parser_error (parser, "expected identifier");
9531 break;
9532 }
9533 c_token *comp_tok = c_parser_peek_token (parser);
9534 offsetof_ref
9535 = build_component_ref (loc, offsetof_ref,
9536 comp_tok->value,
9537 comp_tok->location,
9538 UNKNOWN_LOCATION);
9539 c_parser_consume_token (parser);
9540 }
9541 else
9542 {
9543 struct c_expr ce;
9544 tree idx;
9545 loc = c_parser_peek_token (parser)->location;
9546 c_parser_consume_token (parser);
9547 ce = c_parser_expression (parser);
9548 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
9549 idx = ce.value;
9550 idx = c_fully_fold (idx, false, NULL);
9551 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
9552 "expected %<]%>");
9553 offsetof_ref = build_array_ref (loc, offsetof_ref, idx);
9554 }
9555 }
9556 }
9557 else
9558 c_parser_error (parser, "expected identifier");
9559 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
9560 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9561 "expected %<)%>");
9562 expr.value = fold_offsetof (offsetof_ref);
9563 set_c_expr_source_range (&expr, loc, end_loc);
9564 }
9565 break;
9566 case RID_CHOOSE_EXPR:
9567 {
9568 vec<c_expr_t, va_gc> *cexpr_list;
9569 c_expr_t *e1_p, *e2_p, *e3_p;
9570 tree c;
9571 location_t close_paren_loc;
9572
9573 c_parser_consume_token (parser);
9574 if (!c_parser_get_builtin_args (parser,
9575 "__builtin_choose_expr",
9576 &cexpr_list, true,
9577 &close_paren_loc))
9578 {
9579 expr.set_error ();
9580 break;
9581 }
9582
9583 if (vec_safe_length (cexpr_list) != 3)
9584 {
9585 error_at (loc, "wrong number of arguments to "
9586 "%<__builtin_choose_expr%>");
9587 expr.set_error ();
9588 break;
9589 }
9590
9591 e1_p = &(*cexpr_list)[0];
9592 e2_p = &(*cexpr_list)[1];
9593 e3_p = &(*cexpr_list)[2];
9594
9595 c = e1_p->value;
9596 mark_exp_read (e2_p->value);
9597 mark_exp_read (e3_p->value);
9598 if (TREE_CODE (c) != INTEGER_CST
9599 || !INTEGRAL_TYPE_P (TREE_TYPE (c)))
9600 error_at (loc,
9601 "first argument to %<__builtin_choose_expr%> not"
9602 " a constant");
9603 constant_expression_warning (c);
9604 expr = integer_zerop (c) ? *e3_p : *e2_p;
9605 set_c_expr_source_range (&expr, loc, close_paren_loc);
9606 break;
9607 }
9608 case RID_TYPES_COMPATIBLE_P:
9609 {
9610 c_parser_consume_token (parser);
9611 matching_parens parens;
9612 if (!parens.require_open (parser))
9613 {
9614 expr.set_error ();
9615 break;
9616 }
9617 t1 = c_parser_type_name (parser);
9618 if (t1 == NULL)
9619 {
9620 expr.set_error ();
9621 break;
9622 }
9623 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9624 {
9625 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9626 expr.set_error ();
9627 break;
9628 }
9629 t2 = c_parser_type_name (parser);
9630 if (t2 == NULL)
9631 {
9632 expr.set_error ();
9633 break;
9634 }
9635 location_t close_paren_loc = c_parser_peek_token (parser)->location;
9636 parens.skip_until_found_close (parser);
9637 tree e1, e2;
9638 e1 = groktypename (t1, NULL, NULL);
9639 e2 = groktypename (t2, NULL, NULL);
9640 if (e1 == error_mark_node || e2 == error_mark_node)
9641 {
9642 expr.set_error ();
9643 break;
9644 }
9645
9646 e1 = TYPE_MAIN_VARIANT (e1);
9647 e2 = TYPE_MAIN_VARIANT (e2);
9648
9649 expr.value
9650 = comptypes (e1, e2) ? integer_one_node : integer_zero_node;
9651 set_c_expr_source_range (&expr, loc, close_paren_loc);
9652 }
9653 break;
9654 case RID_BUILTIN_TGMATH:
9655 {
9656 vec<c_expr_t, va_gc> *cexpr_list;
9657 location_t close_paren_loc;
9658
9659 c_parser_consume_token (parser);
9660 if (!c_parser_get_builtin_args (parser,
9661 "__builtin_tgmath",
9662 &cexpr_list, false,
9663 &close_paren_loc))
9664 {
9665 expr.set_error ();
9666 break;
9667 }
9668
9669 if (vec_safe_length (cexpr_list) < 3)
9670 {
9671 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9672 expr.set_error ();
9673 break;
9674 }
9675
9676 unsigned int i;
9677 c_expr_t *p;
9678 FOR_EACH_VEC_ELT (*cexpr_list, i, p)
9679 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
9680 unsigned int nargs = check_tgmath_function (&(*cexpr_list)[0], 1);
9681 if (nargs == 0)
9682 {
9683 expr.set_error ();
9684 break;
9685 }
9686 if (vec_safe_length (cexpr_list) < nargs)
9687 {
9688 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9689 expr.set_error ();
9690 break;
9691 }
9692 unsigned int num_functions = vec_safe_length (cexpr_list) - nargs;
9693 if (num_functions < 2)
9694 {
9695 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9696 expr.set_error ();
9697 break;
9698 }
9699
9700 /* The first NUM_FUNCTIONS expressions are the function
9701 pointers. The remaining NARGS expressions are the
9702 arguments that are to be passed to one of those
9703 functions, chosen following <tgmath.h> rules. */
9704 for (unsigned int j = 1; j < num_functions; j++)
9705 {
9706 unsigned int this_nargs
9707 = check_tgmath_function (&(*cexpr_list)[j], j + 1);
9708 if (this_nargs == 0)
9709 {
9710 expr.set_error ();
9711 goto out;
9712 }
9713 if (this_nargs != nargs)
9714 {
9715 error_at ((*cexpr_list)[j].get_location (),
9716 "argument %u of %<__builtin_tgmath%> has "
9717 "wrong number of arguments", j + 1);
9718 expr.set_error ();
9719 goto out;
9720 }
9721 }
9722
9723 /* The functions all have the same number of arguments.
9724 Determine whether arguments and return types vary in
9725 ways permitted for <tgmath.h> functions. */
9726 /* The first entry in each of these vectors is for the
9727 return type, subsequent entries for parameter
9728 types. */
9729 auto_vec<enum tgmath_parm_kind> parm_kind (nargs + 1);
9730 auto_vec<tree> parm_first (nargs + 1);
9731 auto_vec<bool> parm_complex (nargs + 1);
9732 auto_vec<bool> parm_varies (nargs + 1);
9733 tree first_type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[0].value));
9734 tree first_ret = TYPE_MAIN_VARIANT (TREE_TYPE (first_type));
9735 parm_first.quick_push (first_ret);
9736 parm_complex.quick_push (TREE_CODE (first_ret) == COMPLEX_TYPE);
9737 parm_varies.quick_push (false);
9738 function_args_iterator iter;
9739 tree t;
9740 unsigned int argpos;
9741 FOREACH_FUNCTION_ARGS (first_type, t, iter)
9742 {
9743 if (t == void_type_node)
9744 break;
9745 parm_first.quick_push (TYPE_MAIN_VARIANT (t));
9746 parm_complex.quick_push (TREE_CODE (t) == COMPLEX_TYPE);
9747 parm_varies.quick_push (false);
9748 }
9749 for (unsigned int j = 1; j < num_functions; j++)
9750 {
9751 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9752 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
9753 if (ret != parm_first[0])
9754 {
9755 parm_varies[0] = true;
9756 if (!SCALAR_FLOAT_TYPE_P (parm_first[0])
9757 && !COMPLEX_FLOAT_TYPE_P (parm_first[0]))
9758 {
9759 error_at ((*cexpr_list)[0].get_location (),
9760 "invalid type-generic return type for "
9761 "argument %u of %<__builtin_tgmath%>",
9762 1);
9763 expr.set_error ();
9764 goto out;
9765 }
9766 if (!SCALAR_FLOAT_TYPE_P (ret)
9767 && !COMPLEX_FLOAT_TYPE_P (ret))
9768 {
9769 error_at ((*cexpr_list)[j].get_location (),
9770 "invalid type-generic return type for "
9771 "argument %u of %<__builtin_tgmath%>",
9772 j + 1);
9773 expr.set_error ();
9774 goto out;
9775 }
9776 }
9777 if (TREE_CODE (ret) == COMPLEX_TYPE)
9778 parm_complex[0] = true;
9779 argpos = 1;
9780 FOREACH_FUNCTION_ARGS (type, t, iter)
9781 {
9782 if (t == void_type_node)
9783 break;
9784 t = TYPE_MAIN_VARIANT (t);
9785 if (t != parm_first[argpos])
9786 {
9787 parm_varies[argpos] = true;
9788 if (!SCALAR_FLOAT_TYPE_P (parm_first[argpos])
9789 && !COMPLEX_FLOAT_TYPE_P (parm_first[argpos]))
9790 {
9791 error_at ((*cexpr_list)[0].get_location (),
9792 "invalid type-generic type for "
9793 "argument %u of argument %u of "
9794 "%<__builtin_tgmath%>", argpos, 1);
9795 expr.set_error ();
9796 goto out;
9797 }
9798 if (!SCALAR_FLOAT_TYPE_P (t)
9799 && !COMPLEX_FLOAT_TYPE_P (t))
9800 {
9801 error_at ((*cexpr_list)[j].get_location (),
9802 "invalid type-generic type for "
9803 "argument %u of argument %u of "
9804 "%<__builtin_tgmath%>", argpos, j + 1);
9805 expr.set_error ();
9806 goto out;
9807 }
9808 }
9809 if (TREE_CODE (t) == COMPLEX_TYPE)
9810 parm_complex[argpos] = true;
9811 argpos++;
9812 }
9813 }
9814 enum tgmath_parm_kind max_variation = tgmath_fixed;
9815 for (unsigned int j = 0; j <= nargs; j++)
9816 {
9817 enum tgmath_parm_kind this_kind;
9818 if (parm_varies[j])
9819 {
9820 if (parm_complex[j])
9821 max_variation = this_kind = tgmath_complex;
9822 else
9823 {
9824 this_kind = tgmath_real;
9825 if (max_variation != tgmath_complex)
9826 max_variation = tgmath_real;
9827 }
9828 }
9829 else
9830 this_kind = tgmath_fixed;
9831 parm_kind.quick_push (this_kind);
9832 }
9833 if (max_variation == tgmath_fixed)
9834 {
9835 error_at (loc, "function arguments of %<__builtin_tgmath%> "
9836 "all have the same type");
9837 expr.set_error ();
9838 break;
9839 }
9840
9841 /* Identify a parameter (not the return type) that varies,
9842 including with complex types if any variation includes
9843 complex types; there must be at least one such
9844 parameter. */
9845 unsigned int tgarg = 0;
9846 for (unsigned int j = 1; j <= nargs; j++)
9847 if (parm_kind[j] == max_variation)
9848 {
9849 tgarg = j;
9850 break;
9851 }
9852 if (tgarg == 0)
9853 {
9854 error_at (loc, "function arguments of %<__builtin_tgmath%> "
9855 "lack type-generic parameter");
9856 expr.set_error ();
9857 break;
9858 }
9859
9860 /* Determine the type of the relevant parameter for each
9861 function. */
9862 auto_vec<tree> tg_type (num_functions);
9863 for (unsigned int j = 0; j < num_functions; j++)
9864 {
9865 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9866 argpos = 1;
9867 FOREACH_FUNCTION_ARGS (type, t, iter)
9868 {
9869 if (argpos == tgarg)
9870 {
9871 tg_type.quick_push (TYPE_MAIN_VARIANT (t));
9872 break;
9873 }
9874 argpos++;
9875 }
9876 }
9877
9878 /* Verify that the corresponding types are different for
9879 all the listed functions. Also determine whether all
9880 the types are complex, whether all the types are
9881 standard or binary, and whether all the types are
9882 decimal. */
9883 bool all_complex = true;
9884 bool all_binary = true;
9885 bool all_decimal = true;
9886 hash_set<tree> tg_types;
9887 FOR_EACH_VEC_ELT (tg_type, i, t)
9888 {
9889 if (TREE_CODE (t) == COMPLEX_TYPE)
9890 all_decimal = false;
9891 else
9892 {
9893 all_complex = false;
9894 if (DECIMAL_FLOAT_TYPE_P (t))
9895 all_binary = false;
9896 else
9897 all_decimal = false;
9898 }
9899 if (tg_types.add (t))
9900 {
9901 error_at ((*cexpr_list)[i].get_location (),
9902 "duplicate type-generic parameter type for "
9903 "function argument %u of %<__builtin_tgmath%>",
9904 i + 1);
9905 expr.set_error ();
9906 goto out;
9907 }
9908 }
9909
9910 /* Verify that other parameters and the return type whose
9911 types vary have their types varying in the correct
9912 way. */
9913 for (unsigned int j = 0; j < num_functions; j++)
9914 {
9915 tree exp_type = tg_type[j];
9916 tree exp_real_type = exp_type;
9917 if (TREE_CODE (exp_type) == COMPLEX_TYPE)
9918 exp_real_type = TREE_TYPE (exp_type);
9919 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9920 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
9921 if ((parm_kind[0] == tgmath_complex && ret != exp_type)
9922 || (parm_kind[0] == tgmath_real && ret != exp_real_type))
9923 {
9924 error_at ((*cexpr_list)[j].get_location (),
9925 "bad return type for function argument %u "
9926 "of %<__builtin_tgmath%>", j + 1);
9927 expr.set_error ();
9928 goto out;
9929 }
9930 argpos = 1;
9931 FOREACH_FUNCTION_ARGS (type, t, iter)
9932 {
9933 if (t == void_type_node)
9934 break;
9935 t = TYPE_MAIN_VARIANT (t);
9936 if ((parm_kind[argpos] == tgmath_complex
9937 && t != exp_type)
9938 || (parm_kind[argpos] == tgmath_real
9939 && t != exp_real_type))
9940 {
9941 error_at ((*cexpr_list)[j].get_location (),
9942 "bad type for argument %u of "
9943 "function argument %u of "
9944 "%<__builtin_tgmath%>", argpos, j + 1);
9945 expr.set_error ();
9946 goto out;
9947 }
9948 argpos++;
9949 }
9950 }
9951
9952 /* The functions listed are a valid set of functions for a
9953 <tgmath.h> macro to select between. Identify the
9954 matching function, if any. First, the argument types
9955 must be combined following <tgmath.h> rules. Integer
9956 types are treated as _Decimal64 if any type-generic
9957 argument is decimal, or if the only alternatives for
9958 type-generic arguments are of decimal types, and are
9959 otherwise treated as double (or _Complex double for
9960 complex integer types, or _Float64 or _Complex _Float64
9961 if all the return types are the same _FloatN or
9962 _FloatNx type). After that adjustment, types are
9963 combined following the usual arithmetic conversions.
9964 If the function only accepts complex arguments, a
9965 complex type is produced. */
9966 bool arg_complex = all_complex;
9967 bool arg_binary = all_binary;
9968 bool arg_int_decimal = all_decimal;
9969 for (unsigned int j = 1; j <= nargs; j++)
9970 {
9971 if (parm_kind[j] == tgmath_fixed)
9972 continue;
9973 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
9974 tree type = TREE_TYPE (ce->value);
9975 if (!INTEGRAL_TYPE_P (type)
9976 && !SCALAR_FLOAT_TYPE_P (type)
9977 && TREE_CODE (type) != COMPLEX_TYPE)
9978 {
9979 error_at (ce->get_location (),
9980 "invalid type of argument %u of type-generic "
9981 "function", j);
9982 expr.set_error ();
9983 goto out;
9984 }
9985 if (DECIMAL_FLOAT_TYPE_P (type))
9986 {
9987 arg_int_decimal = true;
9988 if (all_complex)
9989 {
9990 error_at (ce->get_location (),
9991 "decimal floating-point argument %u to "
9992 "complex-only type-generic function", j);
9993 expr.set_error ();
9994 goto out;
9995 }
9996 else if (all_binary)
9997 {
9998 error_at (ce->get_location (),
9999 "decimal floating-point argument %u to "
10000 "binary-only type-generic function", j);
10001 expr.set_error ();
10002 goto out;
10003 }
10004 else if (arg_complex)
10005 {
10006 error_at (ce->get_location (),
10007 "both complex and decimal floating-point "
10008 "arguments to type-generic function");
10009 expr.set_error ();
10010 goto out;
10011 }
10012 else if (arg_binary)
10013 {
10014 error_at (ce->get_location (),
10015 "both binary and decimal floating-point "
10016 "arguments to type-generic function");
10017 expr.set_error ();
10018 goto out;
10019 }
10020 }
10021 else if (TREE_CODE (type) == COMPLEX_TYPE)
10022 {
10023 arg_complex = true;
10024 if (COMPLEX_FLOAT_TYPE_P (type))
10025 arg_binary = true;
10026 if (all_decimal)
10027 {
10028 error_at (ce->get_location (),
10029 "complex argument %u to "
10030 "decimal-only type-generic function", j);
10031 expr.set_error ();
10032 goto out;
10033 }
10034 else if (arg_int_decimal)
10035 {
10036 error_at (ce->get_location (),
10037 "both complex and decimal floating-point "
10038 "arguments to type-generic function");
10039 expr.set_error ();
10040 goto out;
10041 }
10042 }
10043 else if (SCALAR_FLOAT_TYPE_P (type))
10044 {
10045 arg_binary = true;
10046 if (all_decimal)
10047 {
10048 error_at (ce->get_location (),
10049 "binary argument %u to "
10050 "decimal-only type-generic function", j);
10051 expr.set_error ();
10052 goto out;
10053 }
10054 else if (arg_int_decimal)
10055 {
10056 error_at (ce->get_location (),
10057 "both binary and decimal floating-point "
10058 "arguments to type-generic function");
10059 expr.set_error ();
10060 goto out;
10061 }
10062 }
10063 }
10064 /* For a macro rounding its result to a narrower type, map
10065 integer types to _Float64 not double if the return type
10066 is a _FloatN or _FloatNx type. */
10067 bool arg_int_float64 = false;
10068 if (parm_kind[0] == tgmath_fixed
10069 && SCALAR_FLOAT_TYPE_P (parm_first[0])
10070 && float64_type_node != NULL_TREE)
10071 for (unsigned int j = 0; j < NUM_FLOATN_NX_TYPES; j++)
10072 if (parm_first[0] == FLOATN_TYPE_NODE (j))
10073 {
10074 arg_int_float64 = true;
10075 break;
10076 }
10077 tree arg_real = NULL_TREE;
10078 for (unsigned int j = 1; j <= nargs; j++)
10079 {
10080 if (parm_kind[j] == tgmath_fixed)
10081 continue;
10082 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
10083 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ce->value));
10084 if (TREE_CODE (type) == COMPLEX_TYPE)
10085 type = TREE_TYPE (type);
10086 if (INTEGRAL_TYPE_P (type))
10087 type = (arg_int_decimal
10088 ? dfloat64_type_node
10089 : arg_int_float64
10090 ? float64_type_node
10091 : double_type_node);
10092 if (arg_real == NULL_TREE)
10093 arg_real = type;
10094 else
10095 arg_real = common_type (arg_real, type);
10096 if (arg_real == error_mark_node)
10097 {
10098 expr.set_error ();
10099 goto out;
10100 }
10101 }
10102 tree arg_type = (arg_complex
10103 ? build_complex_type (arg_real)
10104 : arg_real);
10105
10106 /* Look for a function to call with type-generic parameter
10107 type ARG_TYPE. */
10108 c_expr_t *fn = NULL;
10109 for (unsigned int j = 0; j < num_functions; j++)
10110 {
10111 if (tg_type[j] == arg_type)
10112 {
10113 fn = &(*cexpr_list)[j];
10114 break;
10115 }
10116 }
10117 if (fn == NULL
10118 && parm_kind[0] == tgmath_fixed
10119 && SCALAR_FLOAT_TYPE_P (parm_first[0]))
10120 {
10121 /* Presume this is a macro that rounds its result to a
10122 narrower type, and look for the first function with
10123 at least the range and precision of the argument
10124 type. */
10125 for (unsigned int j = 0; j < num_functions; j++)
10126 {
10127 if (arg_complex
10128 != (TREE_CODE (tg_type[j]) == COMPLEX_TYPE))
10129 continue;
10130 tree real_tg_type = (arg_complex
10131 ? TREE_TYPE (tg_type[j])
10132 : tg_type[j]);
10133 if (DECIMAL_FLOAT_TYPE_P (arg_real)
10134 != DECIMAL_FLOAT_TYPE_P (real_tg_type))
10135 continue;
10136 scalar_float_mode arg_mode
10137 = SCALAR_FLOAT_TYPE_MODE (arg_real);
10138 scalar_float_mode tg_mode
10139 = SCALAR_FLOAT_TYPE_MODE (real_tg_type);
10140 const real_format *arg_fmt = REAL_MODE_FORMAT (arg_mode);
10141 const real_format *tg_fmt = REAL_MODE_FORMAT (tg_mode);
10142 if (arg_fmt->b == tg_fmt->b
10143 && arg_fmt->p <= tg_fmt->p
10144 && arg_fmt->emax <= tg_fmt->emax
10145 && (arg_fmt->emin - arg_fmt->p
10146 >= tg_fmt->emin - tg_fmt->p))
10147 {
10148 fn = &(*cexpr_list)[j];
10149 break;
10150 }
10151 }
10152 }
10153 if (fn == NULL)
10154 {
10155 error_at (loc, "no matching function for type-generic call");
10156 expr.set_error ();
10157 break;
10158 }
10159
10160 /* Construct a call to FN. */
10161 vec<tree, va_gc> *args;
10162 vec_alloc (args, nargs);
10163 vec<tree, va_gc> *origtypes;
10164 vec_alloc (origtypes, nargs);
10165 auto_vec<location_t> arg_loc (nargs);
10166 for (unsigned int j = 0; j < nargs; j++)
10167 {
10168 c_expr_t *ce = &(*cexpr_list)[num_functions + j];
10169 args->quick_push (ce->value);
10170 arg_loc.quick_push (ce->get_location ());
10171 origtypes->quick_push (ce->original_type);
10172 }
10173 expr.value = c_build_function_call_vec (loc, arg_loc, fn->value,
10174 args, origtypes);
10175 set_c_expr_source_range (&expr, loc, close_paren_loc);
10176 break;
10177 }
10178 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN:
10179 {
10180 vec<c_expr_t, va_gc> *cexpr_list;
10181 c_expr_t *e2_p;
10182 tree chain_value;
10183 location_t close_paren_loc;
10184
10185 c_parser_consume_token (parser);
10186 if (!c_parser_get_builtin_args (parser,
10187 "__builtin_call_with_static_chain",
10188 &cexpr_list, false,
10189 &close_paren_loc))
10190 {
10191 expr.set_error ();
10192 break;
10193 }
10194 if (vec_safe_length (cexpr_list) != 2)
10195 {
10196 error_at (loc, "wrong number of arguments to "
10197 "%<__builtin_call_with_static_chain%>");
10198 expr.set_error ();
10199 break;
10200 }
10201
10202 expr = (*cexpr_list)[0];
10203 e2_p = &(*cexpr_list)[1];
10204 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
10205 chain_value = e2_p->value;
10206 mark_exp_read (chain_value);
10207
10208 if (TREE_CODE (expr.value) != CALL_EXPR)
10209 error_at (loc, "first argument to "
10210 "%<__builtin_call_with_static_chain%> "
10211 "must be a call expression");
10212 else if (TREE_CODE (TREE_TYPE (chain_value)) != POINTER_TYPE)
10213 error_at (loc, "second argument to "
10214 "%<__builtin_call_with_static_chain%> "
10215 "must be a pointer type");
10216 else
10217 CALL_EXPR_STATIC_CHAIN (expr.value) = chain_value;
10218 set_c_expr_source_range (&expr, loc, close_paren_loc);
10219 break;
10220 }
10221 case RID_BUILTIN_COMPLEX:
10222 {
10223 vec<c_expr_t, va_gc> *cexpr_list;
10224 c_expr_t *e1_p, *e2_p;
10225 location_t close_paren_loc;
10226
10227 c_parser_consume_token (parser);
10228 if (!c_parser_get_builtin_args (parser,
10229 "__builtin_complex",
10230 &cexpr_list, false,
10231 &close_paren_loc))
10232 {
10233 expr.set_error ();
10234 break;
10235 }
10236
10237 if (vec_safe_length (cexpr_list) != 2)
10238 {
10239 error_at (loc, "wrong number of arguments to "
10240 "%<__builtin_complex%>");
10241 expr.set_error ();
10242 break;
10243 }
10244
10245 e1_p = &(*cexpr_list)[0];
10246 e2_p = &(*cexpr_list)[1];
10247
10248 *e1_p = convert_lvalue_to_rvalue (loc, *e1_p, true, true);
10249 if (TREE_CODE (e1_p->value) == EXCESS_PRECISION_EXPR)
10250 e1_p->value = convert (TREE_TYPE (e1_p->value),
10251 TREE_OPERAND (e1_p->value, 0));
10252 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
10253 if (TREE_CODE (e2_p->value) == EXCESS_PRECISION_EXPR)
10254 e2_p->value = convert (TREE_TYPE (e2_p->value),
10255 TREE_OPERAND (e2_p->value, 0));
10256 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
10257 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
10258 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p->value))
10259 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p->value)))
10260 {
10261 error_at (loc, "%<__builtin_complex%> operand "
10262 "not of real binary floating-point type");
10263 expr.set_error ();
10264 break;
10265 }
10266 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p->value))
10267 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p->value)))
10268 {
10269 error_at (loc,
10270 "%<__builtin_complex%> operands of different types");
10271 expr.set_error ();
10272 break;
10273 }
10274 pedwarn_c90 (loc, OPT_Wpedantic,
10275 "ISO C90 does not support complex types");
10276 expr.value = build2_loc (loc, COMPLEX_EXPR,
10277 build_complex_type
10278 (TYPE_MAIN_VARIANT
10279 (TREE_TYPE (e1_p->value))),
10280 e1_p->value, e2_p->value);
10281 set_c_expr_source_range (&expr, loc, close_paren_loc);
10282 break;
10283 }
10284 case RID_BUILTIN_SHUFFLE:
10285 {
10286 vec<c_expr_t, va_gc> *cexpr_list;
10287 unsigned int i;
10288 c_expr_t *p;
10289 location_t close_paren_loc;
10290
10291 c_parser_consume_token (parser);
10292 if (!c_parser_get_builtin_args (parser,
10293 "__builtin_shuffle",
10294 &cexpr_list, false,
10295 &close_paren_loc))
10296 {
10297 expr.set_error ();
10298 break;
10299 }
10300
10301 FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
10302 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
10303
10304 if (vec_safe_length (cexpr_list) == 2)
10305 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
10306 NULL_TREE,
10307 (*cexpr_list)[1].value);
10308
10309 else if (vec_safe_length (cexpr_list) == 3)
10310 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
10311 (*cexpr_list)[1].value,
10312 (*cexpr_list)[2].value);
10313 else
10314 {
10315 error_at (loc, "wrong number of arguments to "
10316 "%<__builtin_shuffle%>");
10317 expr.set_error ();
10318 }
10319 set_c_expr_source_range (&expr, loc, close_paren_loc);
10320 break;
10321 }
10322 case RID_BUILTIN_SHUFFLEVECTOR:
10323 {
10324 vec<c_expr_t, va_gc> *cexpr_list;
10325 unsigned int i;
10326 c_expr_t *p;
10327 location_t close_paren_loc;
10328
10329 c_parser_consume_token (parser);
10330 if (!c_parser_get_builtin_args (parser,
10331 "__builtin_shufflevector",
10332 &cexpr_list, false,
10333 &close_paren_loc))
10334 {
10335 expr.set_error ();
10336 break;
10337 }
10338
10339 FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
10340 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
10341
10342 if (vec_safe_length (cexpr_list) < 3)
10343 {
10344 error_at (loc, "wrong number of arguments to "
10345 "%<__builtin_shuffle%>");
10346 expr.set_error ();
10347 }
10348 else
10349 {
10350 auto_vec<tree, 16> mask;
10351 for (i = 2; i < cexpr_list->length (); ++i)
10352 mask.safe_push ((*cexpr_list)[i].value);
10353 expr.value = c_build_shufflevector (loc, (*cexpr_list)[0].value,
10354 (*cexpr_list)[1].value,
10355 mask);
10356 }
10357 set_c_expr_source_range (&expr, loc, close_paren_loc);
10358 break;
10359 }
10360 case RID_BUILTIN_CONVERTVECTOR:
10361 {
10362 location_t start_loc = loc;
10363 c_parser_consume_token (parser);
10364 matching_parens parens;
10365 if (!parens.require_open (parser))
10366 {
10367 expr.set_error ();
10368 break;
10369 }
10370 e1 = c_parser_expr_no_commas (parser, NULL);
10371 mark_exp_read (e1.value);
10372 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10373 {
10374 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10375 expr.set_error ();
10376 break;
10377 }
10378 loc = c_parser_peek_token (parser)->location;
10379 t1 = c_parser_type_name (parser);
10380 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
10381 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10382 "expected %<)%>");
10383 if (t1 == NULL)
10384 expr.set_error ();
10385 else
10386 {
10387 tree type_expr = NULL_TREE;
10388 expr.value = c_build_vec_convert (start_loc, e1.value, loc,
10389 groktypename (t1, &type_expr,
10390 NULL));
10391 set_c_expr_source_range (&expr, start_loc, end_loc);
10392 }
10393 }
10394 break;
10395 case RID_BUILTIN_ASSOC_BARRIER:
10396 {
10397 location_t start_loc = loc;
10398 c_parser_consume_token (parser);
10399 matching_parens parens;
10400 if (!parens.require_open (parser))
10401 {
10402 expr.set_error ();
10403 break;
10404 }
10405 e1 = c_parser_expr_no_commas (parser, NULL);
10406 mark_exp_read (e1.value);
10407 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
10408 parens.skip_until_found_close (parser);
10409 expr = parser_build_unary_op (loc, PAREN_EXPR, e1);
10410 set_c_expr_source_range (&expr, start_loc, end_loc);
10411 }
10412 break;
10413 case RID_AT_SELECTOR:
10414 {
10415 gcc_assert (c_dialect_objc ());
10416 c_parser_consume_token (parser);
10417 matching_parens parens;
10418 if (!parens.require_open (parser))
10419 {
10420 expr.set_error ();
10421 break;
10422 }
10423 tree sel = c_parser_objc_selector_arg (parser);
10424 location_t close_loc = c_parser_peek_token (parser)->location;
10425 parens.skip_until_found_close (parser);
10426 expr.value = objc_build_selector_expr (loc, sel);
10427 set_c_expr_source_range (&expr, loc, close_loc);
10428 }
10429 break;
10430 case RID_AT_PROTOCOL:
10431 {
10432 gcc_assert (c_dialect_objc ());
10433 c_parser_consume_token (parser);
10434 matching_parens parens;
10435 if (!parens.require_open (parser))
10436 {
10437 expr.set_error ();
10438 break;
10439 }
10440 if (c_parser_next_token_is_not (parser, CPP_NAME))
10441 {
10442 c_parser_error (parser, "expected identifier");
10443 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10444 expr.set_error ();
10445 break;
10446 }
10447 tree id = c_parser_peek_token (parser)->value;
10448 c_parser_consume_token (parser);
10449 location_t close_loc = c_parser_peek_token (parser)->location;
10450 parens.skip_until_found_close (parser);
10451 expr.value = objc_build_protocol_expr (id);
10452 set_c_expr_source_range (&expr, loc, close_loc);
10453 }
10454 break;
10455 case RID_AT_ENCODE:
10456 {
10457 /* Extension to support C-structures in the archiver. */
10458 gcc_assert (c_dialect_objc ());
10459 c_parser_consume_token (parser);
10460 matching_parens parens;
10461 if (!parens.require_open (parser))
10462 {
10463 expr.set_error ();
10464 break;
10465 }
10466 t1 = c_parser_type_name (parser);
10467 if (t1 == NULL)
10468 {
10469 expr.set_error ();
10470 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10471 break;
10472 }
10473 location_t close_loc = c_parser_peek_token (parser)->location;
10474 parens.skip_until_found_close (parser);
10475 tree type = groktypename (t1, NULL, NULL);
10476 expr.value = objc_build_encode_expr (type);
10477 set_c_expr_source_range (&expr, loc, close_loc);
10478 }
10479 break;
10480 case RID_GENERIC:
10481 expr = c_parser_generic_selection (parser);
10482 break;
10483 case RID_OMP_ALL_MEMORY:
10484 gcc_assert (flag_openmp);
10485 c_parser_consume_token (parser);
10486 error_at (loc, "%<omp_all_memory%> may only be used in OpenMP "
10487 "%<depend%> clause");
10488 expr.set_error ();
10489 break;
10490 /* C23 'nullptr' literal. */
10491 case RID_NULLPTR:
10492 c_parser_consume_token (parser);
10493 expr.value = nullptr_node;
10494 set_c_expr_source_range (&expr, tok_range);
10495 pedwarn_c11 (loc, OPT_Wpedantic,
10496 "ISO C does not support %qs before C2X", "nullptr");
10497 break;
10498 case RID_TRUE:
10499 c_parser_consume_token (parser);
10500 expr.value = boolean_true_node;
10501 set_c_expr_source_range (&expr, tok_range);
10502 break;
10503 case RID_FALSE:
10504 c_parser_consume_token (parser);
10505 expr.value = boolean_false_node;
10506 set_c_expr_source_range (&expr, tok_range);
10507 break;
10508 default:
10509 c_parser_error (parser, "expected expression");
10510 expr.set_error ();
10511 break;
10512 }
10513 break;
10514 case CPP_OPEN_SQUARE:
10515 if (c_dialect_objc ())
10516 {
10517 tree receiver, args;
10518 c_parser_consume_token (parser);
10519 receiver = c_parser_objc_receiver (parser);
10520 args = c_parser_objc_message_args (parser);
10521 location_t close_loc = c_parser_peek_token (parser)->location;
10522 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10523 "expected %<]%>");
10524 expr.value = objc_build_message_expr (receiver, args);
10525 set_c_expr_source_range (&expr, loc, close_loc);
10526 break;
10527 }
10528 /* Else fall through to report error. */
10529 /* FALLTHRU */
10530 default:
10531 c_parser_error (parser, "expected expression");
10532 expr.set_error ();
10533 break;
10534 }
10535 out:
10536 return c_parser_postfix_expression_after_primary
10537 (parser, EXPR_LOC_OR_LOC (expr.value, loc), expr);
10538 }
10539
10540 /* Parse a postfix expression after a parenthesized type name: the
10541 brace-enclosed initializer of a compound literal, possibly followed
10542 by some postfix operators. This is separate because it is not
10543 possible to tell until after the type name whether a cast
10544 expression has a cast or a compound literal, or whether the operand
10545 of sizeof is a parenthesized type name or starts with a compound
10546 literal. TYPE_LOC is the location where TYPE_NAME starts--the
10547 location of the first token after the parentheses around the type
10548 name. */
10549
10550 static struct c_expr
10551 c_parser_postfix_expression_after_paren_type (c_parser *parser,
10552 struct c_declspecs *scspecs,
10553 struct c_type_name *type_name,
10554 location_t type_loc)
10555 {
10556 tree type;
10557 struct c_expr init;
10558 bool non_const;
10559 struct c_expr expr;
10560 location_t start_loc;
10561 tree type_expr = NULL_TREE;
10562 bool type_expr_const = true;
10563 check_compound_literal_type (type_loc, type_name);
10564 rich_location richloc (line_table, type_loc);
10565 start_init (NULL_TREE, NULL, 0, &richloc);
10566 type = groktypename (type_name, &type_expr, &type_expr_const);
10567 start_loc = c_parser_peek_token (parser)->location;
10568 if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type))
10569 {
10570 error_at (type_loc, "compound literal has variable size");
10571 type = error_mark_node;
10572 }
10573 init = c_parser_braced_init (parser, type, false, NULL, NULL_TREE);
10574 finish_init ();
10575 maybe_warn_string_init (type_loc, type, init);
10576
10577 if (type != error_mark_node
10578 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type))
10579 && current_function_decl)
10580 {
10581 error ("compound literal qualified by address-space qualifier");
10582 type = error_mark_node;
10583 }
10584
10585 if (!pedwarn_c90 (start_loc, OPT_Wpedantic,
10586 "ISO C90 forbids compound literals") && scspecs)
10587 pedwarn_c11 (start_loc, OPT_Wpedantic,
10588 "ISO C forbids storage class specifiers in compound literals "
10589 "before C2X");
10590 non_const = ((init.value && TREE_CODE (init.value) == CONSTRUCTOR)
10591 ? CONSTRUCTOR_NON_CONST (init.value)
10592 : init.original_code == C_MAYBE_CONST_EXPR);
10593 non_const |= !type_expr_const;
10594 unsigned int alignas_align = 0;
10595 if (type != error_mark_node
10596 && type_name->specs->align_log != -1)
10597 {
10598 alignas_align = 1U << type_name->specs->align_log;
10599 if (alignas_align < min_align_of_type (type))
10600 {
10601 error_at (type_name->specs->locations[cdw_alignas],
10602 "%<_Alignas%> specifiers cannot reduce "
10603 "alignment of compound literal");
10604 alignas_align = 0;
10605 }
10606 }
10607 expr.value = build_compound_literal (start_loc, type, init.value, non_const,
10608 alignas_align, scspecs);
10609 set_c_expr_source_range (&expr, init.src_range);
10610 expr.m_decimal = 0;
10611 expr.original_code = ERROR_MARK;
10612 expr.original_type = NULL;
10613 if (type != error_mark_node
10614 && expr.value != error_mark_node
10615 && type_expr)
10616 {
10617 if (TREE_CODE (expr.value) == C_MAYBE_CONST_EXPR)
10618 {
10619 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr.value) == NULL_TREE);
10620 C_MAYBE_CONST_EXPR_PRE (expr.value) = type_expr;
10621 }
10622 else
10623 {
10624 gcc_assert (!non_const);
10625 expr.value = build2 (C_MAYBE_CONST_EXPR, type,
10626 type_expr, expr.value);
10627 }
10628 }
10629 return c_parser_postfix_expression_after_primary (parser, start_loc, expr);
10630 }
10631
10632 /* Callback function for sizeof_pointer_memaccess_warning to compare
10633 types. */
10634
10635 static bool
10636 sizeof_ptr_memacc_comptypes (tree type1, tree type2)
10637 {
10638 return comptypes (type1, type2) == 1;
10639 }
10640
10641 /* Warn for patterns where abs-like function appears to be used incorrectly,
10642 gracefully ignore any non-abs-like function. The warning location should
10643 be LOC. FNDECL is the declaration of called function, it must be a
10644 BUILT_IN_NORMAL function. ARG is the first and only argument of the
10645 call. */
10646
10647 static void
10648 warn_for_abs (location_t loc, tree fndecl, tree arg)
10649 {
10650 /* Avoid warning in unreachable subexpressions. */
10651 if (c_inhibit_evaluation_warnings)
10652 return;
10653
10654 tree atype = TREE_TYPE (arg);
10655
10656 /* Casts from pointers (and thus arrays and fndecls) will generate
10657 -Wint-conversion warnings. Most other wrong types hopefully lead to type
10658 mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P
10659 types and possibly other exotic types. */
10660 if (!INTEGRAL_TYPE_P (atype)
10661 && !SCALAR_FLOAT_TYPE_P (atype)
10662 && TREE_CODE (atype) != COMPLEX_TYPE)
10663 return;
10664
10665 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10666
10667 switch (fcode)
10668 {
10669 case BUILT_IN_ABS:
10670 case BUILT_IN_LABS:
10671 case BUILT_IN_LLABS:
10672 case BUILT_IN_IMAXABS:
10673 if (!INTEGRAL_TYPE_P (atype))
10674 {
10675 if (SCALAR_FLOAT_TYPE_P (atype))
10676 warning_at (loc, OPT_Wabsolute_value,
10677 "using integer absolute value function %qD when "
10678 "argument is of floating-point type %qT",
10679 fndecl, atype);
10680 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10681 warning_at (loc, OPT_Wabsolute_value,
10682 "using integer absolute value function %qD when "
10683 "argument is of complex type %qT", fndecl, atype);
10684 else
10685 gcc_unreachable ();
10686 return;
10687 }
10688 if (TYPE_UNSIGNED (atype))
10689 warning_at (loc, OPT_Wabsolute_value,
10690 "taking the absolute value of unsigned type %qT "
10691 "has no effect", atype);
10692 break;
10693
10694 CASE_FLT_FN (BUILT_IN_FABS):
10695 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS):
10696 if (!SCALAR_FLOAT_TYPE_P (atype)
10697 || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype)))
10698 {
10699 if (INTEGRAL_TYPE_P (atype))
10700 warning_at (loc, OPT_Wabsolute_value,
10701 "using floating-point absolute value function %qD "
10702 "when argument is of integer type %qT", fndecl, atype);
10703 else if (DECIMAL_FLOAT_TYPE_P (atype))
10704 warning_at (loc, OPT_Wabsolute_value,
10705 "using floating-point absolute value function %qD "
10706 "when argument is of decimal floating-point type %qT",
10707 fndecl, atype);
10708 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10709 warning_at (loc, OPT_Wabsolute_value,
10710 "using floating-point absolute value function %qD when "
10711 "argument is of complex type %qT", fndecl, atype);
10712 else
10713 gcc_unreachable ();
10714 return;
10715 }
10716 break;
10717
10718 CASE_FLT_FN (BUILT_IN_CABS):
10719 if (TREE_CODE (atype) != COMPLEX_TYPE)
10720 {
10721 if (INTEGRAL_TYPE_P (atype))
10722 warning_at (loc, OPT_Wabsolute_value,
10723 "using complex absolute value function %qD when "
10724 "argument is of integer type %qT", fndecl, atype);
10725 else if (SCALAR_FLOAT_TYPE_P (atype))
10726 warning_at (loc, OPT_Wabsolute_value,
10727 "using complex absolute value function %qD when "
10728 "argument is of floating-point type %qT",
10729 fndecl, atype);
10730 else
10731 gcc_unreachable ();
10732
10733 return;
10734 }
10735 break;
10736
10737 case BUILT_IN_FABSD32:
10738 case BUILT_IN_FABSD64:
10739 case BUILT_IN_FABSD128:
10740 if (!DECIMAL_FLOAT_TYPE_P (atype))
10741 {
10742 if (INTEGRAL_TYPE_P (atype))
10743 warning_at (loc, OPT_Wabsolute_value,
10744 "using decimal floating-point absolute value "
10745 "function %qD when argument is of integer type %qT",
10746 fndecl, atype);
10747 else if (SCALAR_FLOAT_TYPE_P (atype))
10748 warning_at (loc, OPT_Wabsolute_value,
10749 "using decimal floating-point absolute value "
10750 "function %qD when argument is of floating-point "
10751 "type %qT", fndecl, atype);
10752 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10753 warning_at (loc, OPT_Wabsolute_value,
10754 "using decimal floating-point absolute value "
10755 "function %qD when argument is of complex type %qT",
10756 fndecl, atype);
10757 else
10758 gcc_unreachable ();
10759 return;
10760 }
10761 break;
10762
10763 default:
10764 return;
10765 }
10766
10767 if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
10768 return;
10769
10770 tree ftype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
10771 if (TREE_CODE (atype) == COMPLEX_TYPE)
10772 {
10773 gcc_assert (TREE_CODE (ftype) == COMPLEX_TYPE);
10774 atype = TREE_TYPE (atype);
10775 ftype = TREE_TYPE (ftype);
10776 }
10777
10778 if (TYPE_PRECISION (ftype) < TYPE_PRECISION (atype))
10779 warning_at (loc, OPT_Wabsolute_value,
10780 "absolute value function %qD given an argument of type %qT "
10781 "but has parameter of type %qT which may cause truncation "
10782 "of value", fndecl, atype, ftype);
10783 }
10784
10785
10786 /* Parse a postfix expression after the initial primary or compound
10787 literal; that is, parse a series of postfix operators.
10788
10789 EXPR_LOC is the location of the primary expression. */
10790
10791 static struct c_expr
10792 c_parser_postfix_expression_after_primary (c_parser *parser,
10793 location_t expr_loc,
10794 struct c_expr expr)
10795 {
10796 struct c_expr orig_expr;
10797 tree ident, idx;
10798 location_t sizeof_arg_loc[3], comp_loc;
10799 tree sizeof_arg[3];
10800 unsigned int literal_zero_mask;
10801 unsigned int i;
10802 vec<tree, va_gc> *exprlist;
10803 vec<tree, va_gc> *origtypes = NULL;
10804 vec<location_t> arg_loc = vNULL;
10805 location_t start;
10806 location_t finish;
10807
10808 while (true)
10809 {
10810 location_t op_loc = c_parser_peek_token (parser)->location;
10811 switch (c_parser_peek_token (parser)->type)
10812 {
10813 case CPP_OPEN_SQUARE:
10814 /* Array reference. */
10815 c_parser_consume_token (parser);
10816 idx = c_parser_expression (parser).value;
10817 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10818 "expected %<]%>");
10819 start = expr.get_start ();
10820 finish = parser->tokens_buf[0].location;
10821 expr.value = build_array_ref (op_loc, expr.value, idx);
10822 set_c_expr_source_range (&expr, start, finish);
10823 expr.original_code = ERROR_MARK;
10824 expr.original_type = NULL;
10825 expr.m_decimal = 0;
10826 break;
10827 case CPP_OPEN_PAREN:
10828 /* Function call. */
10829 {
10830 matching_parens parens;
10831 parens.consume_open (parser);
10832 for (i = 0; i < 3; i++)
10833 {
10834 sizeof_arg[i] = NULL_TREE;
10835 sizeof_arg_loc[i] = UNKNOWN_LOCATION;
10836 }
10837 literal_zero_mask = 0;
10838 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10839 exprlist = NULL;
10840 else
10841 exprlist = c_parser_expr_list (parser, true, false, &origtypes,
10842 sizeof_arg_loc, sizeof_arg,
10843 &arg_loc, &literal_zero_mask);
10844 parens.skip_until_found_close (parser);
10845 }
10846 orig_expr = expr;
10847 mark_exp_read (expr.value);
10848 if (warn_sizeof_pointer_memaccess)
10849 sizeof_pointer_memaccess_warning (sizeof_arg_loc,
10850 expr.value, exprlist,
10851 sizeof_arg,
10852 sizeof_ptr_memacc_comptypes);
10853 if (TREE_CODE (expr.value) == FUNCTION_DECL)
10854 {
10855 if (fndecl_built_in_p (expr.value, BUILT_IN_MEMSET)
10856 && vec_safe_length (exprlist) == 3)
10857 {
10858 tree arg0 = (*exprlist)[0];
10859 tree arg2 = (*exprlist)[2];
10860 warn_for_memset (expr_loc, arg0, arg2, literal_zero_mask);
10861 }
10862 if (warn_absolute_value
10863 && fndecl_built_in_p (expr.value, BUILT_IN_NORMAL)
10864 && vec_safe_length (exprlist) == 1)
10865 warn_for_abs (expr_loc, expr.value, (*exprlist)[0]);
10866 }
10867
10868 start = expr.get_start ();
10869 finish = parser->tokens_buf[0].get_finish ();
10870 expr.value
10871 = c_build_function_call_vec (expr_loc, arg_loc, expr.value,
10872 exprlist, origtypes);
10873 set_c_expr_source_range (&expr, start, finish);
10874 expr.m_decimal = 0;
10875
10876 expr.original_code = ERROR_MARK;
10877 if (TREE_CODE (expr.value) == INTEGER_CST
10878 && TREE_CODE (orig_expr.value) == FUNCTION_DECL
10879 && fndecl_built_in_p (orig_expr.value, BUILT_IN_CONSTANT_P))
10880 expr.original_code = C_MAYBE_CONST_EXPR;
10881 expr.original_type = NULL;
10882 if (exprlist)
10883 {
10884 release_tree_vector (exprlist);
10885 release_tree_vector (origtypes);
10886 }
10887 arg_loc.release ();
10888 break;
10889 case CPP_DOT:
10890 /* Structure element reference. */
10891 c_parser_consume_token (parser);
10892 expr = default_function_array_conversion (expr_loc, expr);
10893 if (c_parser_next_token_is (parser, CPP_NAME))
10894 {
10895 c_token *comp_tok = c_parser_peek_token (parser);
10896 ident = comp_tok->value;
10897 comp_loc = comp_tok->location;
10898 }
10899 else
10900 {
10901 c_parser_error (parser, "expected identifier");
10902 expr.set_error ();
10903 expr.original_code = ERROR_MARK;
10904 expr.original_type = NULL;
10905 return expr;
10906 }
10907 start = expr.get_start ();
10908 finish = c_parser_peek_token (parser)->get_finish ();
10909 c_parser_consume_token (parser);
10910 expr.value = build_component_ref (op_loc, expr.value, ident,
10911 comp_loc, UNKNOWN_LOCATION);
10912 set_c_expr_source_range (&expr, start, finish);
10913 expr.original_code = ERROR_MARK;
10914 if (TREE_CODE (expr.value) != COMPONENT_REF)
10915 expr.original_type = NULL;
10916 else
10917 {
10918 /* Remember the original type of a bitfield. */
10919 tree field = TREE_OPERAND (expr.value, 1);
10920 if (TREE_CODE (field) != FIELD_DECL)
10921 expr.original_type = NULL;
10922 else
10923 expr.original_type = DECL_BIT_FIELD_TYPE (field);
10924 }
10925 expr.m_decimal = 0;
10926 break;
10927 case CPP_DEREF:
10928 /* Structure element reference. */
10929 c_parser_consume_token (parser);
10930 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, false);
10931 if (c_parser_next_token_is (parser, CPP_NAME))
10932 {
10933 c_token *comp_tok = c_parser_peek_token (parser);
10934 ident = comp_tok->value;
10935 comp_loc = comp_tok->location;
10936 }
10937 else
10938 {
10939 c_parser_error (parser, "expected identifier");
10940 expr.set_error ();
10941 expr.original_code = ERROR_MARK;
10942 expr.original_type = NULL;
10943 return expr;
10944 }
10945 start = expr.get_start ();
10946 finish = c_parser_peek_token (parser)->get_finish ();
10947 c_parser_consume_token (parser);
10948 expr.value = build_component_ref (op_loc,
10949 build_indirect_ref (op_loc,
10950 expr.value,
10951 RO_ARROW),
10952 ident, comp_loc,
10953 expr.get_location ());
10954 set_c_expr_source_range (&expr, start, finish);
10955 expr.original_code = ERROR_MARK;
10956 if (TREE_CODE (expr.value) != COMPONENT_REF)
10957 expr.original_type = NULL;
10958 else
10959 {
10960 /* Remember the original type of a bitfield. */
10961 tree field = TREE_OPERAND (expr.value, 1);
10962 if (TREE_CODE (field) != FIELD_DECL)
10963 expr.original_type = NULL;
10964 else
10965 expr.original_type = DECL_BIT_FIELD_TYPE (field);
10966 }
10967 expr.m_decimal = 0;
10968 break;
10969 case CPP_PLUS_PLUS:
10970 /* Postincrement. */
10971 start = expr.get_start ();
10972 finish = c_parser_peek_token (parser)->get_finish ();
10973 c_parser_consume_token (parser);
10974 expr = default_function_array_read_conversion (expr_loc, expr);
10975 expr.value = build_unary_op (op_loc, POSTINCREMENT_EXPR,
10976 expr.value, false);
10977 set_c_expr_source_range (&expr, start, finish);
10978 expr.original_code = ERROR_MARK;
10979 expr.original_type = NULL;
10980 break;
10981 case CPP_MINUS_MINUS:
10982 /* Postdecrement. */
10983 start = expr.get_start ();
10984 finish = c_parser_peek_token (parser)->get_finish ();
10985 c_parser_consume_token (parser);
10986 expr = default_function_array_read_conversion (expr_loc, expr);
10987 expr.value = build_unary_op (op_loc, POSTDECREMENT_EXPR,
10988 expr.value, false);
10989 set_c_expr_source_range (&expr, start, finish);
10990 expr.original_code = ERROR_MARK;
10991 expr.original_type = NULL;
10992 break;
10993 default:
10994 return expr;
10995 }
10996 }
10997 }
10998
10999 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
11000
11001 expression:
11002 assignment-expression
11003 expression , assignment-expression
11004 */
11005
11006 static struct c_expr
11007 c_parser_expression (c_parser *parser)
11008 {
11009 location_t tloc = c_parser_peek_token (parser)->location;
11010 struct c_expr expr;
11011 expr = c_parser_expr_no_commas (parser, NULL);
11012 if (c_parser_next_token_is (parser, CPP_COMMA))
11013 expr = convert_lvalue_to_rvalue (tloc, expr, true, false);
11014 while (c_parser_next_token_is (parser, CPP_COMMA))
11015 {
11016 struct c_expr next;
11017 tree lhsval;
11018 location_t loc = c_parser_peek_token (parser)->location;
11019 location_t expr_loc;
11020 c_parser_consume_token (parser);
11021 expr_loc = c_parser_peek_token (parser)->location;
11022 lhsval = expr.value;
11023 while (TREE_CODE (lhsval) == COMPOUND_EXPR
11024 || TREE_CODE (lhsval) == NOP_EXPR)
11025 {
11026 if (TREE_CODE (lhsval) == COMPOUND_EXPR)
11027 lhsval = TREE_OPERAND (lhsval, 1);
11028 else
11029 lhsval = TREE_OPERAND (lhsval, 0);
11030 }
11031 if (DECL_P (lhsval) || handled_component_p (lhsval))
11032 mark_exp_read (lhsval);
11033 next = c_parser_expr_no_commas (parser, NULL);
11034 next = convert_lvalue_to_rvalue (expr_loc, next, true, false);
11035 expr.value = build_compound_expr (loc, expr.value, next.value);
11036 expr.original_code = COMPOUND_EXPR;
11037 expr.original_type = next.original_type;
11038 expr.m_decimal = 0;
11039 }
11040 return expr;
11041 }
11042
11043 /* Parse an expression and convert functions or arrays to pointers and
11044 lvalues to rvalues. */
11045
11046 static struct c_expr
11047 c_parser_expression_conv (c_parser *parser)
11048 {
11049 struct c_expr expr;
11050 location_t loc = c_parser_peek_token (parser)->location;
11051 expr = c_parser_expression (parser);
11052 expr = convert_lvalue_to_rvalue (loc, expr, true, false);
11053 return expr;
11054 }
11055
11056 /* Helper function of c_parser_expr_list. Check if IDXth (0 based)
11057 argument is a literal zero alone and if so, set it in literal_zero_mask. */
11058
11059 static inline void
11060 c_parser_check_literal_zero (c_parser *parser, unsigned *literal_zero_mask,
11061 unsigned int idx)
11062 {
11063 if (idx >= HOST_BITS_PER_INT)
11064 return;
11065
11066 c_token *tok = c_parser_peek_token (parser);
11067 switch (tok->type)
11068 {
11069 case CPP_NUMBER:
11070 case CPP_CHAR:
11071 case CPP_WCHAR:
11072 case CPP_CHAR16:
11073 case CPP_CHAR32:
11074 case CPP_UTF8CHAR:
11075 /* If a parameter is literal zero alone, remember it
11076 for -Wmemset-transposed-args warning. */
11077 if (integer_zerop (tok->value)
11078 && !TREE_OVERFLOW (tok->value)
11079 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
11080 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
11081 *literal_zero_mask |= 1U << idx;
11082 default:
11083 break;
11084 }
11085 }
11086
11087 /* Parse a non-empty list of expressions. If CONVERT_P, convert
11088 functions and arrays to pointers and lvalues to rvalues. If
11089 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the
11090 locations of function arguments into this vector.
11091
11092 nonempty-expr-list:
11093 assignment-expression
11094 nonempty-expr-list , assignment-expression
11095 */
11096
11097 static vec<tree, va_gc> *
11098 c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
11099 vec<tree, va_gc> **p_orig_types,
11100 location_t *sizeof_arg_loc, tree *sizeof_arg,
11101 vec<location_t> *locations,
11102 unsigned int *literal_zero_mask)
11103 {
11104 vec<tree, va_gc> *ret;
11105 vec<tree, va_gc> *orig_types;
11106 struct c_expr expr;
11107 unsigned int idx = 0;
11108
11109 ret = make_tree_vector ();
11110 if (p_orig_types == NULL)
11111 orig_types = NULL;
11112 else
11113 orig_types = make_tree_vector ();
11114
11115 if (literal_zero_mask)
11116 c_parser_check_literal_zero (parser, literal_zero_mask, 0);
11117 expr = c_parser_expr_no_commas (parser, NULL);
11118 if (convert_p)
11119 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true, true);
11120 if (fold_p)
11121 expr.value = c_fully_fold (expr.value, false, NULL);
11122 ret->quick_push (expr.value);
11123 if (orig_types)
11124 orig_types->quick_push (expr.original_type);
11125 if (locations)
11126 locations->safe_push (expr.get_location ());
11127 if (sizeof_arg != NULL
11128 && (expr.original_code == SIZEOF_EXPR
11129 || expr.original_code == PAREN_SIZEOF_EXPR))
11130 {
11131 sizeof_arg[0] = c_last_sizeof_arg;
11132 sizeof_arg_loc[0] = c_last_sizeof_loc;
11133 }
11134 while (c_parser_next_token_is (parser, CPP_COMMA))
11135 {
11136 c_parser_consume_token (parser);
11137 if (literal_zero_mask)
11138 c_parser_check_literal_zero (parser, literal_zero_mask, idx + 1);
11139 expr = c_parser_expr_no_commas (parser, NULL);
11140 if (convert_p)
11141 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true,
11142 true);
11143 if (fold_p)
11144 expr.value = c_fully_fold (expr.value, false, NULL);
11145 vec_safe_push (ret, expr.value);
11146 if (orig_types)
11147 vec_safe_push (orig_types, expr.original_type);
11148 if (locations)
11149 locations->safe_push (expr.get_location ());
11150 if (++idx < 3
11151 && sizeof_arg != NULL
11152 && (expr.original_code == SIZEOF_EXPR
11153 || expr.original_code == PAREN_SIZEOF_EXPR))
11154 {
11155 sizeof_arg[idx] = c_last_sizeof_arg;
11156 sizeof_arg_loc[idx] = c_last_sizeof_loc;
11157 }
11158 }
11159 if (orig_types)
11160 *p_orig_types = orig_types;
11161 return ret;
11162 }
11163 \f
11164 /* Parse Objective-C-specific constructs. */
11165
11166 /* Parse an objc-class-definition.
11167
11168 objc-class-definition:
11169 @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
11170 objc-class-instance-variables[opt] objc-methodprotolist @end
11171 @implementation identifier objc-superclass[opt]
11172 objc-class-instance-variables[opt]
11173 @interface identifier ( identifier ) objc-protocol-refs[opt]
11174 objc-methodprotolist @end
11175 @interface identifier ( ) objc-protocol-refs[opt]
11176 objc-methodprotolist @end
11177 @implementation identifier ( identifier )
11178
11179 objc-superclass:
11180 : identifier
11181
11182 "@interface identifier (" must start "@interface identifier (
11183 identifier ) ...": objc-methodprotolist in the first production may
11184 not start with a parenthesized identifier as a declarator of a data
11185 definition with no declaration specifiers if the objc-superclass,
11186 objc-protocol-refs and objc-class-instance-variables are omitted. */
11187
11188 static void
11189 c_parser_objc_class_definition (c_parser *parser, tree attributes)
11190 {
11191 bool iface_p;
11192 tree id1;
11193 tree superclass;
11194 if (c_parser_next_token_is_keyword (parser, RID_AT_INTERFACE))
11195 iface_p = true;
11196 else if (c_parser_next_token_is_keyword (parser, RID_AT_IMPLEMENTATION))
11197 iface_p = false;
11198 else
11199 gcc_unreachable ();
11200
11201 c_parser_consume_token (parser);
11202 if (c_parser_next_token_is_not (parser, CPP_NAME))
11203 {
11204 c_parser_error (parser, "expected identifier");
11205 return;
11206 }
11207 id1 = c_parser_peek_token (parser)->value;
11208 location_t loc1 = c_parser_peek_token (parser)->location;
11209 c_parser_consume_token (parser);
11210 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11211 {
11212 /* We have a category or class extension. */
11213 tree id2;
11214 tree proto = NULL_TREE;
11215 matching_parens parens;
11216 parens.consume_open (parser);
11217 if (c_parser_next_token_is_not (parser, CPP_NAME))
11218 {
11219 if (iface_p && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
11220 {
11221 /* We have a class extension. */
11222 id2 = NULL_TREE;
11223 }
11224 else
11225 {
11226 c_parser_error (parser, "expected identifier or %<)%>");
11227 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
11228 return;
11229 }
11230 }
11231 else
11232 {
11233 id2 = c_parser_peek_token (parser)->value;
11234 c_parser_consume_token (parser);
11235 }
11236 parens.skip_until_found_close (parser);
11237 if (!iface_p)
11238 {
11239 objc_start_category_implementation (id1, id2);
11240 return;
11241 }
11242 if (c_parser_next_token_is (parser, CPP_LESS))
11243 proto = c_parser_objc_protocol_refs (parser);
11244 objc_start_category_interface (id1, id2, proto, attributes);
11245 c_parser_objc_methodprotolist (parser);
11246 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
11247 objc_finish_interface ();
11248 return;
11249 }
11250 if (c_parser_next_token_is (parser, CPP_COLON))
11251 {
11252 c_parser_consume_token (parser);
11253 if (c_parser_next_token_is_not (parser, CPP_NAME))
11254 {
11255 c_parser_error (parser, "expected identifier");
11256 return;
11257 }
11258 superclass = c_parser_peek_token (parser)->value;
11259 c_parser_consume_token (parser);
11260 }
11261 else
11262 superclass = NULL_TREE;
11263 if (iface_p)
11264 {
11265 tree proto = NULL_TREE;
11266 if (c_parser_next_token_is (parser, CPP_LESS))
11267 proto = c_parser_objc_protocol_refs (parser);
11268 objc_start_class_interface (id1, loc1, superclass, proto, attributes);
11269 }
11270 else
11271 objc_start_class_implementation (id1, superclass);
11272 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11273 c_parser_objc_class_instance_variables (parser);
11274 if (iface_p)
11275 {
11276 objc_continue_interface ();
11277 c_parser_objc_methodprotolist (parser);
11278 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
11279 objc_finish_interface ();
11280 }
11281 else
11282 {
11283 objc_continue_implementation ();
11284 return;
11285 }
11286 }
11287
11288 /* Parse objc-class-instance-variables.
11289
11290 objc-class-instance-variables:
11291 { objc-instance-variable-decl-list[opt] }
11292
11293 objc-instance-variable-decl-list:
11294 objc-visibility-spec
11295 objc-instance-variable-decl ;
11296 ;
11297 objc-instance-variable-decl-list objc-visibility-spec
11298 objc-instance-variable-decl-list objc-instance-variable-decl ;
11299 objc-instance-variable-decl-list ;
11300
11301 objc-visibility-spec:
11302 @private
11303 @protected
11304 @public
11305
11306 objc-instance-variable-decl:
11307 struct-declaration
11308 */
11309
11310 static void
11311 c_parser_objc_class_instance_variables (c_parser *parser)
11312 {
11313 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
11314 c_parser_consume_token (parser);
11315 while (c_parser_next_token_is_not (parser, CPP_EOF))
11316 {
11317 tree decls;
11318 /* Parse any stray semicolon. */
11319 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
11320 {
11321 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11322 "extra semicolon");
11323 c_parser_consume_token (parser);
11324 continue;
11325 }
11326 /* Stop if at the end of the instance variables. */
11327 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
11328 {
11329 c_parser_consume_token (parser);
11330 break;
11331 }
11332 /* Parse any objc-visibility-spec. */
11333 if (c_parser_next_token_is_keyword (parser, RID_AT_PRIVATE))
11334 {
11335 c_parser_consume_token (parser);
11336 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE);
11337 continue;
11338 }
11339 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROTECTED))
11340 {
11341 c_parser_consume_token (parser);
11342 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED);
11343 continue;
11344 }
11345 else if (c_parser_next_token_is_keyword (parser, RID_AT_PUBLIC))
11346 {
11347 c_parser_consume_token (parser);
11348 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC);
11349 continue;
11350 }
11351 else if (c_parser_next_token_is_keyword (parser, RID_AT_PACKAGE))
11352 {
11353 c_parser_consume_token (parser);
11354 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE);
11355 continue;
11356 }
11357 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
11358 {
11359 c_parser_pragma (parser, pragma_external, NULL);
11360 continue;
11361 }
11362
11363 /* Parse some comma-separated declarations. */
11364 decls = c_parser_struct_declaration (parser);
11365 if (decls == NULL)
11366 {
11367 /* There is a syntax error. We want to skip the offending
11368 tokens up to the next ';' (included) or '}'
11369 (excluded). */
11370
11371 /* First, skip manually a ')' or ']'. This is because they
11372 reduce the nesting level, so c_parser_skip_until_found()
11373 wouldn't be able to skip past them. */
11374 c_token *token = c_parser_peek_token (parser);
11375 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_CLOSE_SQUARE)
11376 c_parser_consume_token (parser);
11377
11378 /* Then, do the standard skipping. */
11379 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11380
11381 /* We hopefully recovered. Start normal parsing again. */
11382 parser->error = false;
11383 continue;
11384 }
11385 else
11386 {
11387 /* Comma-separated instance variables are chained together
11388 in reverse order; add them one by one. */
11389 tree ivar = nreverse (decls);
11390 for (; ivar; ivar = DECL_CHAIN (ivar))
11391 objc_add_instance_variable (copy_node (ivar));
11392 }
11393 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11394 }
11395 }
11396
11397 /* Parse an objc-class-declaration.
11398
11399 objc-class-declaration:
11400 @class identifier-list ;
11401 */
11402
11403 static void
11404 c_parser_objc_class_declaration (c_parser *parser)
11405 {
11406 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_CLASS));
11407 c_parser_consume_token (parser);
11408 /* Any identifiers, including those declared as type names, are OK
11409 here. */
11410 while (true)
11411 {
11412 tree id;
11413 if (c_parser_next_token_is_not (parser, CPP_NAME))
11414 {
11415 c_parser_error (parser, "expected identifier");
11416 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11417 parser->error = false;
11418 return;
11419 }
11420 id = c_parser_peek_token (parser)->value;
11421 objc_declare_class (id);
11422 c_parser_consume_token (parser);
11423 if (c_parser_next_token_is (parser, CPP_COMMA))
11424 c_parser_consume_token (parser);
11425 else
11426 break;
11427 }
11428 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11429 }
11430
11431 /* Parse an objc-alias-declaration.
11432
11433 objc-alias-declaration:
11434 @compatibility_alias identifier identifier ;
11435 */
11436
11437 static void
11438 c_parser_objc_alias_declaration (c_parser *parser)
11439 {
11440 tree id1, id2;
11441 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_ALIAS));
11442 c_parser_consume_token (parser);
11443 if (c_parser_next_token_is_not (parser, CPP_NAME))
11444 {
11445 c_parser_error (parser, "expected identifier");
11446 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11447 return;
11448 }
11449 id1 = c_parser_peek_token (parser)->value;
11450 c_parser_consume_token (parser);
11451 if (c_parser_next_token_is_not (parser, CPP_NAME))
11452 {
11453 c_parser_error (parser, "expected identifier");
11454 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11455 return;
11456 }
11457 id2 = c_parser_peek_token (parser)->value;
11458 c_parser_consume_token (parser);
11459 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11460 objc_declare_alias (id1, id2);
11461 }
11462
11463 /* Parse an objc-protocol-definition.
11464
11465 objc-protocol-definition:
11466 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
11467 @protocol identifier-list ;
11468
11469 "@protocol identifier ;" should be resolved as "@protocol
11470 identifier-list ;": objc-methodprotolist may not start with a
11471 semicolon in the first alternative if objc-protocol-refs are
11472 omitted. */
11473
11474 static void
11475 c_parser_objc_protocol_definition (c_parser *parser, tree attributes)
11476 {
11477 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROTOCOL));
11478
11479 c_parser_consume_token (parser);
11480 if (c_parser_next_token_is_not (parser, CPP_NAME))
11481 {
11482 c_parser_error (parser, "expected identifier");
11483 return;
11484 }
11485 if (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
11486 || c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON)
11487 {
11488 /* Any identifiers, including those declared as type names, are
11489 OK here. */
11490 while (true)
11491 {
11492 tree id;
11493 if (c_parser_next_token_is_not (parser, CPP_NAME))
11494 {
11495 c_parser_error (parser, "expected identifier");
11496 break;
11497 }
11498 id = c_parser_peek_token (parser)->value;
11499 objc_declare_protocol (id, attributes);
11500 c_parser_consume_token (parser);
11501 if (c_parser_next_token_is (parser, CPP_COMMA))
11502 c_parser_consume_token (parser);
11503 else
11504 break;
11505 }
11506 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11507 }
11508 else
11509 {
11510 tree id = c_parser_peek_token (parser)->value;
11511 tree proto = NULL_TREE;
11512 c_parser_consume_token (parser);
11513 if (c_parser_next_token_is (parser, CPP_LESS))
11514 proto = c_parser_objc_protocol_refs (parser);
11515 parser->objc_pq_context = true;
11516 objc_start_protocol (id, proto, attributes);
11517 c_parser_objc_methodprotolist (parser);
11518 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
11519 parser->objc_pq_context = false;
11520 objc_finish_interface ();
11521 }
11522 }
11523
11524 /* Parse an objc-method-type.
11525
11526 objc-method-type:
11527 +
11528 -
11529
11530 Return true if it is a class method (+) and false if it is
11531 an instance method (-).
11532 */
11533 static inline bool
11534 c_parser_objc_method_type (c_parser *parser)
11535 {
11536 switch (c_parser_peek_token (parser)->type)
11537 {
11538 case CPP_PLUS:
11539 c_parser_consume_token (parser);
11540 return true;
11541 case CPP_MINUS:
11542 c_parser_consume_token (parser);
11543 return false;
11544 default:
11545 gcc_unreachable ();
11546 }
11547 }
11548
11549 /* Parse an objc-method-definition.
11550
11551 objc-method-definition:
11552 objc-method-type objc-method-decl ;[opt] compound-statement
11553 */
11554
11555 static void
11556 c_parser_objc_method_definition (c_parser *parser)
11557 {
11558 bool is_class_method = c_parser_objc_method_type (parser);
11559 tree decl, attributes = NULL_TREE, expr = NULL_TREE;
11560 parser->objc_pq_context = true;
11561 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
11562 &expr);
11563 if (decl == error_mark_node)
11564 return; /* Bail here. */
11565
11566 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
11567 {
11568 c_parser_consume_token (parser);
11569 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11570 "extra semicolon in method definition specified");
11571 }
11572
11573 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11574 {
11575 c_parser_error (parser, "expected %<{%>");
11576 return;
11577 }
11578
11579 parser->objc_pq_context = false;
11580 if (objc_start_method_definition (is_class_method, decl, attributes, expr))
11581 {
11582 add_stmt (c_parser_compound_statement (parser));
11583 objc_finish_method_definition (current_function_decl);
11584 }
11585 else
11586 {
11587 /* This code is executed when we find a method definition
11588 outside of an @implementation context (or invalid for other
11589 reasons). Parse the method (to keep going) but do not emit
11590 any code.
11591 */
11592 c_parser_compound_statement (parser);
11593 }
11594 }
11595
11596 /* Parse an objc-methodprotolist.
11597
11598 objc-methodprotolist:
11599 empty
11600 objc-methodprotolist objc-methodproto
11601 objc-methodprotolist declaration
11602 objc-methodprotolist ;
11603 @optional
11604 @required
11605
11606 The declaration is a data definition, which may be missing
11607 declaration specifiers under the same rules and diagnostics as
11608 other data definitions outside functions, and the stray semicolon
11609 is diagnosed the same way as a stray semicolon outside a
11610 function. */
11611
11612 static void
11613 c_parser_objc_methodprotolist (c_parser *parser)
11614 {
11615 while (true)
11616 {
11617 /* The list is terminated by @end. */
11618 switch (c_parser_peek_token (parser)->type)
11619 {
11620 case CPP_SEMICOLON:
11621 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11622 "ISO C does not allow extra %<;%> outside of a function");
11623 c_parser_consume_token (parser);
11624 break;
11625 case CPP_PLUS:
11626 case CPP_MINUS:
11627 c_parser_objc_methodproto (parser);
11628 break;
11629 case CPP_PRAGMA:
11630 c_parser_pragma (parser, pragma_external, NULL);
11631 break;
11632 case CPP_EOF:
11633 return;
11634 default:
11635 if (c_parser_next_token_is_keyword (parser, RID_AT_END))
11636 return;
11637 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY))
11638 c_parser_objc_at_property_declaration (parser);
11639 else if (c_parser_next_token_is_keyword (parser, RID_AT_OPTIONAL))
11640 {
11641 objc_set_method_opt (true);
11642 c_parser_consume_token (parser);
11643 }
11644 else if (c_parser_next_token_is_keyword (parser, RID_AT_REQUIRED))
11645 {
11646 objc_set_method_opt (false);
11647 c_parser_consume_token (parser);
11648 }
11649 else
11650 c_parser_declaration_or_fndef (parser, false, false, true,
11651 false, true);
11652 break;
11653 }
11654 }
11655 }
11656
11657 /* Parse an objc-methodproto.
11658
11659 objc-methodproto:
11660 objc-method-type objc-method-decl ;
11661 */
11662
11663 static void
11664 c_parser_objc_methodproto (c_parser *parser)
11665 {
11666 bool is_class_method = c_parser_objc_method_type (parser);
11667 tree decl, attributes = NULL_TREE;
11668
11669 /* Remember protocol qualifiers in prototypes. */
11670 parser->objc_pq_context = true;
11671 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
11672 NULL);
11673 /* Forget protocol qualifiers now. */
11674 parser->objc_pq_context = false;
11675
11676 /* Do not allow the presence of attributes to hide an erroneous
11677 method implementation in the interface section. */
11678 if (!c_parser_next_token_is (parser, CPP_SEMICOLON))
11679 {
11680 c_parser_error (parser, "expected %<;%>");
11681 return;
11682 }
11683
11684 if (decl != error_mark_node)
11685 objc_add_method_declaration (is_class_method, decl, attributes);
11686
11687 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11688 }
11689
11690 /* If we are at a position that method attributes may be present, check that
11691 there are not any parsed already (a syntax error) and then collect any
11692 specified at the current location. Finally, if new attributes were present,
11693 check that the next token is legal ( ';' for decls and '{' for defs). */
11694
11695 static bool
11696 c_parser_objc_maybe_method_attributes (c_parser* parser, tree* attributes)
11697 {
11698 bool bad = false;
11699 if (*attributes)
11700 {
11701 c_parser_error (parser,
11702 "method attributes must be specified at the end only");
11703 *attributes = NULL_TREE;
11704 bad = true;
11705 }
11706
11707 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
11708 *attributes = c_parser_gnu_attributes (parser);
11709
11710 /* If there were no attributes here, just report any earlier error. */
11711 if (*attributes == NULL_TREE || bad)
11712 return bad;
11713
11714 /* If the attributes are followed by a ; or {, then just report any earlier
11715 error. */
11716 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
11717 || c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11718 return bad;
11719
11720 /* We've got attributes, but not at the end. */
11721 c_parser_error (parser,
11722 "expected %<;%> or %<{%> after method attribute definition");
11723 return true;
11724 }
11725
11726 /* Parse an objc-method-decl.
11727
11728 objc-method-decl:
11729 ( objc-type-name ) objc-selector
11730 objc-selector
11731 ( objc-type-name ) objc-keyword-selector objc-optparmlist
11732 objc-keyword-selector objc-optparmlist
11733 gnu-attributes
11734
11735 objc-keyword-selector:
11736 objc-keyword-decl
11737 objc-keyword-selector objc-keyword-decl
11738
11739 objc-keyword-decl:
11740 objc-selector : ( objc-type-name ) identifier
11741 objc-selector : identifier
11742 : ( objc-type-name ) identifier
11743 : identifier
11744
11745 objc-optparmlist:
11746 objc-optparms objc-optellipsis
11747
11748 objc-optparms:
11749 empty
11750 objc-opt-parms , parameter-declaration
11751
11752 objc-optellipsis:
11753 empty
11754 , ...
11755 */
11756
11757 static tree
11758 c_parser_objc_method_decl (c_parser *parser, bool is_class_method,
11759 tree *attributes, tree *expr)
11760 {
11761 tree type = NULL_TREE;
11762 tree sel;
11763 tree parms = NULL_TREE;
11764 bool ellipsis = false;
11765 bool attr_err = false;
11766
11767 *attributes = NULL_TREE;
11768 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11769 {
11770 matching_parens parens;
11771 parens.consume_open (parser);
11772 type = c_parser_objc_type_name (parser);
11773 parens.skip_until_found_close (parser);
11774 }
11775 sel = c_parser_objc_selector (parser);
11776 /* If there is no selector, or a colon follows, we have an
11777 objc-keyword-selector. If there is a selector, and a colon does
11778 not follow, that selector ends the objc-method-decl. */
11779 if (!sel || c_parser_next_token_is (parser, CPP_COLON))
11780 {
11781 tree tsel = sel;
11782 tree list = NULL_TREE;
11783 while (true)
11784 {
11785 tree atype = NULL_TREE, id, keyworddecl;
11786 tree param_attr = NULL_TREE;
11787 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11788 break;
11789 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11790 {
11791 c_parser_consume_token (parser);
11792 atype = c_parser_objc_type_name (parser);
11793 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
11794 "expected %<)%>");
11795 }
11796 /* New ObjC allows attributes on method parameters. */
11797 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
11798 param_attr = c_parser_gnu_attributes (parser);
11799 if (c_parser_next_token_is_not (parser, CPP_NAME))
11800 {
11801 c_parser_error (parser, "expected identifier");
11802 return error_mark_node;
11803 }
11804 id = c_parser_peek_token (parser)->value;
11805 c_parser_consume_token (parser);
11806 keyworddecl = objc_build_keyword_decl (tsel, atype, id, param_attr);
11807 list = chainon (list, keyworddecl);
11808 tsel = c_parser_objc_selector (parser);
11809 if (!tsel && c_parser_next_token_is_not (parser, CPP_COLON))
11810 break;
11811 }
11812
11813 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
11814
11815 /* Parse the optional parameter list. Optional Objective-C
11816 method parameters follow the C syntax, and may include '...'
11817 to denote a variable number of arguments. */
11818 parms = make_node (TREE_LIST);
11819 while (c_parser_next_token_is (parser, CPP_COMMA))
11820 {
11821 struct c_parm *parm;
11822 c_parser_consume_token (parser);
11823 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
11824 {
11825 ellipsis = true;
11826 c_parser_consume_token (parser);
11827 attr_err |= c_parser_objc_maybe_method_attributes
11828 (parser, attributes) ;
11829 break;
11830 }
11831 parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
11832 if (parm == NULL)
11833 break;
11834 parms = chainon (parms,
11835 build_tree_list (NULL_TREE, grokparm (parm, expr)));
11836 }
11837 sel = list;
11838 }
11839 else
11840 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
11841
11842 if (sel == NULL)
11843 {
11844 c_parser_error (parser, "objective-c method declaration is expected");
11845 return error_mark_node;
11846 }
11847
11848 if (attr_err)
11849 return error_mark_node;
11850
11851 return objc_build_method_signature (is_class_method, type, sel, parms, ellipsis);
11852 }
11853
11854 /* Parse an objc-type-name.
11855
11856 objc-type-name:
11857 objc-type-qualifiers[opt] type-name
11858 objc-type-qualifiers[opt]
11859
11860 objc-type-qualifiers:
11861 objc-type-qualifier
11862 objc-type-qualifiers objc-type-qualifier
11863
11864 objc-type-qualifier: one of
11865 in out inout bycopy byref oneway
11866 */
11867
11868 static tree
11869 c_parser_objc_type_name (c_parser *parser)
11870 {
11871 tree quals = NULL_TREE;
11872 struct c_type_name *type_name = NULL;
11873 tree type = NULL_TREE;
11874 while (true)
11875 {
11876 c_token *token = c_parser_peek_token (parser);
11877 if (token->type == CPP_KEYWORD
11878 && (token->keyword == RID_IN
11879 || token->keyword == RID_OUT
11880 || token->keyword == RID_INOUT
11881 || token->keyword == RID_BYCOPY
11882 || token->keyword == RID_BYREF
11883 || token->keyword == RID_ONEWAY))
11884 {
11885 quals = chainon (build_tree_list (NULL_TREE, token->value), quals);
11886 c_parser_consume_token (parser);
11887 }
11888 else
11889 break;
11890 }
11891 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
11892 type_name = c_parser_type_name (parser);
11893 if (type_name)
11894 type = groktypename (type_name, NULL, NULL);
11895
11896 /* If the type is unknown, and error has already been produced and
11897 we need to recover from the error. In that case, use NULL_TREE
11898 for the type, as if no type had been specified; this will use the
11899 default type ('id') which is good for error recovery. */
11900 if (type == error_mark_node)
11901 type = NULL_TREE;
11902
11903 return build_tree_list (quals, type);
11904 }
11905
11906 /* Parse objc-protocol-refs.
11907
11908 objc-protocol-refs:
11909 < identifier-list >
11910 */
11911
11912 static tree
11913 c_parser_objc_protocol_refs (c_parser *parser)
11914 {
11915 tree list = NULL_TREE;
11916 gcc_assert (c_parser_next_token_is (parser, CPP_LESS));
11917 c_parser_consume_token (parser);
11918 /* Any identifiers, including those declared as type names, are OK
11919 here. */
11920 while (true)
11921 {
11922 tree id;
11923 if (c_parser_next_token_is_not (parser, CPP_NAME))
11924 {
11925 c_parser_error (parser, "expected identifier");
11926 break;
11927 }
11928 id = c_parser_peek_token (parser)->value;
11929 list = chainon (list, build_tree_list (NULL_TREE, id));
11930 c_parser_consume_token (parser);
11931 if (c_parser_next_token_is (parser, CPP_COMMA))
11932 c_parser_consume_token (parser);
11933 else
11934 break;
11935 }
11936 c_parser_require (parser, CPP_GREATER, "expected %<>%>");
11937 return list;
11938 }
11939
11940 /* Parse an objc-try-catch-finally-statement.
11941
11942 objc-try-catch-finally-statement:
11943 @try compound-statement objc-catch-list[opt]
11944 @try compound-statement objc-catch-list[opt] @finally compound-statement
11945
11946 objc-catch-list:
11947 @catch ( objc-catch-parameter-declaration ) compound-statement
11948 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
11949
11950 objc-catch-parameter-declaration:
11951 parameter-declaration
11952 '...'
11953
11954 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
11955
11956 PS: This function is identical to cp_parser_objc_try_catch_finally_statement
11957 for C++. Keep them in sync. */
11958
11959 static void
11960 c_parser_objc_try_catch_finally_statement (c_parser *parser)
11961 {
11962 location_t location;
11963 tree stmt;
11964
11965 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_TRY));
11966 c_parser_consume_token (parser);
11967 location = c_parser_peek_token (parser)->location;
11968 objc_maybe_warn_exceptions (location);
11969 stmt = c_parser_compound_statement (parser);
11970 objc_begin_try_stmt (location, stmt);
11971
11972 while (c_parser_next_token_is_keyword (parser, RID_AT_CATCH))
11973 {
11974 struct c_parm *parm;
11975 tree parameter_declaration = error_mark_node;
11976 bool seen_open_paren = false;
11977
11978 c_parser_consume_token (parser);
11979 matching_parens parens;
11980 if (!parens.require_open (parser))
11981 seen_open_paren = true;
11982 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
11983 {
11984 /* We have "@catch (...)" (where the '...' are literally
11985 what is in the code). Skip the '...'.
11986 parameter_declaration is set to NULL_TREE, and
11987 objc_being_catch_clauses() knows that that means
11988 '...'. */
11989 c_parser_consume_token (parser);
11990 parameter_declaration = NULL_TREE;
11991 }
11992 else
11993 {
11994 /* We have "@catch (NSException *exception)" or something
11995 like that. Parse the parameter declaration. */
11996 parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
11997 if (parm == NULL)
11998 parameter_declaration = error_mark_node;
11999 else
12000 parameter_declaration = grokparm (parm, NULL);
12001 }
12002 if (seen_open_paren)
12003 parens.require_close (parser);
12004 else
12005 {
12006 /* If there was no open parenthesis, we are recovering from
12007 an error, and we are trying to figure out what mistake
12008 the user has made. */
12009
12010 /* If there is an immediate closing parenthesis, the user
12011 probably forgot the opening one (ie, they typed "@catch
12012 NSException *e)". Parse the closing parenthesis and keep
12013 going. */
12014 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
12015 c_parser_consume_token (parser);
12016
12017 /* If these is no immediate closing parenthesis, the user
12018 probably doesn't know that parenthesis are required at
12019 all (ie, they typed "@catch NSException *e"). So, just
12020 forget about the closing parenthesis and keep going. */
12021 }
12022 objc_begin_catch_clause (parameter_declaration);
12023 if (c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
12024 c_parser_compound_statement_nostart (parser);
12025 objc_finish_catch_clause ();
12026 }
12027 if (c_parser_next_token_is_keyword (parser, RID_AT_FINALLY))
12028 {
12029 c_parser_consume_token (parser);
12030 location = c_parser_peek_token (parser)->location;
12031 stmt = c_parser_compound_statement (parser);
12032 objc_build_finally_clause (location, stmt);
12033 }
12034 objc_finish_try_stmt ();
12035 }
12036
12037 /* Parse an objc-synchronized-statement.
12038
12039 objc-synchronized-statement:
12040 @synchronized ( expression ) compound-statement
12041 */
12042
12043 static void
12044 c_parser_objc_synchronized_statement (c_parser *parser)
12045 {
12046 location_t loc;
12047 tree expr, stmt;
12048 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNCHRONIZED));
12049 c_parser_consume_token (parser);
12050 loc = c_parser_peek_token (parser)->location;
12051 objc_maybe_warn_exceptions (loc);
12052 matching_parens parens;
12053 if (parens.require_open (parser))
12054 {
12055 struct c_expr ce = c_parser_expression (parser);
12056 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
12057 expr = ce.value;
12058 expr = c_fully_fold (expr, false, NULL);
12059 parens.skip_until_found_close (parser);
12060 }
12061 else
12062 expr = error_mark_node;
12063 stmt = c_parser_compound_statement (parser);
12064 objc_build_synchronized (loc, expr, stmt);
12065 }
12066
12067 /* Parse an objc-selector; return NULL_TREE without an error if the
12068 next token is not an objc-selector.
12069
12070 objc-selector:
12071 identifier
12072 one of
12073 enum struct union if else while do for switch case default
12074 break continue return goto asm sizeof typeof typeof_unqual __alignof
12075 unsigned long const short volatile signed restrict _Complex
12076 in out inout bycopy byref oneway int char float double void _Bool
12077 _Atomic
12078
12079 ??? Why this selection of keywords but not, for example, storage
12080 class specifiers? */
12081
12082 static tree
12083 c_parser_objc_selector (c_parser *parser)
12084 {
12085 c_token *token = c_parser_peek_token (parser);
12086 tree value = token->value;
12087 if (token->type == CPP_NAME)
12088 {
12089 c_parser_consume_token (parser);
12090 return value;
12091 }
12092 if (token->type != CPP_KEYWORD)
12093 return NULL_TREE;
12094 switch (token->keyword)
12095 {
12096 case RID_ENUM:
12097 case RID_STRUCT:
12098 case RID_UNION:
12099 case RID_IF:
12100 case RID_ELSE:
12101 case RID_WHILE:
12102 case RID_DO:
12103 case RID_FOR:
12104 case RID_SWITCH:
12105 case RID_CASE:
12106 case RID_DEFAULT:
12107 case RID_BREAK:
12108 case RID_CONTINUE:
12109 case RID_RETURN:
12110 case RID_GOTO:
12111 case RID_ASM:
12112 case RID_SIZEOF:
12113 case RID_TYPEOF:
12114 case RID_TYPEOF_UNQUAL:
12115 case RID_ALIGNOF:
12116 case RID_UNSIGNED:
12117 case RID_LONG:
12118 case RID_CONST:
12119 case RID_SHORT:
12120 case RID_VOLATILE:
12121 case RID_SIGNED:
12122 case RID_RESTRICT:
12123 case RID_COMPLEX:
12124 case RID_IN:
12125 case RID_OUT:
12126 case RID_INOUT:
12127 case RID_BYCOPY:
12128 case RID_BYREF:
12129 case RID_ONEWAY:
12130 case RID_INT:
12131 case RID_CHAR:
12132 case RID_FLOAT:
12133 case RID_DOUBLE:
12134 CASE_RID_FLOATN_NX:
12135 case RID_VOID:
12136 case RID_BOOL:
12137 case RID_ATOMIC:
12138 case RID_AUTO_TYPE:
12139 case RID_INT_N_0:
12140 case RID_INT_N_1:
12141 case RID_INT_N_2:
12142 case RID_INT_N_3:
12143 c_parser_consume_token (parser);
12144 return value;
12145 default:
12146 return NULL_TREE;
12147 }
12148 }
12149
12150 /* Parse an objc-selector-arg.
12151
12152 objc-selector-arg:
12153 objc-selector
12154 objc-keywordname-list
12155
12156 objc-keywordname-list:
12157 objc-keywordname
12158 objc-keywordname-list objc-keywordname
12159
12160 objc-keywordname:
12161 objc-selector :
12162 :
12163 */
12164
12165 static tree
12166 c_parser_objc_selector_arg (c_parser *parser)
12167 {
12168 tree sel = c_parser_objc_selector (parser);
12169 tree list = NULL_TREE;
12170 if (sel
12171 && c_parser_next_token_is_not (parser, CPP_COLON)
12172 && c_parser_next_token_is_not (parser, CPP_SCOPE))
12173 return sel;
12174 while (true)
12175 {
12176 if (c_parser_next_token_is (parser, CPP_SCOPE))
12177 {
12178 c_parser_consume_token (parser);
12179 list = chainon (list, build_tree_list (sel, NULL_TREE));
12180 list = chainon (list, build_tree_list (NULL_TREE, NULL_TREE));
12181 }
12182 else
12183 {
12184 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
12185 return list;
12186 list = chainon (list, build_tree_list (sel, NULL_TREE));
12187 }
12188 sel = c_parser_objc_selector (parser);
12189 if (!sel
12190 && c_parser_next_token_is_not (parser, CPP_COLON)
12191 && c_parser_next_token_is_not (parser, CPP_SCOPE))
12192 break;
12193 }
12194 return list;
12195 }
12196
12197 /* Parse an objc-receiver.
12198
12199 objc-receiver:
12200 expression
12201 class-name
12202 type-name
12203 */
12204
12205 static tree
12206 c_parser_objc_receiver (c_parser *parser)
12207 {
12208 location_t loc = c_parser_peek_token (parser)->location;
12209
12210 if (c_parser_peek_token (parser)->type == CPP_NAME
12211 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
12212 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
12213 {
12214 tree id = c_parser_peek_token (parser)->value;
12215 c_parser_consume_token (parser);
12216 return objc_get_class_reference (id);
12217 }
12218 struct c_expr ce = c_parser_expression (parser);
12219 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
12220 return c_fully_fold (ce.value, false, NULL);
12221 }
12222
12223 /* Parse objc-message-args.
12224
12225 objc-message-args:
12226 objc-selector
12227 objc-keywordarg-list
12228
12229 objc-keywordarg-list:
12230 objc-keywordarg
12231 objc-keywordarg-list objc-keywordarg
12232
12233 objc-keywordarg:
12234 objc-selector : objc-keywordexpr
12235 : objc-keywordexpr
12236 */
12237
12238 static tree
12239 c_parser_objc_message_args (c_parser *parser)
12240 {
12241 tree sel = c_parser_objc_selector (parser);
12242 tree list = NULL_TREE;
12243 if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
12244 return sel;
12245 while (true)
12246 {
12247 tree keywordexpr;
12248 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
12249 return error_mark_node;
12250 keywordexpr = c_parser_objc_keywordexpr (parser);
12251 list = chainon (list, build_tree_list (sel, keywordexpr));
12252 sel = c_parser_objc_selector (parser);
12253 if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
12254 break;
12255 }
12256 return list;
12257 }
12258
12259 /* Parse an objc-keywordexpr.
12260
12261 objc-keywordexpr:
12262 nonempty-expr-list
12263 */
12264
12265 static tree
12266 c_parser_objc_keywordexpr (c_parser *parser)
12267 {
12268 tree ret;
12269 vec<tree, va_gc> *expr_list = c_parser_expr_list (parser, true, true,
12270 NULL, NULL, NULL, NULL);
12271 if (vec_safe_length (expr_list) == 1)
12272 {
12273 /* Just return the expression, remove a level of
12274 indirection. */
12275 ret = (*expr_list)[0];
12276 }
12277 else
12278 {
12279 /* We have a comma expression, we will collapse later. */
12280 ret = build_tree_list_vec (expr_list);
12281 }
12282 release_tree_vector (expr_list);
12283 return ret;
12284 }
12285
12286 /* A check, needed in several places, that ObjC interface, implementation or
12287 method definitions are not prefixed by incorrect items. */
12288 static bool
12289 c_parser_objc_diagnose_bad_element_prefix (c_parser *parser,
12290 struct c_declspecs *specs)
12291 {
12292 if (!specs->declspecs_seen_p || specs->non_sc_seen_p
12293 || specs->typespec_kind != ctsk_none)
12294 {
12295 c_parser_error (parser,
12296 "no type or storage class may be specified here,");
12297 c_parser_skip_to_end_of_block_or_statement (parser);
12298 return true;
12299 }
12300 return false;
12301 }
12302
12303 /* Parse an Objective-C @property declaration. The syntax is:
12304
12305 objc-property-declaration:
12306 '@property' objc-property-attributes[opt] struct-declaration ;
12307
12308 objc-property-attributes:
12309 '(' objc-property-attribute-list ')'
12310
12311 objc-property-attribute-list:
12312 objc-property-attribute
12313 objc-property-attribute-list, objc-property-attribute
12314
12315 objc-property-attribute
12316 'getter' = identifier
12317 'setter' = identifier
12318 'readonly'
12319 'readwrite'
12320 'assign'
12321 'retain'
12322 'copy'
12323 'nonatomic'
12324
12325 For example:
12326 @property NSString *name;
12327 @property (readonly) id object;
12328 @property (retain, nonatomic, getter=getTheName) id name;
12329 @property int a, b, c;
12330
12331 PS: This function is identical to cp_parser_objc_at_propery_declaration
12332 for C++. Keep them in sync. */
12333 static void
12334 c_parser_objc_at_property_declaration (c_parser *parser)
12335 {
12336 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY));
12337 location_t loc = c_parser_peek_token (parser)->location;
12338 c_parser_consume_token (parser); /* Eat '@property'. */
12339
12340 /* Parse the optional attribute list.
12341
12342 A list of parsed, but not verified, attributes. */
12343 vec<property_attribute_info *> prop_attr_list = vNULL;
12344
12345 bool syntax_error = false;
12346 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
12347 {
12348 matching_parens parens;
12349
12350 location_t attr_start = c_parser_peek_token (parser)->location;
12351 /* Eat the '(' */
12352 parens.consume_open (parser);
12353
12354 /* Property attribute keywords are valid now. */
12355 parser->objc_property_attr_context = true;
12356
12357 /* Allow @property (), with a warning. */
12358 location_t attr_end = c_parser_peek_token (parser)->location;
12359
12360 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
12361 {
12362 location_t attr_comb = make_location (attr_end, attr_start, attr_end);
12363 warning_at (attr_comb, OPT_Wattributes,
12364 "empty property attribute list");
12365 }
12366 else
12367 while (true)
12368 {
12369 c_token *token = c_parser_peek_token (parser);
12370 attr_start = token->location;
12371 attr_end = get_finish (token->location);
12372 location_t attr_comb = make_location (attr_start, attr_start,
12373 attr_end);
12374
12375 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_COMMA)
12376 {
12377 warning_at (attr_comb, OPT_Wattributes,
12378 "missing property attribute");
12379 if (token->type == CPP_CLOSE_PAREN)
12380 break;
12381 c_parser_consume_token (parser);
12382 continue;
12383 }
12384
12385 tree attr_name = NULL_TREE;
12386 enum rid keyword = RID_MAX; /* Not a valid property attribute. */
12387 bool add_at = false;
12388 if (token->type == CPP_KEYWORD)
12389 {
12390 keyword = token->keyword;
12391 if (OBJC_IS_AT_KEYWORD (keyword))
12392 {
12393 /* For '@' keywords the token value has the keyword,
12394 prepend the '@' for diagnostics. */
12395 attr_name = token->value;
12396 add_at = true;
12397 }
12398 else
12399 attr_name = ridpointers[(int)keyword];
12400 }
12401 else if (token->type == CPP_NAME)
12402 attr_name = token->value;
12403 c_parser_consume_token (parser);
12404
12405 enum objc_property_attribute_kind prop_kind
12406 = objc_prop_attr_kind_for_rid (keyword);
12407 property_attribute_info *prop
12408 = new property_attribute_info (attr_name, attr_comb, prop_kind);
12409 prop_attr_list.safe_push (prop);
12410
12411 tree meth_name;
12412 switch (prop->prop_kind)
12413 {
12414 default: break;
12415 case OBJC_PROPERTY_ATTR_UNKNOWN:
12416 if (attr_name)
12417 error_at (attr_comb, "unknown property attribute %<%s%s%>",
12418 add_at ? "@" : "", IDENTIFIER_POINTER (attr_name));
12419 else
12420 error_at (attr_comb, "unknown property attribute");
12421 prop->parse_error = syntax_error = true;
12422 break;
12423
12424 case OBJC_PROPERTY_ATTR_GETTER:
12425 case OBJC_PROPERTY_ATTR_SETTER:
12426 if (c_parser_next_token_is_not (parser, CPP_EQ))
12427 {
12428 attr_comb = make_location (attr_end, attr_start, attr_end);
12429 error_at (attr_comb, "expected %<=%> after Objective-C %qE",
12430 attr_name);
12431 prop->parse_error = syntax_error = true;
12432 break;
12433 }
12434 token = c_parser_peek_token (parser);
12435 attr_end = token->location;
12436 c_parser_consume_token (parser); /* eat the = */
12437 if (c_parser_next_token_is_not (parser, CPP_NAME))
12438 {
12439 attr_comb = make_location (attr_end, attr_start, attr_end);
12440 error_at (attr_comb, "expected %qE selector name",
12441 attr_name);
12442 prop->parse_error = syntax_error = true;
12443 break;
12444 }
12445 /* Get the end of the method name, and consume the name. */
12446 token = c_parser_peek_token (parser);
12447 attr_end = get_finish (token->location);
12448 meth_name = token->value;
12449 c_parser_consume_token (parser);
12450 if (prop->prop_kind == OBJC_PROPERTY_ATTR_SETTER)
12451 {
12452 if (c_parser_next_token_is_not (parser, CPP_COLON))
12453 {
12454 attr_comb = make_location (attr_end, attr_start,
12455 attr_end);
12456 error_at (attr_comb, "setter method names must"
12457 " terminate with %<:%>");
12458 prop->parse_error = syntax_error = true;
12459 }
12460 else
12461 {
12462 attr_end = get_finish (c_parser_peek_token
12463 (parser)->location);
12464 c_parser_consume_token (parser);
12465 }
12466 attr_comb = make_location (attr_start, attr_start,
12467 attr_end);
12468 }
12469 else
12470 attr_comb = make_location (attr_start, attr_start,
12471 attr_end);
12472 prop->ident = meth_name;
12473 /* Updated location including all that was successfully
12474 parsed. */
12475 prop->prop_loc = attr_comb;
12476 break;
12477 }
12478
12479 /* If we see a comma here, then keep going - even if we already
12480 saw a syntax error. For simple mistakes e.g. (asign, getter=x)
12481 this makes a more useful output and avoid spurious warnings about
12482 missing attributes that are, in fact, specified after the one with
12483 the syntax error. */
12484 if (c_parser_next_token_is (parser, CPP_COMMA))
12485 c_parser_consume_token (parser);
12486 else
12487 break;
12488 }
12489 parser->objc_property_attr_context = false;
12490
12491 if (syntax_error && c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
12492 /* We don't really want to chew the whole of the file looking for a
12493 matching closing parenthesis, so we will try to read the decl and
12494 let the error handling for that close out the statement. */
12495 ;
12496 else
12497 syntax_error = false, parens.skip_until_found_close (parser);
12498 }
12499
12500 /* 'properties' is the list of properties that we read. Usually a
12501 single one, but maybe more (eg, in "@property int a, b, c;" there
12502 are three). */
12503 tree properties = c_parser_struct_declaration (parser);
12504
12505 if (properties == error_mark_node)
12506 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12507 else
12508 {
12509 if (properties == NULL_TREE)
12510 c_parser_error (parser, "expected identifier");
12511 else
12512 {
12513 /* Comma-separated properties are chained together in reverse order;
12514 add them one by one. */
12515 properties = nreverse (properties);
12516 for (; properties; properties = TREE_CHAIN (properties))
12517 objc_add_property_declaration (loc, copy_node (properties),
12518 prop_attr_list);
12519 }
12520 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12521 }
12522
12523 while (!prop_attr_list.is_empty())
12524 delete prop_attr_list.pop ();
12525 prop_attr_list.release ();
12526 parser->error = false;
12527 }
12528
12529 /* Parse an Objective-C @synthesize declaration. The syntax is:
12530
12531 objc-synthesize-declaration:
12532 @synthesize objc-synthesize-identifier-list ;
12533
12534 objc-synthesize-identifier-list:
12535 objc-synthesize-identifier
12536 objc-synthesize-identifier-list, objc-synthesize-identifier
12537
12538 objc-synthesize-identifier
12539 identifier
12540 identifier = identifier
12541
12542 For example:
12543 @synthesize MyProperty;
12544 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
12545
12546 PS: This function is identical to cp_parser_objc_at_synthesize_declaration
12547 for C++. Keep them in sync.
12548 */
12549 static void
12550 c_parser_objc_at_synthesize_declaration (c_parser *parser)
12551 {
12552 tree list = NULL_TREE;
12553 location_t loc;
12554 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNTHESIZE));
12555 loc = c_parser_peek_token (parser)->location;
12556
12557 c_parser_consume_token (parser);
12558 while (true)
12559 {
12560 tree property, ivar;
12561 if (c_parser_next_token_is_not (parser, CPP_NAME))
12562 {
12563 c_parser_error (parser, "expected identifier");
12564 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12565 /* Once we find the semicolon, we can resume normal parsing.
12566 We have to reset parser->error manually because
12567 c_parser_skip_until_found() won't reset it for us if the
12568 next token is precisely a semicolon. */
12569 parser->error = false;
12570 return;
12571 }
12572 property = c_parser_peek_token (parser)->value;
12573 c_parser_consume_token (parser);
12574 if (c_parser_next_token_is (parser, CPP_EQ))
12575 {
12576 c_parser_consume_token (parser);
12577 if (c_parser_next_token_is_not (parser, CPP_NAME))
12578 {
12579 c_parser_error (parser, "expected identifier");
12580 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12581 parser->error = false;
12582 return;
12583 }
12584 ivar = c_parser_peek_token (parser)->value;
12585 c_parser_consume_token (parser);
12586 }
12587 else
12588 ivar = NULL_TREE;
12589 list = chainon (list, build_tree_list (ivar, property));
12590 if (c_parser_next_token_is (parser, CPP_COMMA))
12591 c_parser_consume_token (parser);
12592 else
12593 break;
12594 }
12595 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12596 objc_add_synthesize_declaration (loc, list);
12597 }
12598
12599 /* Parse an Objective-C @dynamic declaration. The syntax is:
12600
12601 objc-dynamic-declaration:
12602 @dynamic identifier-list ;
12603
12604 For example:
12605 @dynamic MyProperty;
12606 @dynamic MyProperty, AnotherProperty;
12607
12608 PS: This function is identical to cp_parser_objc_at_dynamic_declaration
12609 for C++. Keep them in sync.
12610 */
12611 static void
12612 c_parser_objc_at_dynamic_declaration (c_parser *parser)
12613 {
12614 tree list = NULL_TREE;
12615 location_t loc;
12616 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_DYNAMIC));
12617 loc = c_parser_peek_token (parser)->location;
12618
12619 c_parser_consume_token (parser);
12620 while (true)
12621 {
12622 tree property;
12623 if (c_parser_next_token_is_not (parser, CPP_NAME))
12624 {
12625 c_parser_error (parser, "expected identifier");
12626 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12627 parser->error = false;
12628 return;
12629 }
12630 property = c_parser_peek_token (parser)->value;
12631 list = chainon (list, build_tree_list (NULL_TREE, property));
12632 c_parser_consume_token (parser);
12633 if (c_parser_next_token_is (parser, CPP_COMMA))
12634 c_parser_consume_token (parser);
12635 else
12636 break;
12637 }
12638 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12639 objc_add_dynamic_declaration (loc, list);
12640 }
12641
12642 \f
12643 /* Parse a pragma GCC ivdep. */
12644
12645 static bool
12646 c_parse_pragma_ivdep (c_parser *parser)
12647 {
12648 c_parser_consume_pragma (parser);
12649 c_parser_skip_to_pragma_eol (parser);
12650 return true;
12651 }
12652
12653 /* Parse a pragma GCC unroll. */
12654
12655 static unsigned short
12656 c_parser_pragma_unroll (c_parser *parser)
12657 {
12658 unsigned short unroll;
12659 c_parser_consume_pragma (parser);
12660 location_t location = c_parser_peek_token (parser)->location;
12661 tree expr = c_parser_expr_no_commas (parser, NULL).value;
12662 mark_exp_read (expr);
12663 expr = c_fully_fold (expr, false, NULL);
12664 HOST_WIDE_INT lunroll = 0;
12665 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
12666 || TREE_CODE (expr) != INTEGER_CST
12667 || (lunroll = tree_to_shwi (expr)) < 0
12668 || lunroll >= USHRT_MAX)
12669 {
12670 error_at (location, "%<#pragma GCC unroll%> requires an"
12671 " assignment-expression that evaluates to a non-negative"
12672 " integral constant less than %u", USHRT_MAX);
12673 unroll = 0;
12674 }
12675 else
12676 {
12677 unroll = (unsigned short)lunroll;
12678 if (unroll == 0)
12679 unroll = 1;
12680 }
12681
12682 c_parser_skip_to_pragma_eol (parser);
12683 return unroll;
12684 }
12685
12686 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
12687 should be considered, statements. ALLOW_STMT is true if we're within
12688 the context of a function and such pragmas are to be allowed. Returns
12689 true if we actually parsed such a pragma. */
12690
12691 static bool
12692 c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p)
12693 {
12694 unsigned int id;
12695 const char *construct = NULL;
12696
12697 input_location = c_parser_peek_token (parser)->location;
12698 id = c_parser_peek_token (parser)->pragma_kind;
12699 gcc_assert (id != PRAGMA_NONE);
12700
12701 switch (id)
12702 {
12703 case PRAGMA_OACC_DECLARE:
12704 c_parser_oacc_declare (parser);
12705 return false;
12706
12707 case PRAGMA_OACC_ENTER_DATA:
12708 if (context != pragma_compound)
12709 {
12710 construct = "acc enter data";
12711 in_compound:
12712 if (context == pragma_stmt)
12713 {
12714 error_at (c_parser_peek_token (parser)->location,
12715 "%<#pragma %s%> may only be used in compound "
12716 "statements", construct);
12717 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12718 return true;
12719 }
12720 goto bad_stmt;
12721 }
12722 c_parser_oacc_enter_exit_data (parser, true);
12723 return false;
12724
12725 case PRAGMA_OACC_EXIT_DATA:
12726 if (context != pragma_compound)
12727 {
12728 construct = "acc exit data";
12729 goto in_compound;
12730 }
12731 c_parser_oacc_enter_exit_data (parser, false);
12732 return false;
12733
12734 case PRAGMA_OACC_ROUTINE:
12735 if (context != pragma_external)
12736 {
12737 error_at (c_parser_peek_token (parser)->location,
12738 "%<#pragma acc routine%> must be at file scope");
12739 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12740 return false;
12741 }
12742 c_parser_oacc_routine (parser, context);
12743 return false;
12744
12745 case PRAGMA_OACC_UPDATE:
12746 if (context != pragma_compound)
12747 {
12748 construct = "acc update";
12749 goto in_compound;
12750 }
12751 c_parser_oacc_update (parser);
12752 return false;
12753
12754 case PRAGMA_OMP_BARRIER:
12755 if (context != pragma_compound)
12756 {
12757 construct = "omp barrier";
12758 goto in_compound;
12759 }
12760 c_parser_omp_barrier (parser);
12761 return false;
12762
12763 case PRAGMA_OMP_DEPOBJ:
12764 if (context != pragma_compound)
12765 {
12766 construct = "omp depobj";
12767 goto in_compound;
12768 }
12769 c_parser_omp_depobj (parser);
12770 return false;
12771
12772 case PRAGMA_OMP_FLUSH:
12773 if (context != pragma_compound)
12774 {
12775 construct = "omp flush";
12776 goto in_compound;
12777 }
12778 c_parser_omp_flush (parser);
12779 return false;
12780
12781 case PRAGMA_OMP_TASKWAIT:
12782 if (context != pragma_compound)
12783 {
12784 construct = "omp taskwait";
12785 goto in_compound;
12786 }
12787 c_parser_omp_taskwait (parser);
12788 return false;
12789
12790 case PRAGMA_OMP_TASKYIELD:
12791 if (context != pragma_compound)
12792 {
12793 construct = "omp taskyield";
12794 goto in_compound;
12795 }
12796 c_parser_omp_taskyield (parser);
12797 return false;
12798
12799 case PRAGMA_OMP_CANCEL:
12800 if (context != pragma_compound)
12801 {
12802 construct = "omp cancel";
12803 goto in_compound;
12804 }
12805 c_parser_omp_cancel (parser);
12806 return false;
12807
12808 case PRAGMA_OMP_CANCELLATION_POINT:
12809 return c_parser_omp_cancellation_point (parser, context);
12810
12811 case PRAGMA_OMP_THREADPRIVATE:
12812 c_parser_omp_threadprivate (parser);
12813 return false;
12814
12815 case PRAGMA_OMP_TARGET:
12816 return c_parser_omp_target (parser, context, if_p);
12817
12818 case PRAGMA_OMP_BEGIN:
12819 c_parser_omp_begin (parser);
12820 return false;
12821
12822 case PRAGMA_OMP_END:
12823 c_parser_omp_end (parser);
12824 return false;
12825
12826 case PRAGMA_OMP_SCAN:
12827 error_at (c_parser_peek_token (parser)->location,
12828 "%<#pragma omp scan%> may only be used in "
12829 "a loop construct with %<inscan%> %<reduction%> clause");
12830 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12831 return false;
12832
12833 case PRAGMA_OMP_SECTION:
12834 error_at (c_parser_peek_token (parser)->location,
12835 "%<#pragma omp section%> may only be used in "
12836 "%<#pragma omp sections%> construct");
12837 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12838 return false;
12839
12840 case PRAGMA_OMP_DECLARE:
12841 return c_parser_omp_declare (parser, context);
12842
12843 case PRAGMA_OMP_REQUIRES:
12844 if (context != pragma_external)
12845 {
12846 error_at (c_parser_peek_token (parser)->location,
12847 "%<#pragma %s%> may only be used at file scope",
12848 "omp requires");
12849 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12850 return false;
12851 }
12852 c_parser_omp_requires (parser);
12853 return false;
12854
12855 case PRAGMA_OMP_ASSUMES:
12856 if (context != pragma_external)
12857 {
12858 error_at (c_parser_peek_token (parser)->location,
12859 "%<#pragma %s%> may only be used at file scope",
12860 "omp assumes");
12861 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12862 return false;
12863 }
12864 c_parser_omp_assumes (parser);
12865 return false;
12866
12867 case PRAGMA_OMP_NOTHING:
12868 c_parser_omp_nothing (parser);
12869 return false;
12870
12871 case PRAGMA_OMP_ERROR:
12872 return c_parser_omp_error (parser, context);
12873
12874 case PRAGMA_OMP_ORDERED:
12875 return c_parser_omp_ordered (parser, context, if_p);
12876
12877 case PRAGMA_IVDEP:
12878 {
12879 const bool ivdep = c_parse_pragma_ivdep (parser);
12880 unsigned short unroll;
12881 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_UNROLL)
12882 unroll = c_parser_pragma_unroll (parser);
12883 else
12884 unroll = 0;
12885 if (!c_parser_next_token_is_keyword (parser, RID_FOR)
12886 && !c_parser_next_token_is_keyword (parser, RID_WHILE)
12887 && !c_parser_next_token_is_keyword (parser, RID_DO))
12888 {
12889 c_parser_error (parser, "for, while or do statement expected");
12890 return false;
12891 }
12892 if (c_parser_next_token_is_keyword (parser, RID_FOR))
12893 c_parser_for_statement (parser, ivdep, unroll, if_p);
12894 else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
12895 c_parser_while_statement (parser, ivdep, unroll, if_p);
12896 else
12897 c_parser_do_statement (parser, ivdep, unroll);
12898 }
12899 return true;
12900
12901 case PRAGMA_UNROLL:
12902 {
12903 unsigned short unroll = c_parser_pragma_unroll (parser);
12904 bool ivdep;
12905 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_IVDEP)
12906 ivdep = c_parse_pragma_ivdep (parser);
12907 else
12908 ivdep = false;
12909 if (!c_parser_next_token_is_keyword (parser, RID_FOR)
12910 && !c_parser_next_token_is_keyword (parser, RID_WHILE)
12911 && !c_parser_next_token_is_keyword (parser, RID_DO))
12912 {
12913 c_parser_error (parser, "for, while or do statement expected");
12914 return false;
12915 }
12916 if (c_parser_next_token_is_keyword (parser, RID_FOR))
12917 c_parser_for_statement (parser, ivdep, unroll, if_p);
12918 else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
12919 c_parser_while_statement (parser, ivdep, unroll, if_p);
12920 else
12921 c_parser_do_statement (parser, ivdep, unroll);
12922 }
12923 return true;
12924
12925 case PRAGMA_GCC_PCH_PREPROCESS:
12926 c_parser_error (parser, "%<#pragma GCC pch_preprocess%> must be first");
12927 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12928 return false;
12929
12930 case PRAGMA_OACC_WAIT:
12931 if (context != pragma_compound)
12932 {
12933 construct = "acc wait";
12934 goto in_compound;
12935 }
12936 /* FALL THROUGH. */
12937
12938 default:
12939 if (id < PRAGMA_FIRST_EXTERNAL)
12940 {
12941 if (context != pragma_stmt && context != pragma_compound)
12942 {
12943 bad_stmt:
12944 c_parser_error (parser, "expected declaration specifiers");
12945 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12946 return false;
12947 }
12948 c_parser_omp_construct (parser, if_p);
12949 return true;
12950 }
12951 break;
12952 }
12953
12954 c_parser_consume_pragma (parser);
12955 c_invoke_pragma_handler (id);
12956
12957 /* Skip to EOL, but suppress any error message. Those will have been
12958 generated by the handler routine through calling error, as opposed
12959 to calling c_parser_error. */
12960 parser->error = true;
12961 c_parser_skip_to_pragma_eol (parser);
12962
12963 return false;
12964 }
12965
12966 /* The interface the pragma parsers have to the lexer. */
12967
12968 enum cpp_ttype
12969 pragma_lex (tree *value, location_t *loc)
12970 {
12971 c_token *tok = c_parser_peek_token (the_parser);
12972 enum cpp_ttype ret = tok->type;
12973
12974 *value = tok->value;
12975 if (loc)
12976 *loc = tok->location;
12977
12978 if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF)
12979 ret = CPP_EOF;
12980 else if (ret == CPP_STRING)
12981 *value = c_parser_string_literal (the_parser, false, false).value;
12982 else
12983 {
12984 if (ret == CPP_KEYWORD)
12985 ret = CPP_NAME;
12986 c_parser_consume_token (the_parser);
12987 }
12988
12989 return ret;
12990 }
12991
12992 static void
12993 c_parser_pragma_pch_preprocess (c_parser *parser)
12994 {
12995 tree name = NULL;
12996
12997 parser->lex_joined_string = true;
12998 c_parser_consume_pragma (parser);
12999 if (c_parser_next_token_is (parser, CPP_STRING))
13000 {
13001 name = c_parser_peek_token (parser)->value;
13002 c_parser_consume_token (parser);
13003 }
13004 else
13005 c_parser_error (parser, "expected string literal");
13006 c_parser_skip_to_pragma_eol (parser);
13007 parser->lex_joined_string = false;
13008
13009 if (name)
13010 c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name));
13011 }
13012 \f
13013 /* OpenACC and OpenMP parsing routines. */
13014
13015 /* Returns name of the next clause.
13016 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
13017 the token is not consumed. Otherwise appropriate pragma_omp_clause is
13018 returned and the token is consumed. */
13019
13020 static pragma_omp_clause
13021 c_parser_omp_clause_name (c_parser *parser)
13022 {
13023 pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;
13024
13025 if (c_parser_next_token_is_keyword (parser, RID_AUTO))
13026 result = PRAGMA_OACC_CLAUSE_AUTO;
13027 else if (c_parser_next_token_is_keyword (parser, RID_IF))
13028 result = PRAGMA_OMP_CLAUSE_IF;
13029 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
13030 result = PRAGMA_OMP_CLAUSE_DEFAULT;
13031 else if (c_parser_next_token_is_keyword (parser, RID_FOR))
13032 result = PRAGMA_OMP_CLAUSE_FOR;
13033 else if (c_parser_next_token_is (parser, CPP_NAME))
13034 {
13035 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13036
13037 switch (p[0])
13038 {
13039 case 'a':
13040 if (!strcmp ("affinity", p))
13041 result = PRAGMA_OMP_CLAUSE_AFFINITY;
13042 else if (!strcmp ("aligned", p))
13043 result = PRAGMA_OMP_CLAUSE_ALIGNED;
13044 else if (!strcmp ("allocate", p))
13045 result = PRAGMA_OMP_CLAUSE_ALLOCATE;
13046 else if (!strcmp ("async", p))
13047 result = PRAGMA_OACC_CLAUSE_ASYNC;
13048 else if (!strcmp ("attach", p))
13049 result = PRAGMA_OACC_CLAUSE_ATTACH;
13050 break;
13051 case 'b':
13052 if (!strcmp ("bind", p))
13053 result = PRAGMA_OMP_CLAUSE_BIND;
13054 break;
13055 case 'c':
13056 if (!strcmp ("collapse", p))
13057 result = PRAGMA_OMP_CLAUSE_COLLAPSE;
13058 else if (!strcmp ("copy", p))
13059 result = PRAGMA_OACC_CLAUSE_COPY;
13060 else if (!strcmp ("copyin", p))
13061 result = PRAGMA_OMP_CLAUSE_COPYIN;
13062 else if (!strcmp ("copyout", p))
13063 result = PRAGMA_OACC_CLAUSE_COPYOUT;
13064 else if (!strcmp ("copyprivate", p))
13065 result = PRAGMA_OMP_CLAUSE_COPYPRIVATE;
13066 else if (!strcmp ("create", p))
13067 result = PRAGMA_OACC_CLAUSE_CREATE;
13068 break;
13069 case 'd':
13070 if (!strcmp ("defaultmap", p))
13071 result = PRAGMA_OMP_CLAUSE_DEFAULTMAP;
13072 else if (!strcmp ("delete", p))
13073 result = PRAGMA_OACC_CLAUSE_DELETE;
13074 else if (!strcmp ("depend", p))
13075 result = PRAGMA_OMP_CLAUSE_DEPEND;
13076 else if (!strcmp ("detach", p))
13077 result = PRAGMA_OACC_CLAUSE_DETACH;
13078 else if (!strcmp ("device", p))
13079 result = PRAGMA_OMP_CLAUSE_DEVICE;
13080 else if (!strcmp ("deviceptr", p))
13081 result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
13082 else if (!strcmp ("device_resident", p))
13083 result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
13084 else if (!strcmp ("device_type", p))
13085 result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
13086 else if (!strcmp ("dist_schedule", p))
13087 result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
13088 else if (!strcmp ("doacross", p))
13089 result = PRAGMA_OMP_CLAUSE_DOACROSS;
13090 break;
13091 case 'e':
13092 if (!strcmp ("enter", p))
13093 result = PRAGMA_OMP_CLAUSE_ENTER;
13094 break;
13095 case 'f':
13096 if (!strcmp ("filter", p))
13097 result = PRAGMA_OMP_CLAUSE_FILTER;
13098 else if (!strcmp ("final", p))
13099 result = PRAGMA_OMP_CLAUSE_FINAL;
13100 else if (!strcmp ("finalize", p))
13101 result = PRAGMA_OACC_CLAUSE_FINALIZE;
13102 else if (!strcmp ("firstprivate", p))
13103 result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
13104 else if (!strcmp ("from", p))
13105 result = PRAGMA_OMP_CLAUSE_FROM;
13106 break;
13107 case 'g':
13108 if (!strcmp ("gang", p))
13109 result = PRAGMA_OACC_CLAUSE_GANG;
13110 else if (!strcmp ("grainsize", p))
13111 result = PRAGMA_OMP_CLAUSE_GRAINSIZE;
13112 break;
13113 case 'h':
13114 if (!strcmp ("has_device_addr", p))
13115 result = PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR;
13116 else if (!strcmp ("hint", p))
13117 result = PRAGMA_OMP_CLAUSE_HINT;
13118 else if (!strcmp ("host", p))
13119 result = PRAGMA_OACC_CLAUSE_HOST;
13120 break;
13121 case 'i':
13122 if (!strcmp ("if_present", p))
13123 result = PRAGMA_OACC_CLAUSE_IF_PRESENT;
13124 else if (!strcmp ("in_reduction", p))
13125 result = PRAGMA_OMP_CLAUSE_IN_REDUCTION;
13126 else if (!strcmp ("inbranch", p))
13127 result = PRAGMA_OMP_CLAUSE_INBRANCH;
13128 else if (!strcmp ("independent", p))
13129 result = PRAGMA_OACC_CLAUSE_INDEPENDENT;
13130 else if (!strcmp ("is_device_ptr", p))
13131 result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR;
13132 break;
13133 case 'l':
13134 if (!strcmp ("lastprivate", p))
13135 result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
13136 else if (!strcmp ("linear", p))
13137 result = PRAGMA_OMP_CLAUSE_LINEAR;
13138 else if (!strcmp ("link", p))
13139 result = PRAGMA_OMP_CLAUSE_LINK;
13140 break;
13141 case 'm':
13142 if (!strcmp ("map", p))
13143 result = PRAGMA_OMP_CLAUSE_MAP;
13144 else if (!strcmp ("mergeable", p))
13145 result = PRAGMA_OMP_CLAUSE_MERGEABLE;
13146 break;
13147 case 'n':
13148 if (!strcmp ("no_create", p))
13149 result = PRAGMA_OACC_CLAUSE_NO_CREATE;
13150 else if (!strcmp ("nogroup", p))
13151 result = PRAGMA_OMP_CLAUSE_NOGROUP;
13152 else if (!strcmp ("nohost", p))
13153 result = PRAGMA_OACC_CLAUSE_NOHOST;
13154 else if (!strcmp ("nontemporal", p))
13155 result = PRAGMA_OMP_CLAUSE_NONTEMPORAL;
13156 else if (!strcmp ("notinbranch", p))
13157 result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
13158 else if (!strcmp ("nowait", p))
13159 result = PRAGMA_OMP_CLAUSE_NOWAIT;
13160 else if (!strcmp ("num_gangs", p))
13161 result = PRAGMA_OACC_CLAUSE_NUM_GANGS;
13162 else if (!strcmp ("num_tasks", p))
13163 result = PRAGMA_OMP_CLAUSE_NUM_TASKS;
13164 else if (!strcmp ("num_teams", p))
13165 result = PRAGMA_OMP_CLAUSE_NUM_TEAMS;
13166 else if (!strcmp ("num_threads", p))
13167 result = PRAGMA_OMP_CLAUSE_NUM_THREADS;
13168 else if (!strcmp ("num_workers", p))
13169 result = PRAGMA_OACC_CLAUSE_NUM_WORKERS;
13170 break;
13171 case 'o':
13172 if (!strcmp ("ordered", p))
13173 result = PRAGMA_OMP_CLAUSE_ORDERED;
13174 else if (!strcmp ("order", p))
13175 result = PRAGMA_OMP_CLAUSE_ORDER;
13176 break;
13177 case 'p':
13178 if (!strcmp ("parallel", p))
13179 result = PRAGMA_OMP_CLAUSE_PARALLEL;
13180 else if (!strcmp ("present", p))
13181 result = PRAGMA_OACC_CLAUSE_PRESENT;
13182 /* As of OpenACC 2.5, these are now aliases of the non-present_or
13183 clauses. */
13184 else if (!strcmp ("present_or_copy", p)
13185 || !strcmp ("pcopy", p))
13186 result = PRAGMA_OACC_CLAUSE_COPY;
13187 else if (!strcmp ("present_or_copyin", p)
13188 || !strcmp ("pcopyin", p))
13189 result = PRAGMA_OACC_CLAUSE_COPYIN;
13190 else if (!strcmp ("present_or_copyout", p)
13191 || !strcmp ("pcopyout", p))
13192 result = PRAGMA_OACC_CLAUSE_COPYOUT;
13193 else if (!strcmp ("present_or_create", p)
13194 || !strcmp ("pcreate", p))
13195 result = PRAGMA_OACC_CLAUSE_CREATE;
13196 else if (!strcmp ("priority", p))
13197 result = PRAGMA_OMP_CLAUSE_PRIORITY;
13198 else if (!strcmp ("private", p))
13199 result = PRAGMA_OMP_CLAUSE_PRIVATE;
13200 else if (!strcmp ("proc_bind", p))
13201 result = PRAGMA_OMP_CLAUSE_PROC_BIND;
13202 break;
13203 case 'r':
13204 if (!strcmp ("reduction", p))
13205 result = PRAGMA_OMP_CLAUSE_REDUCTION;
13206 break;
13207 case 's':
13208 if (!strcmp ("safelen", p))
13209 result = PRAGMA_OMP_CLAUSE_SAFELEN;
13210 else if (!strcmp ("schedule", p))
13211 result = PRAGMA_OMP_CLAUSE_SCHEDULE;
13212 else if (!strcmp ("sections", p))
13213 result = PRAGMA_OMP_CLAUSE_SECTIONS;
13214 else if (!strcmp ("self", p)) /* "self" is a synonym for "host". */
13215 result = PRAGMA_OACC_CLAUSE_HOST;
13216 else if (!strcmp ("seq", p))
13217 result = PRAGMA_OACC_CLAUSE_SEQ;
13218 else if (!strcmp ("shared", p))
13219 result = PRAGMA_OMP_CLAUSE_SHARED;
13220 else if (!strcmp ("simd", p))
13221 result = PRAGMA_OMP_CLAUSE_SIMD;
13222 else if (!strcmp ("simdlen", p))
13223 result = PRAGMA_OMP_CLAUSE_SIMDLEN;
13224 break;
13225 case 't':
13226 if (!strcmp ("task_reduction", p))
13227 result = PRAGMA_OMP_CLAUSE_TASK_REDUCTION;
13228 else if (!strcmp ("taskgroup", p))
13229 result = PRAGMA_OMP_CLAUSE_TASKGROUP;
13230 else if (!strcmp ("thread_limit", p))
13231 result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT;
13232 else if (!strcmp ("threads", p))
13233 result = PRAGMA_OMP_CLAUSE_THREADS;
13234 else if (!strcmp ("tile", p))
13235 result = PRAGMA_OACC_CLAUSE_TILE;
13236 else if (!strcmp ("to", p))
13237 result = PRAGMA_OMP_CLAUSE_TO;
13238 break;
13239 case 'u':
13240 if (!strcmp ("uniform", p))
13241 result = PRAGMA_OMP_CLAUSE_UNIFORM;
13242 else if (!strcmp ("untied", p))
13243 result = PRAGMA_OMP_CLAUSE_UNTIED;
13244 else if (!strcmp ("use_device", p))
13245 result = PRAGMA_OACC_CLAUSE_USE_DEVICE;
13246 else if (!strcmp ("use_device_addr", p))
13247 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR;
13248 else if (!strcmp ("use_device_ptr", p))
13249 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR;
13250 break;
13251 case 'v':
13252 if (!strcmp ("vector", p))
13253 result = PRAGMA_OACC_CLAUSE_VECTOR;
13254 else if (!strcmp ("vector_length", p))
13255 result = PRAGMA_OACC_CLAUSE_VECTOR_LENGTH;
13256 break;
13257 case 'w':
13258 if (!strcmp ("wait", p))
13259 result = PRAGMA_OACC_CLAUSE_WAIT;
13260 else if (!strcmp ("worker", p))
13261 result = PRAGMA_OACC_CLAUSE_WORKER;
13262 break;
13263 }
13264 }
13265
13266 if (result != PRAGMA_OMP_CLAUSE_NONE)
13267 c_parser_consume_token (parser);
13268
13269 return result;
13270 }
13271
13272 /* Validate that a clause of the given type does not already exist. */
13273
13274 static void
13275 check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
13276 const char *name)
13277 {
13278 if (tree c = omp_find_clause (clauses, code))
13279 error_at (OMP_CLAUSE_LOCATION (c), "too many %qs clauses", name);
13280 }
13281
13282 /* OpenACC 2.0
13283 Parse wait clause or wait directive parameters. */
13284
13285 static tree
13286 c_parser_oacc_wait_list (c_parser *parser, location_t clause_loc, tree list)
13287 {
13288 vec<tree, va_gc> *args;
13289 tree t, args_tree;
13290
13291 matching_parens parens;
13292 if (!parens.require_open (parser))
13293 return list;
13294
13295 args = c_parser_expr_list (parser, false, true, NULL, NULL, NULL, NULL);
13296 args_tree = build_tree_list_vec (args);
13297
13298 for (t = args_tree; t; t = TREE_CHAIN (t))
13299 {
13300 tree targ = TREE_VALUE (t);
13301
13302 if (targ != error_mark_node)
13303 {
13304 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ)))
13305 {
13306 c_parser_error (parser, "expression must be integral");
13307 targ = error_mark_node;
13308 }
13309 else
13310 {
13311 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
13312
13313 OMP_CLAUSE_DECL (c) = targ;
13314 OMP_CLAUSE_CHAIN (c) = list;
13315 list = c;
13316 }
13317 }
13318 }
13319
13320 release_tree_vector (args);
13321 parens.require_close (parser);
13322 return list;
13323 }
13324
13325 /* OpenACC 2.0, OpenMP 2.5:
13326 variable-list:
13327 identifier
13328 variable-list , identifier
13329
13330 If KIND is nonzero, create the appropriate node and install the
13331 decl in OMP_CLAUSE_DECL and add the node to the head of the list.
13332 If KIND is nonzero, CLAUSE_LOC is the location of the clause.
13333
13334 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
13335 return the list created.
13336
13337 The optional ALLOW_DEREF argument is true if list items can use the deref
13338 (->) operator. */
13339
13340 struct omp_dim
13341 {
13342 tree low_bound, length;
13343 location_t loc;
13344 bool no_colon;
13345 omp_dim (tree lb, tree len, location_t lo, bool nc)
13346 : low_bound (lb), length (len), loc (lo), no_colon (nc) {}
13347 };
13348
13349 static tree
13350 c_parser_omp_variable_list (c_parser *parser,
13351 location_t clause_loc,
13352 enum omp_clause_code kind, tree list,
13353 bool allow_deref = false)
13354 {
13355 auto_vec<omp_dim> dims;
13356 bool array_section_p;
13357 auto_vec<c_token> tokens;
13358 unsigned int tokens_avail = 0;
13359 bool first = true;
13360
13361 while (1)
13362 {
13363 if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
13364 {
13365 if (c_parser_next_token_is_not (parser, CPP_NAME)
13366 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
13367 {
13368 struct c_expr expr;
13369 if (kind == OMP_CLAUSE_DEPEND
13370 && c_parser_next_token_is_keyword (parser,
13371 RID_OMP_ALL_MEMORY)
13372 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
13373 || (c_parser_peek_2nd_token (parser)->type
13374 == CPP_CLOSE_PAREN)))
13375 {
13376 expr.value = ridpointers[RID_OMP_ALL_MEMORY];
13377 c_parser_consume_token (parser);
13378 }
13379 else
13380 expr = c_parser_expr_no_commas (parser, NULL);
13381 if (expr.value != error_mark_node)
13382 {
13383 tree u = build_omp_clause (clause_loc, kind);
13384 OMP_CLAUSE_DECL (u) = expr.value;
13385 OMP_CLAUSE_CHAIN (u) = list;
13386 list = u;
13387 }
13388
13389 if (c_parser_next_token_is_not (parser, CPP_COMMA))
13390 break;
13391
13392 c_parser_consume_token (parser);
13393 first = false;
13394 continue;
13395 }
13396
13397 tokens.truncate (0);
13398 unsigned int nesting_depth = 0;
13399 while (1)
13400 {
13401 c_token *token = c_parser_peek_token (parser);
13402 switch (token->type)
13403 {
13404 case CPP_EOF:
13405 case CPP_PRAGMA_EOL:
13406 break;
13407 case CPP_OPEN_BRACE:
13408 case CPP_OPEN_PAREN:
13409 case CPP_OPEN_SQUARE:
13410 ++nesting_depth;
13411 goto add;
13412 case CPP_CLOSE_BRACE:
13413 case CPP_CLOSE_PAREN:
13414 case CPP_CLOSE_SQUARE:
13415 if (nesting_depth-- == 0)
13416 break;
13417 goto add;
13418 case CPP_COMMA:
13419 if (nesting_depth == 0)
13420 break;
13421 goto add;
13422 default:
13423 add:
13424 tokens.safe_push (*token);
13425 c_parser_consume_token (parser);
13426 continue;
13427 }
13428 break;
13429 }
13430
13431 /* Make sure nothing tries to read past the end of the tokens. */
13432 c_token eof_token;
13433 memset (&eof_token, 0, sizeof (eof_token));
13434 eof_token.type = CPP_EOF;
13435 tokens.safe_push (eof_token);
13436 tokens.safe_push (eof_token);
13437
13438 tokens_avail = parser->tokens_avail;
13439 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
13440 parser->tokens = tokens.address ();
13441 parser->tokens_avail = tokens.length ();
13442 }
13443
13444 tree t = NULL_TREE;
13445
13446 if (c_parser_next_token_is (parser, CPP_NAME)
13447 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
13448 {
13449 t = lookup_name (c_parser_peek_token (parser)->value);
13450
13451 if (t == NULL_TREE)
13452 {
13453 undeclared_variable (c_parser_peek_token (parser)->location,
13454 c_parser_peek_token (parser)->value);
13455 t = error_mark_node;
13456 }
13457
13458 c_parser_consume_token (parser);
13459 }
13460 else if (c_parser_next_token_is (parser, CPP_KEYWORD)
13461 && (c_parser_peek_token (parser)->keyword == RID_FUNCTION_NAME
13462 || (c_parser_peek_token (parser)->keyword
13463 == RID_PRETTY_FUNCTION_NAME)
13464 || (c_parser_peek_token (parser)->keyword
13465 == RID_C99_FUNCTION_NAME)))
13466 t = c_parser_predefined_identifier (parser).value;
13467 else
13468 {
13469 if (first)
13470 c_parser_error (parser, "expected identifier");
13471 break;
13472 }
13473
13474 if (t == error_mark_node)
13475 ;
13476 else if (kind != 0)
13477 {
13478 switch (kind)
13479 {
13480 case OMP_CLAUSE__CACHE_:
13481 /* The OpenACC cache directive explicitly only allows "array
13482 elements or subarrays". */
13483 if (c_parser_peek_token (parser)->type != CPP_OPEN_SQUARE)
13484 {
13485 c_parser_error (parser, "expected %<[%>");
13486 t = error_mark_node;
13487 break;
13488 }
13489 /* FALLTHROUGH */
13490 case OMP_CLAUSE_MAP:
13491 case OMP_CLAUSE_FROM:
13492 case OMP_CLAUSE_TO:
13493 start_component_ref:
13494 while (c_parser_next_token_is (parser, CPP_DOT)
13495 || (allow_deref
13496 && c_parser_next_token_is (parser, CPP_DEREF)))
13497 {
13498 location_t op_loc = c_parser_peek_token (parser)->location;
13499 location_t arrow_loc = UNKNOWN_LOCATION;
13500 if (c_parser_next_token_is (parser, CPP_DEREF))
13501 {
13502 c_expr t_expr;
13503 t_expr.value = t;
13504 t_expr.original_code = ERROR_MARK;
13505 t_expr.original_type = NULL;
13506 set_c_expr_source_range (&t_expr, op_loc, op_loc);
13507 t_expr.m_decimal = 0;
13508 t_expr = convert_lvalue_to_rvalue (op_loc, t_expr,
13509 true, false);
13510 t = build_indirect_ref (op_loc, t_expr.value, RO_ARROW);
13511 arrow_loc = t_expr.get_location ();
13512 }
13513 c_parser_consume_token (parser);
13514 if (!c_parser_next_token_is (parser, CPP_NAME))
13515 {
13516 c_parser_error (parser, "expected identifier");
13517 t = error_mark_node;
13518 break;
13519 }
13520
13521 c_token *comp_tok = c_parser_peek_token (parser);
13522 tree ident = comp_tok->value;
13523 location_t comp_loc = comp_tok->location;
13524 c_parser_consume_token (parser);
13525 t = build_component_ref (op_loc, t, ident, comp_loc,
13526 arrow_loc);
13527 }
13528 /* FALLTHROUGH */
13529 case OMP_CLAUSE_AFFINITY:
13530 case OMP_CLAUSE_DEPEND:
13531 case OMP_CLAUSE_REDUCTION:
13532 case OMP_CLAUSE_IN_REDUCTION:
13533 case OMP_CLAUSE_TASK_REDUCTION:
13534 case OMP_CLAUSE_HAS_DEVICE_ADDR:
13535 array_section_p = false;
13536 dims.truncate (0);
13537 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
13538 {
13539 location_t loc = UNKNOWN_LOCATION;
13540 tree low_bound = NULL_TREE, length = NULL_TREE;
13541 bool no_colon = false;
13542
13543 c_parser_consume_token (parser);
13544 if (!c_parser_next_token_is (parser, CPP_COLON))
13545 {
13546 location_t expr_loc
13547 = c_parser_peek_token (parser)->location;
13548 c_expr expr = c_parser_expression (parser);
13549 expr = convert_lvalue_to_rvalue (expr_loc, expr,
13550 false, true);
13551 low_bound = expr.value;
13552 loc = expr_loc;
13553 }
13554 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
13555 {
13556 length = integer_one_node;
13557 no_colon = true;
13558 }
13559 else
13560 {
13561 /* Look for `:'. */
13562 if (!c_parser_require (parser, CPP_COLON,
13563 "expected %<:%>"))
13564 {
13565 t = error_mark_node;
13566 break;
13567 }
13568 array_section_p = true;
13569 if (!c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
13570 {
13571 location_t expr_loc
13572 = c_parser_peek_token (parser)->location;
13573 c_expr expr = c_parser_expression (parser);
13574 expr = convert_lvalue_to_rvalue (expr_loc, expr,
13575 false, true);
13576 length = expr.value;
13577 }
13578 }
13579 /* Look for the closing `]'. */
13580 if (!c_parser_require (parser, CPP_CLOSE_SQUARE,
13581 "expected %<]%>"))
13582 {
13583 t = error_mark_node;
13584 break;
13585 }
13586
13587 dims.safe_push (omp_dim (low_bound, length, loc, no_colon));
13588 }
13589
13590 if (t != error_mark_node)
13591 {
13592 if ((kind == OMP_CLAUSE_MAP
13593 || kind == OMP_CLAUSE_FROM
13594 || kind == OMP_CLAUSE_TO)
13595 && !array_section_p
13596 && (c_parser_next_token_is (parser, CPP_DOT)
13597 || (allow_deref
13598 && c_parser_next_token_is (parser,
13599 CPP_DEREF))))
13600 {
13601 for (unsigned i = 0; i < dims.length (); i++)
13602 {
13603 gcc_assert (dims[i].length == integer_one_node);
13604 t = build_array_ref (dims[i].loc,
13605 t, dims[i].low_bound);
13606 }
13607 goto start_component_ref;
13608 }
13609 else
13610 for (unsigned i = 0; i < dims.length (); i++)
13611 t = tree_cons (dims[i].low_bound, dims[i].length, t);
13612 }
13613
13614 if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
13615 && t != error_mark_node
13616 && parser->tokens_avail != 2)
13617 {
13618 if (array_section_p)
13619 {
13620 error_at (c_parser_peek_token (parser)->location,
13621 "expected %<)%> or %<,%>");
13622 t = error_mark_node;
13623 }
13624 else
13625 {
13626 parser->tokens = tokens.address ();
13627 parser->tokens_avail = tokens.length ();
13628
13629 t = c_parser_expr_no_commas (parser, NULL).value;
13630 if (t != error_mark_node && parser->tokens_avail != 2)
13631 {
13632 error_at (c_parser_peek_token (parser)->location,
13633 "expected %<)%> or %<,%>");
13634 t = error_mark_node;
13635 }
13636 }
13637 }
13638 break;
13639 default:
13640 break;
13641 }
13642
13643 if (t != error_mark_node)
13644 {
13645 tree u = build_omp_clause (clause_loc, kind);
13646 OMP_CLAUSE_DECL (u) = t;
13647 OMP_CLAUSE_CHAIN (u) = list;
13648 list = u;
13649 }
13650 }
13651 else
13652 list = tree_cons (t, NULL_TREE, list);
13653
13654 if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
13655 {
13656 parser->tokens = &parser->tokens_buf[0];
13657 parser->tokens_avail = tokens_avail;
13658 }
13659 if (c_parser_next_token_is_not (parser, CPP_COMMA))
13660 break;
13661
13662 c_parser_consume_token (parser);
13663 first = false;
13664 }
13665
13666 return list;
13667 }
13668
13669 /* Similarly, but expect leading and trailing parenthesis. This is a very
13670 common case for OpenACC and OpenMP clauses. The optional ALLOW_DEREF
13671 argument is true if list items can use the deref (->) operator. */
13672
13673 static tree
13674 c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind,
13675 tree list, bool allow_deref = false)
13676 {
13677 /* The clauses location. */
13678 location_t loc = c_parser_peek_token (parser)->location;
13679
13680 matching_parens parens;
13681 if (parens.require_open (parser))
13682 {
13683 list = c_parser_omp_variable_list (parser, loc, kind, list, allow_deref);
13684 parens.skip_until_found_close (parser);
13685 }
13686 return list;
13687 }
13688
13689 /* OpenACC 2.0:
13690 copy ( variable-list )
13691 copyin ( variable-list )
13692 copyout ( variable-list )
13693 create ( variable-list )
13694 delete ( variable-list )
13695 present ( variable-list )
13696
13697 OpenACC 2.6:
13698 no_create ( variable-list )
13699 attach ( variable-list )
13700 detach ( variable-list ) */
13701
13702 static tree
13703 c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind,
13704 tree list)
13705 {
13706 enum gomp_map_kind kind;
13707 switch (c_kind)
13708 {
13709 case PRAGMA_OACC_CLAUSE_ATTACH:
13710 kind = GOMP_MAP_ATTACH;
13711 break;
13712 case PRAGMA_OACC_CLAUSE_COPY:
13713 kind = GOMP_MAP_TOFROM;
13714 break;
13715 case PRAGMA_OACC_CLAUSE_COPYIN:
13716 kind = GOMP_MAP_TO;
13717 break;
13718 case PRAGMA_OACC_CLAUSE_COPYOUT:
13719 kind = GOMP_MAP_FROM;
13720 break;
13721 case PRAGMA_OACC_CLAUSE_CREATE:
13722 kind = GOMP_MAP_ALLOC;
13723 break;
13724 case PRAGMA_OACC_CLAUSE_DELETE:
13725 kind = GOMP_MAP_RELEASE;
13726 break;
13727 case PRAGMA_OACC_CLAUSE_DETACH:
13728 kind = GOMP_MAP_DETACH;
13729 break;
13730 case PRAGMA_OACC_CLAUSE_DEVICE:
13731 kind = GOMP_MAP_FORCE_TO;
13732 break;
13733 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
13734 kind = GOMP_MAP_DEVICE_RESIDENT;
13735 break;
13736 case PRAGMA_OACC_CLAUSE_HOST:
13737 kind = GOMP_MAP_FORCE_FROM;
13738 break;
13739 case PRAGMA_OACC_CLAUSE_LINK:
13740 kind = GOMP_MAP_LINK;
13741 break;
13742 case PRAGMA_OACC_CLAUSE_NO_CREATE:
13743 kind = GOMP_MAP_IF_PRESENT;
13744 break;
13745 case PRAGMA_OACC_CLAUSE_PRESENT:
13746 kind = GOMP_MAP_FORCE_PRESENT;
13747 break;
13748 default:
13749 gcc_unreachable ();
13750 }
13751 tree nl, c;
13752 nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_MAP, list, true);
13753
13754 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
13755 OMP_CLAUSE_SET_MAP_KIND (c, kind);
13756
13757 return nl;
13758 }
13759
13760 /* OpenACC 2.0:
13761 deviceptr ( variable-list ) */
13762
13763 static tree
13764 c_parser_oacc_data_clause_deviceptr (c_parser *parser, tree list)
13765 {
13766 location_t loc = c_parser_peek_token (parser)->location;
13767 tree vars, t;
13768
13769 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
13770 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
13771 variable-list must only allow for pointer variables. */
13772 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
13773 for (t = vars; t && t; t = TREE_CHAIN (t))
13774 {
13775 tree v = TREE_PURPOSE (t);
13776
13777 /* FIXME diagnostics: Ideally we should keep individual
13778 locations for all the variables in the var list to make the
13779 following errors more precise. Perhaps
13780 c_parser_omp_var_list_parens() should construct a list of
13781 locations to go along with the var list. */
13782
13783 if (!VAR_P (v) && TREE_CODE (v) != PARM_DECL)
13784 error_at (loc, "%qD is not a variable", v);
13785 else if (TREE_TYPE (v) == error_mark_node)
13786 ;
13787 else if (!POINTER_TYPE_P (TREE_TYPE (v)))
13788 error_at (loc, "%qD is not a pointer variable", v);
13789
13790 tree u = build_omp_clause (loc, OMP_CLAUSE_MAP);
13791 OMP_CLAUSE_SET_MAP_KIND (u, GOMP_MAP_FORCE_DEVICEPTR);
13792 OMP_CLAUSE_DECL (u) = v;
13793 OMP_CLAUSE_CHAIN (u) = list;
13794 list = u;
13795 }
13796
13797 return list;
13798 }
13799
13800 /* OpenACC 2.0, OpenMP 3.0:
13801 collapse ( constant-expression ) */
13802
13803 static tree
13804 c_parser_omp_clause_collapse (c_parser *parser, tree list)
13805 {
13806 tree c, num = error_mark_node;
13807 HOST_WIDE_INT n;
13808 location_t loc;
13809
13810 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
13811 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
13812
13813 loc = c_parser_peek_token (parser)->location;
13814 matching_parens parens;
13815 if (parens.require_open (parser))
13816 {
13817 num = c_parser_expr_no_commas (parser, NULL).value;
13818 parens.skip_until_found_close (parser);
13819 }
13820 if (num == error_mark_node)
13821 return list;
13822 mark_exp_read (num);
13823 num = c_fully_fold (num, false, NULL);
13824 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
13825 || !tree_fits_shwi_p (num)
13826 || (n = tree_to_shwi (num)) <= 0
13827 || (int) n != n)
13828 {
13829 error_at (loc,
13830 "collapse argument needs positive constant integer expression");
13831 return list;
13832 }
13833 c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE);
13834 OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
13835 OMP_CLAUSE_CHAIN (c) = list;
13836 return c;
13837 }
13838
13839 /* OpenMP 2.5:
13840 copyin ( variable-list ) */
13841
13842 static tree
13843 c_parser_omp_clause_copyin (c_parser *parser, tree list)
13844 {
13845 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYIN, list);
13846 }
13847
13848 /* OpenMP 2.5:
13849 copyprivate ( variable-list ) */
13850
13851 static tree
13852 c_parser_omp_clause_copyprivate (c_parser *parser, tree list)
13853 {
13854 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYPRIVATE, list);
13855 }
13856
13857 /* OpenMP 2.5:
13858 default ( none | shared )
13859
13860 OpenMP 5.1:
13861 default ( private | firstprivate )
13862
13863 OpenACC:
13864 default ( none | present ) */
13865
13866 static tree
13867 c_parser_omp_clause_default (c_parser *parser, tree list, bool is_oacc)
13868 {
13869 enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
13870 location_t loc = c_parser_peek_token (parser)->location;
13871 tree c;
13872
13873 matching_parens parens;
13874 if (!parens.require_open (parser))
13875 return list;
13876 if (c_parser_next_token_is (parser, CPP_NAME))
13877 {
13878 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13879
13880 switch (p[0])
13881 {
13882 case 'n':
13883 if (strcmp ("none", p) != 0)
13884 goto invalid_kind;
13885 kind = OMP_CLAUSE_DEFAULT_NONE;
13886 break;
13887
13888 case 'p':
13889 if (is_oacc)
13890 {
13891 if (strcmp ("present", p) != 0)
13892 goto invalid_kind;
13893 kind = OMP_CLAUSE_DEFAULT_PRESENT;
13894 }
13895 else
13896 {
13897 if (strcmp ("private", p) != 0)
13898 goto invalid_kind;
13899 kind = OMP_CLAUSE_DEFAULT_PRIVATE;
13900 }
13901 break;
13902
13903 case 'f':
13904 if (strcmp ("firstprivate", p) != 0 || is_oacc)
13905 goto invalid_kind;
13906 kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
13907 break;
13908
13909 case 's':
13910 if (strcmp ("shared", p) != 0 || is_oacc)
13911 goto invalid_kind;
13912 kind = OMP_CLAUSE_DEFAULT_SHARED;
13913 break;
13914
13915 default:
13916 goto invalid_kind;
13917 }
13918
13919 c_parser_consume_token (parser);
13920 }
13921 else
13922 {
13923 invalid_kind:
13924 if (is_oacc)
13925 c_parser_error (parser, "expected %<none%> or %<present%>");
13926 else
13927 c_parser_error (parser, "expected %<none%>, %<shared%>, "
13928 "%<private%> or %<firstprivate%>");
13929 }
13930 parens.skip_until_found_close (parser);
13931
13932 if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED)
13933 return list;
13934
13935 check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default");
13936 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULT);
13937 OMP_CLAUSE_CHAIN (c) = list;
13938 OMP_CLAUSE_DEFAULT_KIND (c) = kind;
13939
13940 return c;
13941 }
13942
13943 /* OpenMP 2.5:
13944 firstprivate ( variable-list ) */
13945
13946 static tree
13947 c_parser_omp_clause_firstprivate (c_parser *parser, tree list)
13948 {
13949 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FIRSTPRIVATE, list);
13950 }
13951
13952 /* OpenMP 3.1:
13953 final ( expression ) */
13954
13955 static tree
13956 c_parser_omp_clause_final (c_parser *parser, tree list)
13957 {
13958 location_t loc = c_parser_peek_token (parser)->location;
13959 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
13960 {
13961 matching_parens parens;
13962 tree t, c;
13963 if (!parens.require_open (parser))
13964 t = error_mark_node;
13965 else
13966 {
13967 location_t eloc = c_parser_peek_token (parser)->location;
13968 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13969 t = convert_lvalue_to_rvalue (eloc, expr, true, true).value;
13970 t = c_objc_common_truthvalue_conversion (eloc, t);
13971 t = c_fully_fold (t, false, NULL);
13972 parens.skip_until_found_close (parser);
13973 }
13974
13975 check_no_duplicate_clause (list, OMP_CLAUSE_FINAL, "final");
13976
13977 c = build_omp_clause (loc, OMP_CLAUSE_FINAL);
13978 OMP_CLAUSE_FINAL_EXPR (c) = t;
13979 OMP_CLAUSE_CHAIN (c) = list;
13980 list = c;
13981 }
13982 else
13983 c_parser_error (parser, "expected %<(%>");
13984
13985 return list;
13986 }
13987
13988 /* OpenACC, OpenMP 2.5:
13989 if ( expression )
13990
13991 OpenMP 4.5:
13992 if ( directive-name-modifier : expression )
13993
13994 directive-name-modifier:
13995 parallel | task | taskloop | target data | target | target update
13996 | target enter data | target exit data
13997
13998 OpenMP 5.0:
13999 directive-name-modifier:
14000 ... | simd | cancel */
14001
14002 static tree
14003 c_parser_omp_clause_if (c_parser *parser, tree list, bool is_omp)
14004 {
14005 location_t location = c_parser_peek_token (parser)->location;
14006 enum tree_code if_modifier = ERROR_MARK;
14007
14008 matching_parens parens;
14009 if (!parens.require_open (parser))
14010 return list;
14011
14012 if (is_omp && c_parser_next_token_is (parser, CPP_NAME))
14013 {
14014 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14015 int n = 2;
14016 if (strcmp (p, "cancel") == 0)
14017 if_modifier = VOID_CST;
14018 else if (strcmp (p, "parallel") == 0)
14019 if_modifier = OMP_PARALLEL;
14020 else if (strcmp (p, "simd") == 0)
14021 if_modifier = OMP_SIMD;
14022 else if (strcmp (p, "task") == 0)
14023 if_modifier = OMP_TASK;
14024 else if (strcmp (p, "taskloop") == 0)
14025 if_modifier = OMP_TASKLOOP;
14026 else if (strcmp (p, "target") == 0)
14027 {
14028 if_modifier = OMP_TARGET;
14029 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
14030 {
14031 p = IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser)->value);
14032 if (strcmp ("data", p) == 0)
14033 if_modifier = OMP_TARGET_DATA;
14034 else if (strcmp ("update", p) == 0)
14035 if_modifier = OMP_TARGET_UPDATE;
14036 else if (strcmp ("enter", p) == 0)
14037 if_modifier = OMP_TARGET_ENTER_DATA;
14038 else if (strcmp ("exit", p) == 0)
14039 if_modifier = OMP_TARGET_EXIT_DATA;
14040 if (if_modifier != OMP_TARGET)
14041 {
14042 n = 3;
14043 c_parser_consume_token (parser);
14044 }
14045 else
14046 {
14047 location_t loc = c_parser_peek_2nd_token (parser)->location;
14048 error_at (loc, "expected %<data%>, %<update%>, %<enter%> "
14049 "or %<exit%>");
14050 if_modifier = ERROR_MARK;
14051 }
14052 if (if_modifier == OMP_TARGET_ENTER_DATA
14053 || if_modifier == OMP_TARGET_EXIT_DATA)
14054 {
14055 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
14056 {
14057 p = IDENTIFIER_POINTER
14058 (c_parser_peek_2nd_token (parser)->value);
14059 if (strcmp ("data", p) == 0)
14060 n = 4;
14061 }
14062 if (n == 4)
14063 c_parser_consume_token (parser);
14064 else
14065 {
14066 location_t loc
14067 = c_parser_peek_2nd_token (parser)->location;
14068 error_at (loc, "expected %<data%>");
14069 if_modifier = ERROR_MARK;
14070 }
14071 }
14072 }
14073 }
14074 if (if_modifier != ERROR_MARK)
14075 {
14076 if (c_parser_peek_2nd_token (parser)->type == CPP_COLON)
14077 {
14078 c_parser_consume_token (parser);
14079 c_parser_consume_token (parser);
14080 }
14081 else
14082 {
14083 if (n > 2)
14084 {
14085 location_t loc = c_parser_peek_2nd_token (parser)->location;
14086 error_at (loc, "expected %<:%>");
14087 }
14088 if_modifier = ERROR_MARK;
14089 }
14090 }
14091 }
14092
14093 location_t loc = c_parser_peek_token (parser)->location;
14094 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14095 expr = convert_lvalue_to_rvalue (loc, expr, true, true);
14096 tree t = c_objc_common_truthvalue_conversion (loc, expr.value), c;
14097 t = c_fully_fold (t, false, NULL);
14098 parens.skip_until_found_close (parser);
14099
14100 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
14101 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF)
14102 {
14103 if (if_modifier != ERROR_MARK
14104 && OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
14105 {
14106 const char *p = NULL;
14107 switch (if_modifier)
14108 {
14109 case VOID_CST: p = "cancel"; break;
14110 case OMP_PARALLEL: p = "parallel"; break;
14111 case OMP_SIMD: p = "simd"; break;
14112 case OMP_TASK: p = "task"; break;
14113 case OMP_TASKLOOP: p = "taskloop"; break;
14114 case OMP_TARGET_DATA: p = "target data"; break;
14115 case OMP_TARGET: p = "target"; break;
14116 case OMP_TARGET_UPDATE: p = "target update"; break;
14117 case OMP_TARGET_ENTER_DATA: p = "target enter data"; break;
14118 case OMP_TARGET_EXIT_DATA: p = "target exit data"; break;
14119 default: gcc_unreachable ();
14120 }
14121 error_at (location, "too many %<if%> clauses with %qs modifier",
14122 p);
14123 return list;
14124 }
14125 else if (OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
14126 {
14127 if (!is_omp)
14128 error_at (location, "too many %<if%> clauses");
14129 else
14130 error_at (location, "too many %<if%> clauses without modifier");
14131 return list;
14132 }
14133 else if (if_modifier == ERROR_MARK
14134 || OMP_CLAUSE_IF_MODIFIER (c) == ERROR_MARK)
14135 {
14136 error_at (location, "if any %<if%> clause has modifier, then all "
14137 "%<if%> clauses have to use modifier");
14138 return list;
14139 }
14140 }
14141
14142 c = build_omp_clause (location, OMP_CLAUSE_IF);
14143 OMP_CLAUSE_IF_MODIFIER (c) = if_modifier;
14144 OMP_CLAUSE_IF_EXPR (c) = t;
14145 OMP_CLAUSE_CHAIN (c) = list;
14146 return c;
14147 }
14148
14149 /* OpenMP 2.5:
14150 lastprivate ( variable-list )
14151
14152 OpenMP 5.0:
14153 lastprivate ( [ lastprivate-modifier : ] variable-list ) */
14154
14155 static tree
14156 c_parser_omp_clause_lastprivate (c_parser *parser, tree list)
14157 {
14158 /* The clauses location. */
14159 location_t loc = c_parser_peek_token (parser)->location;
14160
14161 if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
14162 {
14163 bool conditional = false;
14164 if (c_parser_next_token_is (parser, CPP_NAME)
14165 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
14166 {
14167 const char *p
14168 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14169 if (strcmp (p, "conditional") == 0)
14170 {
14171 conditional = true;
14172 c_parser_consume_token (parser);
14173 c_parser_consume_token (parser);
14174 }
14175 }
14176 tree nlist = c_parser_omp_variable_list (parser, loc,
14177 OMP_CLAUSE_LASTPRIVATE, list);
14178 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
14179 if (conditional)
14180 for (tree c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
14181 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 1;
14182 return nlist;
14183 }
14184 return list;
14185 }
14186
14187 /* OpenMP 3.1:
14188 mergeable */
14189
14190 static tree
14191 c_parser_omp_clause_mergeable (c_parser *parser ATTRIBUTE_UNUSED, tree list)
14192 {
14193 tree c;
14194
14195 /* FIXME: Should we allow duplicates? */
14196 check_no_duplicate_clause (list, OMP_CLAUSE_MERGEABLE, "mergeable");
14197
14198 c = build_omp_clause (c_parser_peek_token (parser)->location,
14199 OMP_CLAUSE_MERGEABLE);
14200 OMP_CLAUSE_CHAIN (c) = list;
14201
14202 return c;
14203 }
14204
14205 /* OpenMP 2.5:
14206 nowait */
14207
14208 static tree
14209 c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list)
14210 {
14211 tree c;
14212 location_t loc = c_parser_peek_token (parser)->location;
14213
14214 check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait");
14215
14216 c = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
14217 OMP_CLAUSE_CHAIN (c) = list;
14218 return c;
14219 }
14220
14221 /* OpenMP 2.5:
14222 num_threads ( expression ) */
14223
14224 static tree
14225 c_parser_omp_clause_num_threads (c_parser *parser, tree list)
14226 {
14227 location_t num_threads_loc = c_parser_peek_token (parser)->location;
14228 matching_parens parens;
14229 if (parens.require_open (parser))
14230 {
14231 location_t expr_loc = c_parser_peek_token (parser)->location;
14232 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14233 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14234 tree c, t = expr.value;
14235 t = c_fully_fold (t, false, NULL);
14236
14237 parens.skip_until_found_close (parser);
14238
14239 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14240 {
14241 c_parser_error (parser, "expected integer expression");
14242 return list;
14243 }
14244
14245 /* Attempt to statically determine when the number isn't positive. */
14246 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14247 build_int_cst (TREE_TYPE (t), 0));
14248 protected_set_expr_location (c, expr_loc);
14249 if (c == boolean_true_node)
14250 {
14251 warning_at (expr_loc, 0,
14252 "%<num_threads%> value must be positive");
14253 t = integer_one_node;
14254 }
14255
14256 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads");
14257
14258 c = build_omp_clause (num_threads_loc, OMP_CLAUSE_NUM_THREADS);
14259 OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
14260 OMP_CLAUSE_CHAIN (c) = list;
14261 list = c;
14262 }
14263
14264 return list;
14265 }
14266
14267 /* OpenMP 4.5:
14268 num_tasks ( expression )
14269
14270 OpenMP 5.1:
14271 num_tasks ( strict : expression ) */
14272
14273 static tree
14274 c_parser_omp_clause_num_tasks (c_parser *parser, tree list)
14275 {
14276 location_t num_tasks_loc = c_parser_peek_token (parser)->location;
14277 matching_parens parens;
14278 if (parens.require_open (parser))
14279 {
14280 bool strict = false;
14281 if (c_parser_next_token_is (parser, CPP_NAME)
14282 && c_parser_peek_2nd_token (parser)->type == CPP_COLON
14283 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
14284 "strict") == 0)
14285 {
14286 strict = true;
14287 c_parser_consume_token (parser);
14288 c_parser_consume_token (parser);
14289 }
14290
14291 location_t expr_loc = c_parser_peek_token (parser)->location;
14292 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14293 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14294 tree c, t = expr.value;
14295 t = c_fully_fold (t, false, NULL);
14296
14297 parens.skip_until_found_close (parser);
14298
14299 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14300 {
14301 c_parser_error (parser, "expected integer expression");
14302 return list;
14303 }
14304
14305 /* Attempt to statically determine when the number isn't positive. */
14306 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14307 build_int_cst (TREE_TYPE (t), 0));
14308 if (CAN_HAVE_LOCATION_P (c))
14309 SET_EXPR_LOCATION (c, expr_loc);
14310 if (c == boolean_true_node)
14311 {
14312 warning_at (expr_loc, 0, "%<num_tasks%> value must be positive");
14313 t = integer_one_node;
14314 }
14315
14316 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TASKS, "num_tasks");
14317
14318 c = build_omp_clause (num_tasks_loc, OMP_CLAUSE_NUM_TASKS);
14319 OMP_CLAUSE_NUM_TASKS_EXPR (c) = t;
14320 OMP_CLAUSE_NUM_TASKS_STRICT (c) = strict;
14321 OMP_CLAUSE_CHAIN (c) = list;
14322 list = c;
14323 }
14324
14325 return list;
14326 }
14327
14328 /* OpenMP 4.5:
14329 grainsize ( expression )
14330
14331 OpenMP 5.1:
14332 grainsize ( strict : expression ) */
14333
14334 static tree
14335 c_parser_omp_clause_grainsize (c_parser *parser, tree list)
14336 {
14337 location_t grainsize_loc = c_parser_peek_token (parser)->location;
14338 matching_parens parens;
14339 if (parens.require_open (parser))
14340 {
14341 bool strict = false;
14342 if (c_parser_next_token_is (parser, CPP_NAME)
14343 && c_parser_peek_2nd_token (parser)->type == CPP_COLON
14344 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
14345 "strict") == 0)
14346 {
14347 strict = true;
14348 c_parser_consume_token (parser);
14349 c_parser_consume_token (parser);
14350 }
14351
14352 location_t expr_loc = c_parser_peek_token (parser)->location;
14353 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14354 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14355 tree c, t = expr.value;
14356 t = c_fully_fold (t, false, NULL);
14357
14358 parens.skip_until_found_close (parser);
14359
14360 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14361 {
14362 c_parser_error (parser, "expected integer expression");
14363 return list;
14364 }
14365
14366 /* Attempt to statically determine when the number isn't positive. */
14367 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14368 build_int_cst (TREE_TYPE (t), 0));
14369 if (CAN_HAVE_LOCATION_P (c))
14370 SET_EXPR_LOCATION (c, expr_loc);
14371 if (c == boolean_true_node)
14372 {
14373 warning_at (expr_loc, 0, "%<grainsize%> value must be positive");
14374 t = integer_one_node;
14375 }
14376
14377 check_no_duplicate_clause (list, OMP_CLAUSE_GRAINSIZE, "grainsize");
14378
14379 c = build_omp_clause (grainsize_loc, OMP_CLAUSE_GRAINSIZE);
14380 OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
14381 OMP_CLAUSE_GRAINSIZE_STRICT (c) = strict;
14382 OMP_CLAUSE_CHAIN (c) = list;
14383 list = c;
14384 }
14385
14386 return list;
14387 }
14388
14389 /* OpenMP 4.5:
14390 priority ( expression ) */
14391
14392 static tree
14393 c_parser_omp_clause_priority (c_parser *parser, tree list)
14394 {
14395 location_t priority_loc = c_parser_peek_token (parser)->location;
14396 matching_parens parens;
14397 if (parens.require_open (parser))
14398 {
14399 location_t expr_loc = c_parser_peek_token (parser)->location;
14400 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14401 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14402 tree c, t = expr.value;
14403 t = c_fully_fold (t, false, NULL);
14404
14405 parens.skip_until_found_close (parser);
14406
14407 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14408 {
14409 c_parser_error (parser, "expected integer expression");
14410 return list;
14411 }
14412
14413 /* Attempt to statically determine when the number isn't
14414 non-negative. */
14415 c = fold_build2_loc (expr_loc, LT_EXPR, boolean_type_node, t,
14416 build_int_cst (TREE_TYPE (t), 0));
14417 if (CAN_HAVE_LOCATION_P (c))
14418 SET_EXPR_LOCATION (c, expr_loc);
14419 if (c == boolean_true_node)
14420 {
14421 warning_at (expr_loc, 0, "%<priority%> value must be non-negative");
14422 t = integer_one_node;
14423 }
14424
14425 check_no_duplicate_clause (list, OMP_CLAUSE_PRIORITY, "priority");
14426
14427 c = build_omp_clause (priority_loc, OMP_CLAUSE_PRIORITY);
14428 OMP_CLAUSE_PRIORITY_EXPR (c) = t;
14429 OMP_CLAUSE_CHAIN (c) = list;
14430 list = c;
14431 }
14432
14433 return list;
14434 }
14435
14436 /* OpenMP 4.5:
14437 hint ( expression ) */
14438
14439 static tree
14440 c_parser_omp_clause_hint (c_parser *parser, tree list)
14441 {
14442 location_t hint_loc = c_parser_peek_token (parser)->location;
14443 matching_parens parens;
14444 if (parens.require_open (parser))
14445 {
14446 location_t expr_loc = c_parser_peek_token (parser)->location;
14447 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14448 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14449 tree c, t = expr.value;
14450 t = c_fully_fold (t, false, NULL);
14451 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
14452 || TREE_CODE (t) != INTEGER_CST
14453 || tree_int_cst_sgn (t) == -1)
14454 {
14455 c_parser_error (parser, "expected constant integer expression "
14456 "with valid sync-hint value");
14457 return list;
14458 }
14459 parens.skip_until_found_close (parser);
14460 check_no_duplicate_clause (list, OMP_CLAUSE_HINT, "hint");
14461
14462 c = build_omp_clause (hint_loc, OMP_CLAUSE_HINT);
14463 OMP_CLAUSE_HINT_EXPR (c) = t;
14464 OMP_CLAUSE_CHAIN (c) = list;
14465 list = c;
14466 }
14467
14468 return list;
14469 }
14470
14471 /* OpenMP 5.1:
14472 filter ( integer-expression ) */
14473
14474 static tree
14475 c_parser_omp_clause_filter (c_parser *parser, tree list)
14476 {
14477 location_t hint_loc = c_parser_peek_token (parser)->location;
14478 matching_parens parens;
14479 if (parens.require_open (parser))
14480 {
14481 location_t expr_loc = c_parser_peek_token (parser)->location;
14482 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14483 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14484 tree c, t = expr.value;
14485 t = c_fully_fold (t, false, NULL);
14486 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14487 {
14488 c_parser_error (parser, "expected integer expression");
14489 return list;
14490 }
14491 parens.skip_until_found_close (parser);
14492 check_no_duplicate_clause (list, OMP_CLAUSE_FILTER, "filter");
14493
14494 c = build_omp_clause (hint_loc, OMP_CLAUSE_FILTER);
14495 OMP_CLAUSE_FILTER_EXPR (c) = t;
14496 OMP_CLAUSE_CHAIN (c) = list;
14497 list = c;
14498 }
14499
14500 return list;
14501 }
14502
14503 /* OpenMP 4.5:
14504 defaultmap ( tofrom : scalar )
14505
14506 OpenMP 5.0:
14507 defaultmap ( implicit-behavior [ : variable-category ] ) */
14508
14509 static tree
14510 c_parser_omp_clause_defaultmap (c_parser *parser, tree list)
14511 {
14512 location_t loc = c_parser_peek_token (parser)->location;
14513 tree c;
14514 const char *p;
14515 enum omp_clause_defaultmap_kind behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
14516 enum omp_clause_defaultmap_kind category
14517 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
14518
14519 matching_parens parens;
14520 if (!parens.require_open (parser))
14521 return list;
14522 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
14523 p = "default";
14524 else if (!c_parser_next_token_is (parser, CPP_NAME))
14525 {
14526 invalid_behavior:
14527 c_parser_error (parser, "expected %<alloc%>, %<to%>, %<from%>, "
14528 "%<tofrom%>, %<firstprivate%>, %<none%> "
14529 "or %<default%>");
14530 goto out_err;
14531 }
14532 else
14533 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14534
14535 switch (p[0])
14536 {
14537 case 'a':
14538 if (strcmp ("alloc", p) == 0)
14539 behavior = OMP_CLAUSE_DEFAULTMAP_ALLOC;
14540 else
14541 goto invalid_behavior;
14542 break;
14543
14544 case 'd':
14545 if (strcmp ("default", p) == 0)
14546 behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
14547 else
14548 goto invalid_behavior;
14549 break;
14550
14551 case 'f':
14552 if (strcmp ("firstprivate", p) == 0)
14553 behavior = OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
14554 else if (strcmp ("from", p) == 0)
14555 behavior = OMP_CLAUSE_DEFAULTMAP_FROM;
14556 else
14557 goto invalid_behavior;
14558 break;
14559
14560 case 'n':
14561 if (strcmp ("none", p) == 0)
14562 behavior = OMP_CLAUSE_DEFAULTMAP_NONE;
14563 else
14564 goto invalid_behavior;
14565 break;
14566
14567 case 't':
14568 if (strcmp ("tofrom", p) == 0)
14569 behavior = OMP_CLAUSE_DEFAULTMAP_TOFROM;
14570 else if (strcmp ("to", p) == 0)
14571 behavior = OMP_CLAUSE_DEFAULTMAP_TO;
14572 else
14573 goto invalid_behavior;
14574 break;
14575
14576 default:
14577 goto invalid_behavior;
14578 }
14579 c_parser_consume_token (parser);
14580
14581 if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
14582 {
14583 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14584 goto out_err;
14585 if (!c_parser_next_token_is (parser, CPP_NAME))
14586 {
14587 invalid_category:
14588 c_parser_error (parser, "expected %<scalar%>, %<aggregate%> or "
14589 "%<pointer%>");
14590 goto out_err;
14591 }
14592 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14593 switch (p[0])
14594 {
14595 case 'a':
14596 if (strcmp ("aggregate", p) == 0)
14597 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE;
14598 else
14599 goto invalid_category;
14600 break;
14601
14602 case 'p':
14603 if (strcmp ("pointer", p) == 0)
14604 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER;
14605 else
14606 goto invalid_category;
14607 break;
14608
14609 case 's':
14610 if (strcmp ("scalar", p) == 0)
14611 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR;
14612 else
14613 goto invalid_category;
14614 break;
14615
14616 default:
14617 goto invalid_category;
14618 }
14619
14620 c_parser_consume_token (parser);
14621 }
14622 parens.skip_until_found_close (parser);
14623
14624 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
14625 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEFAULTMAP
14626 && (category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
14627 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c) == category
14628 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
14629 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)))
14630 {
14631 enum omp_clause_defaultmap_kind cat = category;
14632 location_t loc = OMP_CLAUSE_LOCATION (c);
14633 if (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
14634 cat = OMP_CLAUSE_DEFAULTMAP_CATEGORY (c);
14635 p = NULL;
14636 switch (cat)
14637 {
14638 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
14639 p = NULL;
14640 break;
14641 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
14642 p = "aggregate";
14643 break;
14644 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
14645 p = "pointer";
14646 break;
14647 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
14648 p = "scalar";
14649 break;
14650 default:
14651 gcc_unreachable ();
14652 }
14653 if (p)
14654 error_at (loc, "too many %<defaultmap%> clauses with %qs category",
14655 p);
14656 else
14657 error_at (loc, "too many %<defaultmap%> clauses with unspecified "
14658 "category");
14659 break;
14660 }
14661
14662 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULTMAP);
14663 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c, behavior, category);
14664 OMP_CLAUSE_CHAIN (c) = list;
14665 return c;
14666
14667 out_err:
14668 parens.skip_until_found_close (parser);
14669 return list;
14670 }
14671
14672 /* OpenACC 2.0:
14673 use_device ( variable-list )
14674
14675 OpenMP 4.5:
14676 use_device_ptr ( variable-list ) */
14677
14678 static tree
14679 c_parser_omp_clause_use_device_ptr (c_parser *parser, tree list)
14680 {
14681 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_PTR,
14682 list);
14683 }
14684
14685 /* OpenMP 5.0:
14686 use_device_addr ( variable-list ) */
14687
14688 static tree
14689 c_parser_omp_clause_use_device_addr (c_parser *parser, tree list)
14690 {
14691 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_ADDR,
14692 list);
14693 }
14694
14695 /* OpenMP 5.1:
14696 has_device_addr ( variable-list ) */
14697
14698 static tree
14699 c_parser_omp_clause_has_device_addr (c_parser *parser, tree list)
14700 {
14701 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_HAS_DEVICE_ADDR,
14702 list);
14703 }
14704
14705 /* OpenMP 4.5:
14706 is_device_ptr ( variable-list ) */
14707
14708 static tree
14709 c_parser_omp_clause_is_device_ptr (c_parser *parser, tree list)
14710 {
14711 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_IS_DEVICE_PTR, list);
14712 }
14713
14714 /* OpenACC:
14715 num_gangs ( expression )
14716 num_workers ( expression )
14717 vector_length ( expression ) */
14718
14719 static tree
14720 c_parser_oacc_single_int_clause (c_parser *parser, omp_clause_code code,
14721 tree list)
14722 {
14723 location_t loc = c_parser_peek_token (parser)->location;
14724
14725 matching_parens parens;
14726 if (!parens.require_open (parser))
14727 return list;
14728
14729 location_t expr_loc = c_parser_peek_token (parser)->location;
14730 c_expr expr = c_parser_expression (parser);
14731 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14732 tree c, t = expr.value;
14733 t = c_fully_fold (t, false, NULL);
14734
14735 parens.skip_until_found_close (parser);
14736
14737 if (t == error_mark_node)
14738 return list;
14739 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14740 {
14741 error_at (expr_loc, "%qs expression must be integral",
14742 omp_clause_code_name[code]);
14743 return list;
14744 }
14745
14746 /* Attempt to statically determine when the number isn't positive. */
14747 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14748 build_int_cst (TREE_TYPE (t), 0));
14749 protected_set_expr_location (c, expr_loc);
14750 if (c == boolean_true_node)
14751 {
14752 warning_at (expr_loc, 0,
14753 "%qs value must be positive",
14754 omp_clause_code_name[code]);
14755 t = integer_one_node;
14756 }
14757
14758 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14759
14760 c = build_omp_clause (loc, code);
14761 OMP_CLAUSE_OPERAND (c, 0) = t;
14762 OMP_CLAUSE_CHAIN (c) = list;
14763 return c;
14764 }
14765
14766 /* OpenACC:
14767
14768 gang [( gang-arg-list )]
14769 worker [( [num:] int-expr )]
14770 vector [( [length:] int-expr )]
14771
14772 where gang-arg is one of:
14773
14774 [num:] int-expr
14775 static: size-expr
14776
14777 and size-expr may be:
14778
14779 *
14780 int-expr
14781 */
14782
14783 static tree
14784 c_parser_oacc_shape_clause (c_parser *parser, location_t loc,
14785 omp_clause_code kind,
14786 const char *str, tree list)
14787 {
14788 const char *id = "num";
14789 tree ops[2] = { NULL_TREE, NULL_TREE }, c;
14790
14791 if (kind == OMP_CLAUSE_VECTOR)
14792 id = "length";
14793
14794 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14795 {
14796 c_parser_consume_token (parser);
14797
14798 do
14799 {
14800 c_token *next = c_parser_peek_token (parser);
14801 int idx = 0;
14802
14803 /* Gang static argument. */
14804 if (kind == OMP_CLAUSE_GANG
14805 && c_parser_next_token_is_keyword (parser, RID_STATIC))
14806 {
14807 c_parser_consume_token (parser);
14808
14809 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14810 goto cleanup_error;
14811
14812 idx = 1;
14813 if (ops[idx] != NULL_TREE)
14814 {
14815 c_parser_error (parser, "too many %<static%> arguments");
14816 goto cleanup_error;
14817 }
14818
14819 /* Check for the '*' argument. */
14820 if (c_parser_next_token_is (parser, CPP_MULT)
14821 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
14822 || c_parser_peek_2nd_token (parser)->type
14823 == CPP_CLOSE_PAREN))
14824 {
14825 c_parser_consume_token (parser);
14826 ops[idx] = integer_minus_one_node;
14827
14828 if (c_parser_next_token_is (parser, CPP_COMMA))
14829 {
14830 c_parser_consume_token (parser);
14831 continue;
14832 }
14833 else
14834 break;
14835 }
14836 }
14837 /* Worker num: argument and vector length: arguments. */
14838 else if (c_parser_next_token_is (parser, CPP_NAME)
14839 && strcmp (id, IDENTIFIER_POINTER (next->value)) == 0
14840 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
14841 {
14842 c_parser_consume_token (parser); /* id */
14843 c_parser_consume_token (parser); /* ':' */
14844 }
14845
14846 /* Now collect the actual argument. */
14847 if (ops[idx] != NULL_TREE)
14848 {
14849 c_parser_error (parser, "unexpected argument");
14850 goto cleanup_error;
14851 }
14852
14853 location_t expr_loc = c_parser_peek_token (parser)->location;
14854 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
14855 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
14856 tree expr = cexpr.value;
14857 if (expr == error_mark_node)
14858 goto cleanup_error;
14859
14860 expr = c_fully_fold (expr, false, NULL);
14861
14862 /* Attempt to statically determine when the number isn't a
14863 positive integer. */
14864
14865 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr)))
14866 {
14867 c_parser_error (parser, "expected integer expression");
14868 return list;
14869 }
14870
14871 tree c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, expr,
14872 build_int_cst (TREE_TYPE (expr), 0));
14873 if (c == boolean_true_node)
14874 {
14875 warning_at (loc, 0,
14876 "%qs value must be positive", str);
14877 expr = integer_one_node;
14878 }
14879
14880 ops[idx] = expr;
14881
14882 if (kind == OMP_CLAUSE_GANG
14883 && c_parser_next_token_is (parser, CPP_COMMA))
14884 {
14885 c_parser_consume_token (parser);
14886 continue;
14887 }
14888 break;
14889 }
14890 while (1);
14891
14892 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
14893 goto cleanup_error;
14894 }
14895
14896 check_no_duplicate_clause (list, kind, str);
14897
14898 c = build_omp_clause (loc, kind);
14899
14900 if (ops[1])
14901 OMP_CLAUSE_OPERAND (c, 1) = ops[1];
14902
14903 OMP_CLAUSE_OPERAND (c, 0) = ops[0];
14904 OMP_CLAUSE_CHAIN (c) = list;
14905
14906 return c;
14907
14908 cleanup_error:
14909 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
14910 return list;
14911 }
14912
14913 /* OpenACC 2.5:
14914 auto
14915 finalize
14916 independent
14917 nohost
14918 seq */
14919
14920 static tree
14921 c_parser_oacc_simple_clause (location_t loc, enum omp_clause_code code,
14922 tree list)
14923 {
14924 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14925
14926 tree c = build_omp_clause (loc, code);
14927 OMP_CLAUSE_CHAIN (c) = list;
14928
14929 return c;
14930 }
14931
14932 /* OpenACC:
14933 async [( int-expr )] */
14934
14935 static tree
14936 c_parser_oacc_clause_async (c_parser *parser, tree list)
14937 {
14938 tree c, t;
14939 location_t loc = c_parser_peek_token (parser)->location;
14940
14941 t = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
14942
14943 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
14944 {
14945 c_parser_consume_token (parser);
14946
14947 t = c_parser_expr_no_commas (parser, NULL).value;
14948 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14949 c_parser_error (parser, "expected integer expression");
14950 else if (t == error_mark_node
14951 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
14952 return list;
14953 }
14954 else
14955 t = c_fully_fold (t, false, NULL);
14956
14957 check_no_duplicate_clause (list, OMP_CLAUSE_ASYNC, "async");
14958
14959 c = build_omp_clause (loc, OMP_CLAUSE_ASYNC);
14960 OMP_CLAUSE_ASYNC_EXPR (c) = t;
14961 OMP_CLAUSE_CHAIN (c) = list;
14962 list = c;
14963
14964 return list;
14965 }
14966
14967 /* OpenACC 2.0:
14968 tile ( size-expr-list ) */
14969
14970 static tree
14971 c_parser_oacc_clause_tile (c_parser *parser, tree list)
14972 {
14973 tree c, expr = error_mark_node;
14974 location_t loc;
14975 tree tile = NULL_TREE;
14976
14977 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
14978 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
14979
14980 loc = c_parser_peek_token (parser)->location;
14981 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
14982 return list;
14983
14984 do
14985 {
14986 if (tile && !c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
14987 return list;
14988
14989 if (c_parser_next_token_is (parser, CPP_MULT)
14990 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
14991 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
14992 {
14993 c_parser_consume_token (parser);
14994 expr = integer_zero_node;
14995 }
14996 else
14997 {
14998 location_t expr_loc = c_parser_peek_token (parser)->location;
14999 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
15000 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
15001 expr = cexpr.value;
15002
15003 if (expr == error_mark_node)
15004 {
15005 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
15006 "expected %<)%>");
15007 return list;
15008 }
15009
15010 expr = c_fully_fold (expr, false, NULL);
15011
15012 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
15013 || !tree_fits_shwi_p (expr)
15014 || tree_to_shwi (expr) <= 0)
15015 {
15016 error_at (expr_loc, "%<tile%> argument needs positive"
15017 " integral constant");
15018 expr = integer_zero_node;
15019 }
15020 }
15021
15022 tile = tree_cons (NULL_TREE, expr, tile);
15023 }
15024 while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN));
15025
15026 /* Consume the trailing ')'. */
15027 c_parser_consume_token (parser);
15028
15029 c = build_omp_clause (loc, OMP_CLAUSE_TILE);
15030 tile = nreverse (tile);
15031 OMP_CLAUSE_TILE_LIST (c) = tile;
15032 OMP_CLAUSE_CHAIN (c) = list;
15033 return c;
15034 }
15035
15036 /* OpenACC:
15037 wait [( int-expr-list )] */
15038
15039 static tree
15040 c_parser_oacc_clause_wait (c_parser *parser, tree list)
15041 {
15042 location_t clause_loc = c_parser_peek_token (parser)->location;
15043
15044 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
15045 list = c_parser_oacc_wait_list (parser, clause_loc, list);
15046 else
15047 {
15048 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
15049
15050 OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
15051 OMP_CLAUSE_CHAIN (c) = list;
15052 list = c;
15053 }
15054
15055 return list;
15056 }
15057
15058
15059 /* OpenMP 5.0:
15060 order ( concurrent )
15061
15062 OpenMP 5.1:
15063 order ( order-modifier : concurrent )
15064
15065 order-modifier:
15066 reproducible
15067 unconstrained */
15068
15069 static tree
15070 c_parser_omp_clause_order (c_parser *parser, tree list)
15071 {
15072 location_t loc = c_parser_peek_token (parser)->location;
15073 tree c;
15074 const char *p;
15075 bool unconstrained = false;
15076 bool reproducible = false;
15077
15078 matching_parens parens;
15079 if (!parens.require_open (parser))
15080 return list;
15081 if (c_parser_next_token_is (parser, CPP_NAME)
15082 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
15083 {
15084 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15085 if (strcmp (p, "unconstrained") == 0)
15086 unconstrained = true;
15087 else if (strcmp (p, "reproducible") == 0)
15088 reproducible = true;
15089 else
15090 {
15091 c_parser_error (parser, "expected %<reproducible%> or "
15092 "%<unconstrained%>");
15093 goto out_err;
15094 }
15095 c_parser_consume_token (parser);
15096 c_parser_consume_token (parser);
15097 }
15098 if (!c_parser_next_token_is (parser, CPP_NAME))
15099 {
15100 c_parser_error (parser, "expected %<concurrent%>");
15101 goto out_err;
15102 }
15103 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15104 if (strcmp (p, "concurrent") != 0)
15105 {
15106 c_parser_error (parser, "expected %<concurrent%>");
15107 goto out_err;
15108 }
15109 c_parser_consume_token (parser);
15110 parens.skip_until_found_close (parser);
15111 check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order");
15112 c = build_omp_clause (loc, OMP_CLAUSE_ORDER);
15113 OMP_CLAUSE_ORDER_UNCONSTRAINED (c) = unconstrained;
15114 OMP_CLAUSE_ORDER_REPRODUCIBLE (c) = reproducible;
15115 OMP_CLAUSE_CHAIN (c) = list;
15116 return c;
15117
15118 out_err:
15119 parens.skip_until_found_close (parser);
15120 return list;
15121 }
15122
15123
15124 /* OpenMP 5.0:
15125 bind ( teams | parallel | thread ) */
15126
15127 static tree
15128 c_parser_omp_clause_bind (c_parser *parser, tree list)
15129 {
15130 location_t loc = c_parser_peek_token (parser)->location;
15131 tree c;
15132 const char *p;
15133 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
15134
15135 matching_parens parens;
15136 if (!parens.require_open (parser))
15137 return list;
15138 if (!c_parser_next_token_is (parser, CPP_NAME))
15139 {
15140 invalid:
15141 c_parser_error (parser,
15142 "expected %<teams%>, %<parallel%> or %<thread%>");
15143 parens.skip_until_found_close (parser);
15144 return list;
15145 }
15146 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15147 if (strcmp (p, "teams") == 0)
15148 kind = OMP_CLAUSE_BIND_TEAMS;
15149 else if (strcmp (p, "parallel") == 0)
15150 kind = OMP_CLAUSE_BIND_PARALLEL;
15151 else if (strcmp (p, "thread") != 0)
15152 goto invalid;
15153 c_parser_consume_token (parser);
15154 parens.skip_until_found_close (parser);
15155 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
15156 c = build_omp_clause (loc, OMP_CLAUSE_BIND);
15157 OMP_CLAUSE_BIND_KIND (c) = kind;
15158 OMP_CLAUSE_CHAIN (c) = list;
15159 return c;
15160 }
15161
15162
15163 /* OpenMP 2.5:
15164 ordered
15165
15166 OpenMP 4.5:
15167 ordered ( constant-expression ) */
15168
15169 static tree
15170 c_parser_omp_clause_ordered (c_parser *parser, tree list)
15171 {
15172 check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered");
15173
15174 tree c, num = NULL_TREE;
15175 HOST_WIDE_INT n;
15176 location_t loc = c_parser_peek_token (parser)->location;
15177 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
15178 {
15179 matching_parens parens;
15180 parens.consume_open (parser);
15181 num = c_parser_expr_no_commas (parser, NULL).value;
15182 parens.skip_until_found_close (parser);
15183 }
15184 if (num == error_mark_node)
15185 return list;
15186 if (num)
15187 {
15188 mark_exp_read (num);
15189 num = c_fully_fold (num, false, NULL);
15190 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
15191 || !tree_fits_shwi_p (num)
15192 || (n = tree_to_shwi (num)) <= 0
15193 || (int) n != n)
15194 {
15195 error_at (loc, "ordered argument needs positive "
15196 "constant integer expression");
15197 return list;
15198 }
15199 }
15200 c = build_omp_clause (loc, OMP_CLAUSE_ORDERED);
15201 OMP_CLAUSE_ORDERED_EXPR (c) = num;
15202 OMP_CLAUSE_CHAIN (c) = list;
15203 return c;
15204 }
15205
15206 /* OpenMP 2.5:
15207 private ( variable-list ) */
15208
15209 static tree
15210 c_parser_omp_clause_private (c_parser *parser, tree list)
15211 {
15212 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_PRIVATE, list);
15213 }
15214
15215 /* OpenMP 2.5:
15216 reduction ( reduction-operator : variable-list )
15217
15218 reduction-operator:
15219 One of: + * - & ^ | && ||
15220
15221 OpenMP 3.1:
15222
15223 reduction-operator:
15224 One of: + * - & ^ | && || max min
15225
15226 OpenMP 4.0:
15227
15228 reduction-operator:
15229 One of: + * - & ^ | && ||
15230 identifier
15231
15232 OpenMP 5.0:
15233 reduction ( reduction-modifier, reduction-operator : variable-list )
15234 in_reduction ( reduction-operator : variable-list )
15235 task_reduction ( reduction-operator : variable-list ) */
15236
15237 static tree
15238 c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind,
15239 bool is_omp, tree list)
15240 {
15241 location_t clause_loc = c_parser_peek_token (parser)->location;
15242 matching_parens parens;
15243 if (parens.require_open (parser))
15244 {
15245 bool task = false;
15246 bool inscan = false;
15247 enum tree_code code = ERROR_MARK;
15248 tree reduc_id = NULL_TREE;
15249
15250 if (kind == OMP_CLAUSE_REDUCTION && is_omp)
15251 {
15252 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)
15253 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
15254 {
15255 c_parser_consume_token (parser);
15256 c_parser_consume_token (parser);
15257 }
15258 else if (c_parser_next_token_is (parser, CPP_NAME)
15259 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
15260 {
15261 const char *p
15262 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15263 if (strcmp (p, "task") == 0)
15264 task = true;
15265 else if (strcmp (p, "inscan") == 0)
15266 inscan = true;
15267 if (task || inscan)
15268 {
15269 c_parser_consume_token (parser);
15270 c_parser_consume_token (parser);
15271 }
15272 }
15273 }
15274
15275 switch (c_parser_peek_token (parser)->type)
15276 {
15277 case CPP_PLUS:
15278 code = PLUS_EXPR;
15279 break;
15280 case CPP_MULT:
15281 code = MULT_EXPR;
15282 break;
15283 case CPP_MINUS:
15284 code = MINUS_EXPR;
15285 break;
15286 case CPP_AND:
15287 code = BIT_AND_EXPR;
15288 break;
15289 case CPP_XOR:
15290 code = BIT_XOR_EXPR;
15291 break;
15292 case CPP_OR:
15293 code = BIT_IOR_EXPR;
15294 break;
15295 case CPP_AND_AND:
15296 code = TRUTH_ANDIF_EXPR;
15297 break;
15298 case CPP_OR_OR:
15299 code = TRUTH_ORIF_EXPR;
15300 break;
15301 case CPP_NAME:
15302 {
15303 const char *p
15304 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15305 if (strcmp (p, "min") == 0)
15306 {
15307 code = MIN_EXPR;
15308 break;
15309 }
15310 if (strcmp (p, "max") == 0)
15311 {
15312 code = MAX_EXPR;
15313 break;
15314 }
15315 reduc_id = c_parser_peek_token (parser)->value;
15316 break;
15317 }
15318 default:
15319 c_parser_error (parser,
15320 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
15321 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
15322 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
15323 return list;
15324 }
15325 c_parser_consume_token (parser);
15326 reduc_id = c_omp_reduction_id (code, reduc_id);
15327 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15328 {
15329 tree nl, c;
15330
15331 nl = c_parser_omp_variable_list (parser, clause_loc, kind, list);
15332 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15333 {
15334 tree d = OMP_CLAUSE_DECL (c), type;
15335 if (TREE_CODE (d) != TREE_LIST)
15336 type = TREE_TYPE (d);
15337 else
15338 {
15339 int cnt = 0;
15340 tree t;
15341 for (t = d; TREE_CODE (t) == TREE_LIST; t = TREE_CHAIN (t))
15342 cnt++;
15343 type = TREE_TYPE (t);
15344 while (cnt > 0)
15345 {
15346 if (TREE_CODE (type) != POINTER_TYPE
15347 && TREE_CODE (type) != ARRAY_TYPE)
15348 break;
15349 type = TREE_TYPE (type);
15350 cnt--;
15351 }
15352 }
15353 while (TREE_CODE (type) == ARRAY_TYPE)
15354 type = TREE_TYPE (type);
15355 OMP_CLAUSE_REDUCTION_CODE (c) = code;
15356 if (task)
15357 OMP_CLAUSE_REDUCTION_TASK (c) = 1;
15358 else if (inscan)
15359 OMP_CLAUSE_REDUCTION_INSCAN (c) = 1;
15360 if (code == ERROR_MARK
15361 || !(INTEGRAL_TYPE_P (type)
15362 || TREE_CODE (type) == REAL_TYPE
15363 || TREE_CODE (type) == COMPLEX_TYPE))
15364 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
15365 = c_omp_reduction_lookup (reduc_id,
15366 TYPE_MAIN_VARIANT (type));
15367 }
15368
15369 list = nl;
15370 }
15371 parens.skip_until_found_close (parser);
15372 }
15373 return list;
15374 }
15375
15376 /* OpenMP 2.5:
15377 schedule ( schedule-kind )
15378 schedule ( schedule-kind , expression )
15379
15380 schedule-kind:
15381 static | dynamic | guided | runtime | auto
15382
15383 OpenMP 4.5:
15384 schedule ( schedule-modifier : schedule-kind )
15385 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
15386
15387 schedule-modifier:
15388 simd
15389 monotonic
15390 nonmonotonic */
15391
15392 static tree
15393 c_parser_omp_clause_schedule (c_parser *parser, tree list)
15394 {
15395 tree c, t;
15396 location_t loc = c_parser_peek_token (parser)->location;
15397 int modifiers = 0, nmodifiers = 0;
15398
15399 matching_parens parens;
15400 if (!parens.require_open (parser))
15401 return list;
15402
15403 c = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE);
15404
15405 location_t comma = UNKNOWN_LOCATION;
15406 while (c_parser_next_token_is (parser, CPP_NAME))
15407 {
15408 tree kind = c_parser_peek_token (parser)->value;
15409 const char *p = IDENTIFIER_POINTER (kind);
15410 if (strcmp ("simd", p) == 0)
15411 OMP_CLAUSE_SCHEDULE_SIMD (c) = 1;
15412 else if (strcmp ("monotonic", p) == 0)
15413 modifiers |= OMP_CLAUSE_SCHEDULE_MONOTONIC;
15414 else if (strcmp ("nonmonotonic", p) == 0)
15415 modifiers |= OMP_CLAUSE_SCHEDULE_NONMONOTONIC;
15416 else
15417 break;
15418 comma = UNKNOWN_LOCATION;
15419 c_parser_consume_token (parser);
15420 if (nmodifiers++ == 0
15421 && c_parser_next_token_is (parser, CPP_COMMA))
15422 {
15423 comma = c_parser_peek_token (parser)->location;
15424 c_parser_consume_token (parser);
15425 }
15426 else
15427 {
15428 c_parser_require (parser, CPP_COLON, "expected %<:%>");
15429 break;
15430 }
15431 }
15432 if (comma != UNKNOWN_LOCATION)
15433 error_at (comma, "expected %<:%>");
15434
15435 if ((modifiers & (OMP_CLAUSE_SCHEDULE_MONOTONIC
15436 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
15437 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
15438 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
15439 {
15440 error_at (loc, "both %<monotonic%> and %<nonmonotonic%> modifiers "
15441 "specified");
15442 modifiers = 0;
15443 }
15444
15445 if (c_parser_next_token_is (parser, CPP_NAME))
15446 {
15447 tree kind = c_parser_peek_token (parser)->value;
15448 const char *p = IDENTIFIER_POINTER (kind);
15449
15450 switch (p[0])
15451 {
15452 case 'd':
15453 if (strcmp ("dynamic", p) != 0)
15454 goto invalid_kind;
15455 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
15456 break;
15457
15458 case 'g':
15459 if (strcmp ("guided", p) != 0)
15460 goto invalid_kind;
15461 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
15462 break;
15463
15464 case 'r':
15465 if (strcmp ("runtime", p) != 0)
15466 goto invalid_kind;
15467 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
15468 break;
15469
15470 default:
15471 goto invalid_kind;
15472 }
15473 }
15474 else if (c_parser_next_token_is_keyword (parser, RID_STATIC))
15475 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
15476 else if (c_parser_next_token_is_keyword (parser, RID_AUTO))
15477 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
15478 else
15479 goto invalid_kind;
15480
15481 c_parser_consume_token (parser);
15482 if (c_parser_next_token_is (parser, CPP_COMMA))
15483 {
15484 location_t here;
15485 c_parser_consume_token (parser);
15486
15487 here = c_parser_peek_token (parser)->location;
15488 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15489 expr = convert_lvalue_to_rvalue (here, expr, false, true);
15490 t = expr.value;
15491 t = c_fully_fold (t, false, NULL);
15492
15493 if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
15494 error_at (here, "schedule %<runtime%> does not take "
15495 "a %<chunk_size%> parameter");
15496 else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO)
15497 error_at (here,
15498 "schedule %<auto%> does not take "
15499 "a %<chunk_size%> parameter");
15500 else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE)
15501 {
15502 /* Attempt to statically determine when the number isn't
15503 positive. */
15504 tree s = fold_build2_loc (loc, LE_EXPR, boolean_type_node, t,
15505 build_int_cst (TREE_TYPE (t), 0));
15506 protected_set_expr_location (s, loc);
15507 if (s == boolean_true_node)
15508 {
15509 warning_at (loc, 0,
15510 "chunk size value must be positive");
15511 t = integer_one_node;
15512 }
15513 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
15514 }
15515 else
15516 c_parser_error (parser, "expected integer expression");
15517
15518 parens.skip_until_found_close (parser);
15519 }
15520 else
15521 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
15522 "expected %<,%> or %<)%>");
15523
15524 OMP_CLAUSE_SCHEDULE_KIND (c)
15525 = (enum omp_clause_schedule_kind)
15526 (OMP_CLAUSE_SCHEDULE_KIND (c) | modifiers);
15527
15528 check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule");
15529 OMP_CLAUSE_CHAIN (c) = list;
15530 return c;
15531
15532 invalid_kind:
15533 c_parser_error (parser, "invalid schedule kind");
15534 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
15535 return list;
15536 }
15537
15538 /* OpenMP 2.5:
15539 shared ( variable-list ) */
15540
15541 static tree
15542 c_parser_omp_clause_shared (c_parser *parser, tree list)
15543 {
15544 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_SHARED, list);
15545 }
15546
15547 /* OpenMP 3.0:
15548 untied */
15549
15550 static tree
15551 c_parser_omp_clause_untied (c_parser *parser ATTRIBUTE_UNUSED, tree list)
15552 {
15553 tree c;
15554
15555 /* FIXME: Should we allow duplicates? */
15556 check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied");
15557
15558 c = build_omp_clause (c_parser_peek_token (parser)->location,
15559 OMP_CLAUSE_UNTIED);
15560 OMP_CLAUSE_CHAIN (c) = list;
15561
15562 return c;
15563 }
15564
15565 /* OpenMP 4.0:
15566 inbranch
15567 notinbranch */
15568
15569 static tree
15570 c_parser_omp_clause_branch (c_parser *parser ATTRIBUTE_UNUSED,
15571 enum omp_clause_code code, tree list)
15572 {
15573 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
15574
15575 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15576 OMP_CLAUSE_CHAIN (c) = list;
15577
15578 return c;
15579 }
15580
15581 /* OpenMP 4.0:
15582 parallel
15583 for
15584 sections
15585 taskgroup */
15586
15587 static tree
15588 c_parser_omp_clause_cancelkind (c_parser *parser ATTRIBUTE_UNUSED,
15589 enum omp_clause_code code, tree list)
15590 {
15591 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15592 OMP_CLAUSE_CHAIN (c) = list;
15593
15594 return c;
15595 }
15596
15597 /* OpenMP 4.5:
15598 nogroup */
15599
15600 static tree
15601 c_parser_omp_clause_nogroup (c_parser *parser ATTRIBUTE_UNUSED, tree list)
15602 {
15603 check_no_duplicate_clause (list, OMP_CLAUSE_NOGROUP, "nogroup");
15604 tree c = build_omp_clause (c_parser_peek_token (parser)->location,
15605 OMP_CLAUSE_NOGROUP);
15606 OMP_CLAUSE_CHAIN (c) = list;
15607 return c;
15608 }
15609
15610 /* OpenMP 4.5:
15611 simd
15612 threads */
15613
15614 static tree
15615 c_parser_omp_clause_orderedkind (c_parser *parser ATTRIBUTE_UNUSED,
15616 enum omp_clause_code code, tree list)
15617 {
15618 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
15619 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15620 OMP_CLAUSE_CHAIN (c) = list;
15621 return c;
15622 }
15623
15624 /* OpenMP 4.0:
15625 num_teams ( expression )
15626
15627 OpenMP 5.1:
15628 num_teams ( expression : expression ) */
15629
15630 static tree
15631 c_parser_omp_clause_num_teams (c_parser *parser, tree list)
15632 {
15633 location_t num_teams_loc = c_parser_peek_token (parser)->location;
15634 matching_parens parens;
15635 if (parens.require_open (parser))
15636 {
15637 location_t upper_loc = c_parser_peek_token (parser)->location;
15638 location_t lower_loc = UNKNOWN_LOCATION;
15639 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15640 expr = convert_lvalue_to_rvalue (upper_loc, expr, false, true);
15641 tree c, upper = expr.value, lower = NULL_TREE;
15642 upper = c_fully_fold (upper, false, NULL);
15643
15644 if (c_parser_next_token_is (parser, CPP_COLON))
15645 {
15646 c_parser_consume_token (parser);
15647 lower_loc = upper_loc;
15648 lower = upper;
15649 upper_loc = c_parser_peek_token (parser)->location;
15650 expr = c_parser_expr_no_commas (parser, NULL);
15651 expr = convert_lvalue_to_rvalue (upper_loc, expr, false, true);
15652 upper = expr.value;
15653 upper = c_fully_fold (upper, false, NULL);
15654 }
15655
15656 parens.skip_until_found_close (parser);
15657
15658 if (!INTEGRAL_TYPE_P (TREE_TYPE (upper))
15659 || (lower && !INTEGRAL_TYPE_P (TREE_TYPE (lower))))
15660 {
15661 c_parser_error (parser, "expected integer expression");
15662 return list;
15663 }
15664
15665 /* Attempt to statically determine when the number isn't positive. */
15666 c = fold_build2_loc (upper_loc, LE_EXPR, boolean_type_node, upper,
15667 build_int_cst (TREE_TYPE (upper), 0));
15668 protected_set_expr_location (c, upper_loc);
15669 if (c == boolean_true_node)
15670 {
15671 warning_at (upper_loc, 0, "%<num_teams%> value must be positive");
15672 upper = integer_one_node;
15673 }
15674 if (lower)
15675 {
15676 c = fold_build2_loc (lower_loc, LE_EXPR, boolean_type_node, lower,
15677 build_int_cst (TREE_TYPE (lower), 0));
15678 protected_set_expr_location (c, lower_loc);
15679 if (c == boolean_true_node)
15680 {
15681 warning_at (lower_loc, 0, "%<num_teams%> value must be positive");
15682 lower = NULL_TREE;
15683 }
15684 else if (TREE_CODE (lower) == INTEGER_CST
15685 && TREE_CODE (upper) == INTEGER_CST
15686 && tree_int_cst_lt (upper, lower))
15687 {
15688 warning_at (lower_loc, 0, "%<num_teams%> lower bound %qE bigger "
15689 "than upper bound %qE", lower, upper);
15690 lower = NULL_TREE;
15691 }
15692 }
15693
15694 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TEAMS, "num_teams");
15695
15696 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
15697 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = upper;
15698 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = lower;
15699 OMP_CLAUSE_CHAIN (c) = list;
15700 list = c;
15701 }
15702
15703 return list;
15704 }
15705
15706 /* OpenMP 4.0:
15707 thread_limit ( expression ) */
15708
15709 static tree
15710 c_parser_omp_clause_thread_limit (c_parser *parser, tree list)
15711 {
15712 location_t num_thread_limit_loc = c_parser_peek_token (parser)->location;
15713 matching_parens parens;
15714 if (parens.require_open (parser))
15715 {
15716 location_t expr_loc = c_parser_peek_token (parser)->location;
15717 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15718 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15719 tree c, t = expr.value;
15720 t = c_fully_fold (t, false, NULL);
15721
15722 parens.skip_until_found_close (parser);
15723
15724 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
15725 {
15726 c_parser_error (parser, "expected integer expression");
15727 return list;
15728 }
15729
15730 /* Attempt to statically determine when the number isn't positive. */
15731 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
15732 build_int_cst (TREE_TYPE (t), 0));
15733 protected_set_expr_location (c, expr_loc);
15734 if (c == boolean_true_node)
15735 {
15736 warning_at (expr_loc, 0, "%<thread_limit%> value must be positive");
15737 t = integer_one_node;
15738 }
15739
15740 check_no_duplicate_clause (list, OMP_CLAUSE_THREAD_LIMIT,
15741 "thread_limit");
15742
15743 c = build_omp_clause (num_thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
15744 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
15745 OMP_CLAUSE_CHAIN (c) = list;
15746 list = c;
15747 }
15748
15749 return list;
15750 }
15751
15752 /* OpenMP 4.0:
15753 aligned ( variable-list )
15754 aligned ( variable-list : constant-expression ) */
15755
15756 static tree
15757 c_parser_omp_clause_aligned (c_parser *parser, tree list)
15758 {
15759 location_t clause_loc = c_parser_peek_token (parser)->location;
15760 tree nl, c;
15761
15762 matching_parens parens;
15763 if (!parens.require_open (parser))
15764 return list;
15765
15766 nl = c_parser_omp_variable_list (parser, clause_loc,
15767 OMP_CLAUSE_ALIGNED, list);
15768
15769 if (c_parser_next_token_is (parser, CPP_COLON))
15770 {
15771 c_parser_consume_token (parser);
15772 location_t expr_loc = c_parser_peek_token (parser)->location;
15773 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15774 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15775 tree alignment = expr.value;
15776 alignment = c_fully_fold (alignment, false, NULL);
15777 if (TREE_CODE (alignment) != INTEGER_CST
15778 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment))
15779 || tree_int_cst_sgn (alignment) != 1)
15780 {
15781 error_at (clause_loc, "%<aligned%> clause alignment expression must "
15782 "be positive constant integer expression");
15783 alignment = NULL_TREE;
15784 }
15785
15786 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15787 OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = alignment;
15788 }
15789
15790 parens.skip_until_found_close (parser);
15791 return nl;
15792 }
15793
15794 /* OpenMP 5.0:
15795 allocate ( variable-list )
15796 allocate ( expression : variable-list )
15797
15798 OpenMP 5.1:
15799 allocate ( allocator-modifier : variable-list )
15800 allocate ( allocator-modifier , allocator-modifier : variable-list )
15801
15802 allocator-modifier:
15803 allocator ( expression )
15804 align ( expression ) */
15805
15806 static tree
15807 c_parser_omp_clause_allocate (c_parser *parser, tree list)
15808 {
15809 location_t clause_loc = c_parser_peek_token (parser)->location;
15810 tree nl, c;
15811 tree allocator = NULL_TREE;
15812 tree align = NULL_TREE;
15813
15814 matching_parens parens;
15815 if (!parens.require_open (parser))
15816 return list;
15817
15818 if ((c_parser_next_token_is_not (parser, CPP_NAME)
15819 && c_parser_next_token_is_not (parser, CPP_KEYWORD))
15820 || (c_parser_peek_2nd_token (parser)->type != CPP_COMMA
15821 && c_parser_peek_2nd_token (parser)->type != CPP_CLOSE_PAREN))
15822 {
15823 bool has_modifiers = false;
15824 tree orig_type = NULL_TREE;
15825 if (c_parser_next_token_is (parser, CPP_NAME)
15826 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
15827 {
15828 unsigned int n = 3;
15829 const char *p
15830 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15831 if ((strcmp (p, "allocator") == 0 || strcmp (p, "align") == 0)
15832 && c_parser_check_balanced_raw_token_sequence (parser, &n)
15833 && (c_parser_peek_nth_token_raw (parser, n)->type
15834 == CPP_CLOSE_PAREN))
15835 {
15836 if (c_parser_peek_nth_token_raw (parser, n + 1)->type
15837 == CPP_COLON)
15838 has_modifiers = true;
15839 else if (c_parser_peek_nth_token_raw (parser, n + 1)->type
15840 == CPP_COMMA
15841 && (c_parser_peek_nth_token_raw (parser, n + 2)->type
15842 == CPP_NAME)
15843 && (c_parser_peek_nth_token_raw (parser, n + 3)->type
15844 == CPP_OPEN_PAREN))
15845 {
15846 c_token *tok = c_parser_peek_nth_token_raw (parser, n + 2);
15847 const char *q = IDENTIFIER_POINTER (tok->value);
15848 n += 4;
15849 if ((strcmp (q, "allocator") == 0
15850 || strcmp (q, "align") == 0)
15851 && c_parser_check_balanced_raw_token_sequence (parser,
15852 &n)
15853 && (c_parser_peek_nth_token_raw (parser, n)->type
15854 == CPP_CLOSE_PAREN)
15855 && (c_parser_peek_nth_token_raw (parser, n + 1)->type
15856 == CPP_COLON))
15857 has_modifiers = true;
15858 }
15859 }
15860 if (has_modifiers)
15861 {
15862 c_parser_consume_token (parser);
15863 matching_parens parens2;;
15864 parens2.require_open (parser);
15865 location_t expr_loc = c_parser_peek_token (parser)->location;
15866 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15867 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15868 if (strcmp (p, "allocator") == 0)
15869 {
15870 allocator = expr.value;
15871 allocator = c_fully_fold (allocator, false, NULL);
15872 orig_type = expr.original_type
15873 ? expr.original_type : TREE_TYPE (allocator);
15874 orig_type = TYPE_MAIN_VARIANT (orig_type);
15875 }
15876 else
15877 {
15878 align = expr.value;
15879 align = c_fully_fold (align, false, NULL);
15880 }
15881 parens2.skip_until_found_close (parser);
15882 if (c_parser_next_token_is (parser, CPP_COMMA))
15883 {
15884 c_parser_consume_token (parser);
15885 c_token *tok = c_parser_peek_token (parser);
15886 const char *q = "";
15887 if (c_parser_next_token_is (parser, CPP_NAME))
15888 q = IDENTIFIER_POINTER (tok->value);
15889 if (strcmp (q, "allocator") != 0 && strcmp (q, "align") != 0)
15890 {
15891 c_parser_error (parser, "expected %<allocator%> or "
15892 "%<align%>");
15893 parens.skip_until_found_close (parser);
15894 return list;
15895 }
15896 else if (strcmp (p, q) == 0)
15897 {
15898 error_at (tok->location, "duplicate %qs modifier", p);
15899 parens.skip_until_found_close (parser);
15900 return list;
15901 }
15902 c_parser_consume_token (parser);
15903 if (!parens2.require_open (parser))
15904 {
15905 parens.skip_until_found_close (parser);
15906 return list;
15907 }
15908 expr_loc = c_parser_peek_token (parser)->location;
15909 expr = c_parser_expr_no_commas (parser, NULL);
15910 expr = convert_lvalue_to_rvalue (expr_loc, expr, false,
15911 true);
15912 if (strcmp (q, "allocator") == 0)
15913 {
15914 allocator = expr.value;
15915 allocator = c_fully_fold (allocator, false, NULL);
15916 orig_type = expr.original_type
15917 ? expr.original_type : TREE_TYPE (allocator);
15918 orig_type = TYPE_MAIN_VARIANT (orig_type);
15919 }
15920 else
15921 {
15922 align = expr.value;
15923 align = c_fully_fold (align, false, NULL);
15924 }
15925 parens2.skip_until_found_close (parser);
15926 }
15927 }
15928 }
15929 if (!has_modifiers)
15930 {
15931 location_t expr_loc = c_parser_peek_token (parser)->location;
15932 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15933 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15934 allocator = expr.value;
15935 allocator = c_fully_fold (allocator, false, NULL);
15936 orig_type = expr.original_type
15937 ? expr.original_type : TREE_TYPE (allocator);
15938 orig_type = TYPE_MAIN_VARIANT (orig_type);
15939 }
15940 if (allocator
15941 && (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
15942 || TREE_CODE (orig_type) != ENUMERAL_TYPE
15943 || (TYPE_NAME (orig_type)
15944 != get_identifier ("omp_allocator_handle_t"))))
15945 {
15946 error_at (clause_loc, "%<allocate%> clause allocator expression "
15947 "has type %qT rather than "
15948 "%<omp_allocator_handle_t%>",
15949 TREE_TYPE (allocator));
15950 allocator = NULL_TREE;
15951 }
15952 if (align
15953 && (!INTEGRAL_TYPE_P (TREE_TYPE (align))
15954 || !tree_fits_uhwi_p (align)
15955 || !integer_pow2p (align)))
15956 {
15957 error_at (clause_loc, "%<allocate%> clause %<align%> modifier "
15958 "argument needs to be positive constant "
15959 "power of two integer expression");
15960 align = NULL_TREE;
15961 }
15962 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15963 {
15964 parens.skip_until_found_close (parser);
15965 return list;
15966 }
15967 }
15968
15969 nl = c_parser_omp_variable_list (parser, clause_loc,
15970 OMP_CLAUSE_ALLOCATE, list);
15971
15972 if (allocator || align)
15973 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15974 {
15975 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
15976 OMP_CLAUSE_ALLOCATE_ALIGN (c) = align;
15977 }
15978
15979 parens.skip_until_found_close (parser);
15980 return nl;
15981 }
15982
15983 /* OpenMP 4.0:
15984 linear ( variable-list )
15985 linear ( variable-list : expression )
15986
15987 OpenMP 4.5:
15988 linear ( modifier ( variable-list ) )
15989 linear ( modifier ( variable-list ) : expression )
15990
15991 modifier:
15992 val
15993
15994 OpenMP 5.2:
15995 linear ( variable-list : modifiers-list )
15996
15997 modifiers:
15998 val
15999 step ( expression ) */
16000
16001 static tree
16002 c_parser_omp_clause_linear (c_parser *parser, tree list)
16003 {
16004 location_t clause_loc = c_parser_peek_token (parser)->location;
16005 tree nl, c, step;
16006 enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
16007 bool old_linear_modifier = false;
16008
16009 matching_parens parens;
16010 if (!parens.require_open (parser))
16011 return list;
16012
16013 if (c_parser_next_token_is (parser, CPP_NAME))
16014 {
16015 c_token *tok = c_parser_peek_token (parser);
16016 const char *p = IDENTIFIER_POINTER (tok->value);
16017 if (strcmp ("val", p) == 0)
16018 kind = OMP_CLAUSE_LINEAR_VAL;
16019 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN)
16020 kind = OMP_CLAUSE_LINEAR_DEFAULT;
16021 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
16022 {
16023 old_linear_modifier = true;
16024 c_parser_consume_token (parser);
16025 c_parser_consume_token (parser);
16026 }
16027 }
16028
16029 nl = c_parser_omp_variable_list (parser, clause_loc,
16030 OMP_CLAUSE_LINEAR, list);
16031
16032 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
16033 parens.skip_until_found_close (parser);
16034
16035 if (c_parser_next_token_is (parser, CPP_COLON))
16036 {
16037 c_parser_consume_token (parser);
16038 location_t expr_loc = c_parser_peek_token (parser)->location;
16039 bool has_modifiers = false;
16040 if (kind == OMP_CLAUSE_LINEAR_DEFAULT
16041 && c_parser_next_token_is (parser, CPP_NAME))
16042 {
16043 c_token *tok = c_parser_peek_token (parser);
16044 const char *p = IDENTIFIER_POINTER (tok->value);
16045 unsigned int pos = 0;
16046 if (strcmp ("val", p) == 0)
16047 pos = 2;
16048 else if (strcmp ("step", p) == 0
16049 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
16050 {
16051 pos = 3;
16052 if (c_parser_check_balanced_raw_token_sequence (parser, &pos)
16053 && (c_parser_peek_nth_token_raw (parser, pos)->type
16054 == CPP_CLOSE_PAREN))
16055 ++pos;
16056 else
16057 pos = 0;
16058 }
16059 if (pos)
16060 {
16061 tok = c_parser_peek_nth_token_raw (parser, pos);
16062 if (tok->type == CPP_COMMA || tok->type == CPP_CLOSE_PAREN)
16063 has_modifiers = true;
16064 }
16065 }
16066 if (has_modifiers)
16067 {
16068 step = NULL_TREE;
16069 while (c_parser_next_token_is (parser, CPP_NAME))
16070 {
16071 c_token *tok = c_parser_peek_token (parser);
16072 const char *p = IDENTIFIER_POINTER (tok->value);
16073 if (strcmp ("val", p) == 0)
16074 {
16075 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
16076 error_at (tok->location, "multiple linear modifiers");
16077 kind = OMP_CLAUSE_LINEAR_DEFAULT;
16078 c_parser_consume_token (parser);
16079 }
16080 else if (strcmp ("step", p) == 0)
16081 {
16082 c_parser_consume_token (parser);
16083 matching_parens parens2;
16084 if (parens2.require_open (parser))
16085 {
16086 if (step)
16087 error_at (tok->location,
16088 "multiple %<step%> modifiers");
16089 expr_loc = c_parser_peek_token (parser)->location;
16090 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16091 expr = convert_lvalue_to_rvalue (expr_loc, expr, false,
16092 true);
16093 step = c_fully_fold (expr.value, false, NULL);
16094 if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
16095 {
16096 error_at (clause_loc, "%<linear%> clause step "
16097 "expression must be integral");
16098 step = integer_one_node;
16099 }
16100 parens2.skip_until_found_close (parser);
16101 }
16102 else
16103 break;
16104 }
16105 else
16106 break;
16107 if (c_parser_next_token_is (parser, CPP_COMMA))
16108 {
16109 c_parser_consume_token (parser);
16110 continue;
16111 }
16112 break;
16113 }
16114 if (!step)
16115 step = integer_one_node;
16116 }
16117 else
16118 {
16119 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16120 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16121 step = c_fully_fold (expr.value, false, NULL);
16122 if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
16123 {
16124 error_at (clause_loc, "%<linear%> clause step expression must "
16125 "be integral");
16126 step = integer_one_node;
16127 }
16128 }
16129
16130 }
16131 else
16132 step = integer_one_node;
16133
16134 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
16135 {
16136 OMP_CLAUSE_LINEAR_STEP (c) = step;
16137 OMP_CLAUSE_LINEAR_KIND (c) = kind;
16138 OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c) = old_linear_modifier;
16139 }
16140
16141 parens.skip_until_found_close (parser);
16142 return nl;
16143 }
16144
16145 /* OpenMP 5.0:
16146 nontemporal ( variable-list ) */
16147
16148 static tree
16149 c_parser_omp_clause_nontemporal (c_parser *parser, tree list)
16150 {
16151 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_NONTEMPORAL, list);
16152 }
16153
16154 /* OpenMP 4.0:
16155 safelen ( constant-expression ) */
16156
16157 static tree
16158 c_parser_omp_clause_safelen (c_parser *parser, tree list)
16159 {
16160 location_t clause_loc = c_parser_peek_token (parser)->location;
16161 tree c, t;
16162
16163 matching_parens parens;
16164 if (!parens.require_open (parser))
16165 return list;
16166
16167 location_t expr_loc = c_parser_peek_token (parser)->location;
16168 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16169 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16170 t = expr.value;
16171 t = c_fully_fold (t, false, NULL);
16172 if (TREE_CODE (t) != INTEGER_CST
16173 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
16174 || tree_int_cst_sgn (t) != 1)
16175 {
16176 error_at (clause_loc, "%<safelen%> clause expression must "
16177 "be positive constant integer expression");
16178 t = NULL_TREE;
16179 }
16180
16181 parens.skip_until_found_close (parser);
16182 if (t == NULL_TREE || t == error_mark_node)
16183 return list;
16184
16185 check_no_duplicate_clause (list, OMP_CLAUSE_SAFELEN, "safelen");
16186
16187 c = build_omp_clause (clause_loc, OMP_CLAUSE_SAFELEN);
16188 OMP_CLAUSE_SAFELEN_EXPR (c) = t;
16189 OMP_CLAUSE_CHAIN (c) = list;
16190 return c;
16191 }
16192
16193 /* OpenMP 4.0:
16194 simdlen ( constant-expression ) */
16195
16196 static tree
16197 c_parser_omp_clause_simdlen (c_parser *parser, tree list)
16198 {
16199 location_t clause_loc = c_parser_peek_token (parser)->location;
16200 tree c, t;
16201
16202 matching_parens parens;
16203 if (!parens.require_open (parser))
16204 return list;
16205
16206 location_t expr_loc = c_parser_peek_token (parser)->location;
16207 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16208 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16209 t = expr.value;
16210 t = c_fully_fold (t, false, NULL);
16211 if (TREE_CODE (t) != INTEGER_CST
16212 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
16213 || tree_int_cst_sgn (t) != 1)
16214 {
16215 error_at (clause_loc, "%<simdlen%> clause expression must "
16216 "be positive constant integer expression");
16217 t = NULL_TREE;
16218 }
16219
16220 parens.skip_until_found_close (parser);
16221 if (t == NULL_TREE || t == error_mark_node)
16222 return list;
16223
16224 check_no_duplicate_clause (list, OMP_CLAUSE_SIMDLEN, "simdlen");
16225
16226 c = build_omp_clause (clause_loc, OMP_CLAUSE_SIMDLEN);
16227 OMP_CLAUSE_SIMDLEN_EXPR (c) = t;
16228 OMP_CLAUSE_CHAIN (c) = list;
16229 return c;
16230 }
16231
16232 /* OpenMP 4.5:
16233 vec:
16234 identifier [+/- integer]
16235 vec , identifier [+/- integer]
16236 */
16237
16238 static tree
16239 c_parser_omp_clause_doacross_sink (c_parser *parser, location_t clause_loc,
16240 tree list, bool depend_p)
16241 {
16242 tree vec = NULL;
16243 if (c_parser_next_token_is_not (parser, CPP_NAME)
16244 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
16245 {
16246 c_parser_error (parser, "expected identifier");
16247 return list;
16248 }
16249
16250 if (!depend_p)
16251 {
16252 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16253 if (strcmp (p, "omp_cur_iteration") == 0
16254 && c_parser_peek_2nd_token (parser)->type == CPP_MINUS
16255 && c_parser_peek_nth_token (parser, 3)->type == CPP_NUMBER
16256 && c_parser_peek_nth_token (parser, 4)->type == CPP_CLOSE_PAREN)
16257 {
16258 tree val = c_parser_peek_nth_token (parser, 3)->value;
16259 if (integer_onep (val))
16260 {
16261 c_parser_consume_token (parser);
16262 c_parser_consume_token (parser);
16263 c_parser_consume_token (parser);
16264 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
16265 OMP_CLAUSE_DOACROSS_KIND (u) = OMP_CLAUSE_DOACROSS_SINK;
16266 OMP_CLAUSE_CHAIN (u) = list;
16267 return u;
16268 }
16269 }
16270 }
16271
16272
16273
16274 while (c_parser_next_token_is (parser, CPP_NAME)
16275 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
16276 {
16277 tree t = lookup_name (c_parser_peek_token (parser)->value);
16278 tree addend = NULL;
16279
16280 if (t == NULL_TREE)
16281 {
16282 undeclared_variable (c_parser_peek_token (parser)->location,
16283 c_parser_peek_token (parser)->value);
16284 t = error_mark_node;
16285 }
16286
16287 c_parser_consume_token (parser);
16288
16289 bool neg = false;
16290 if (c_parser_next_token_is (parser, CPP_MINUS))
16291 neg = true;
16292 else if (!c_parser_next_token_is (parser, CPP_PLUS))
16293 {
16294 addend = integer_zero_node;
16295 neg = false;
16296 goto add_to_vector;
16297 }
16298 c_parser_consume_token (parser);
16299
16300 if (c_parser_next_token_is_not (parser, CPP_NUMBER))
16301 {
16302 c_parser_error (parser, "expected integer");
16303 return list;
16304 }
16305
16306 addend = c_parser_peek_token (parser)->value;
16307 if (TREE_CODE (addend) != INTEGER_CST)
16308 {
16309 c_parser_error (parser, "expected integer");
16310 return list;
16311 }
16312 c_parser_consume_token (parser);
16313
16314 add_to_vector:
16315 if (t != error_mark_node)
16316 {
16317 vec = tree_cons (addend, t, vec);
16318 if (neg)
16319 OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (vec) = 1;
16320 }
16321
16322 if (c_parser_next_token_is_not (parser, CPP_COMMA)
16323 || c_parser_peek_2nd_token (parser)->type != CPP_NAME
16324 || c_parser_peek_2nd_token (parser)->id_kind != C_ID_ID)
16325 break;
16326
16327 c_parser_consume_token (parser);
16328 }
16329
16330 if (vec == NULL_TREE)
16331 return list;
16332
16333 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
16334 OMP_CLAUSE_DOACROSS_KIND (u) = OMP_CLAUSE_DOACROSS_SINK;
16335 OMP_CLAUSE_DOACROSS_DEPEND (u) = depend_p;
16336 OMP_CLAUSE_DECL (u) = nreverse (vec);
16337 OMP_CLAUSE_CHAIN (u) = list;
16338 return u;
16339 }
16340
16341 /* OpenMP 5.0:
16342 iterators ( iterators-definition )
16343
16344 iterators-definition:
16345 iterator-specifier
16346 iterator-specifier , iterators-definition
16347
16348 iterator-specifier:
16349 identifier = range-specification
16350 iterator-type identifier = range-specification
16351
16352 range-specification:
16353 begin : end
16354 begin : end : step */
16355
16356 static tree
16357 c_parser_omp_iterators (c_parser *parser)
16358 {
16359 tree ret = NULL_TREE, *last = &ret;
16360 c_parser_consume_token (parser);
16361
16362 push_scope ();
16363
16364 matching_parens parens;
16365 if (!parens.require_open (parser))
16366 return error_mark_node;
16367
16368 do
16369 {
16370 tree iter_type = NULL_TREE, type_expr = NULL_TREE;
16371 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
16372 {
16373 struct c_type_name *type = c_parser_type_name (parser);
16374 if (type != NULL)
16375 iter_type = groktypename (type, &type_expr, NULL);
16376 }
16377 if (iter_type == NULL_TREE)
16378 iter_type = integer_type_node;
16379
16380 location_t loc = c_parser_peek_token (parser)->location;
16381 if (!c_parser_next_token_is (parser, CPP_NAME))
16382 {
16383 c_parser_error (parser, "expected identifier");
16384 break;
16385 }
16386
16387 tree id = c_parser_peek_token (parser)->value;
16388 c_parser_consume_token (parser);
16389
16390 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
16391 break;
16392
16393 location_t eloc = c_parser_peek_token (parser)->location;
16394 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16395 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
16396 tree begin = expr.value;
16397
16398 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16399 break;
16400
16401 eloc = c_parser_peek_token (parser)->location;
16402 expr = c_parser_expr_no_commas (parser, NULL);
16403 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
16404 tree end = expr.value;
16405
16406 tree step = integer_one_node;
16407 if (c_parser_next_token_is (parser, CPP_COLON))
16408 {
16409 c_parser_consume_token (parser);
16410 eloc = c_parser_peek_token (parser)->location;
16411 expr = c_parser_expr_no_commas (parser, NULL);
16412 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
16413 step = expr.value;
16414 }
16415
16416 tree iter_var = build_decl (loc, VAR_DECL, id, iter_type);
16417 DECL_ARTIFICIAL (iter_var) = 1;
16418 DECL_CONTEXT (iter_var) = current_function_decl;
16419 pushdecl (iter_var);
16420
16421 *last = make_tree_vec (6);
16422 TREE_VEC_ELT (*last, 0) = iter_var;
16423 TREE_VEC_ELT (*last, 1) = begin;
16424 TREE_VEC_ELT (*last, 2) = end;
16425 TREE_VEC_ELT (*last, 3) = step;
16426 last = &TREE_CHAIN (*last);
16427
16428 if (c_parser_next_token_is (parser, CPP_COMMA))
16429 {
16430 c_parser_consume_token (parser);
16431 continue;
16432 }
16433 break;
16434 }
16435 while (1);
16436
16437 parens.skip_until_found_close (parser);
16438 return ret ? ret : error_mark_node;
16439 }
16440
16441 /* OpenMP 5.0:
16442 affinity ( [aff-modifier :] variable-list )
16443 aff-modifier:
16444 iterator ( iterators-definition ) */
16445
16446 static tree
16447 c_parser_omp_clause_affinity (c_parser *parser, tree list)
16448 {
16449 location_t clause_loc = c_parser_peek_token (parser)->location;
16450 tree nl, iterators = NULL_TREE;
16451
16452 matching_parens parens;
16453 if (!parens.require_open (parser))
16454 return list;
16455
16456 if (c_parser_next_token_is (parser, CPP_NAME))
16457 {
16458 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16459 bool parse_iter = ((strcmp ("iterator", p) == 0)
16460 && (c_parser_peek_2nd_token (parser)->type
16461 == CPP_OPEN_PAREN));
16462 if (parse_iter)
16463 {
16464 unsigned n = 3;
16465 parse_iter = (c_parser_check_balanced_raw_token_sequence (parser, &n)
16466 && (c_parser_peek_nth_token_raw (parser, n)->type
16467 == CPP_CLOSE_PAREN)
16468 && (c_parser_peek_nth_token_raw (parser, n + 1)->type
16469 == CPP_COLON));
16470 }
16471 if (parse_iter)
16472 {
16473 iterators = c_parser_omp_iterators (parser);
16474 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16475 {
16476 if (iterators)
16477 pop_scope ();
16478 parens.skip_until_found_close (parser);
16479 return list;
16480 }
16481 }
16482 }
16483 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_AFFINITY,
16484 list);
16485 if (iterators)
16486 {
16487 tree block = pop_scope ();
16488 if (iterators != error_mark_node)
16489 {
16490 TREE_VEC_ELT (iterators, 5) = block;
16491 for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
16492 OMP_CLAUSE_DECL (c) = build_tree_list (iterators,
16493 OMP_CLAUSE_DECL (c));
16494 }
16495 }
16496
16497 parens.skip_until_found_close (parser);
16498 return nl;
16499 }
16500
16501
16502 /* OpenMP 4.0:
16503 depend ( depend-kind: variable-list )
16504
16505 depend-kind:
16506 in | out | inout
16507
16508 OpenMP 4.5:
16509 depend ( source )
16510
16511 depend ( sink : vec )
16512
16513 OpenMP 5.0:
16514 depend ( depend-modifier , depend-kind: variable-list )
16515
16516 depend-kind:
16517 in | out | inout | mutexinoutset | depobj | inoutset
16518
16519 depend-modifier:
16520 iterator ( iterators-definition ) */
16521
16522 static tree
16523 c_parser_omp_clause_depend (c_parser *parser, tree list)
16524 {
16525 location_t clause_loc = c_parser_peek_token (parser)->location;
16526 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_LAST;
16527 enum omp_clause_doacross_kind dkind = OMP_CLAUSE_DOACROSS_LAST;
16528 tree nl, c, iterators = NULL_TREE;
16529
16530 matching_parens parens;
16531 if (!parens.require_open (parser))
16532 return list;
16533
16534 do
16535 {
16536 if (c_parser_next_token_is_not (parser, CPP_NAME))
16537 goto invalid_kind;
16538
16539 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16540 if (strcmp ("iterator", p) == 0 && iterators == NULL_TREE)
16541 {
16542 iterators = c_parser_omp_iterators (parser);
16543 c_parser_require (parser, CPP_COMMA, "expected %<,%>");
16544 continue;
16545 }
16546 if (strcmp ("in", p) == 0)
16547 kind = OMP_CLAUSE_DEPEND_IN;
16548 else if (strcmp ("inout", p) == 0)
16549 kind = OMP_CLAUSE_DEPEND_INOUT;
16550 else if (strcmp ("inoutset", p) == 0)
16551 kind = OMP_CLAUSE_DEPEND_INOUTSET;
16552 else if (strcmp ("mutexinoutset", p) == 0)
16553 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
16554 else if (strcmp ("out", p) == 0)
16555 kind = OMP_CLAUSE_DEPEND_OUT;
16556 else if (strcmp ("depobj", p) == 0)
16557 kind = OMP_CLAUSE_DEPEND_DEPOBJ;
16558 else if (strcmp ("sink", p) == 0)
16559 dkind = OMP_CLAUSE_DOACROSS_SINK;
16560 else if (strcmp ("source", p) == 0)
16561 dkind = OMP_CLAUSE_DOACROSS_SOURCE;
16562 else
16563 goto invalid_kind;
16564 break;
16565 }
16566 while (1);
16567
16568 c_parser_consume_token (parser);
16569
16570 if (iterators
16571 && (dkind == OMP_CLAUSE_DOACROSS_SOURCE
16572 || dkind == OMP_CLAUSE_DOACROSS_SINK))
16573 {
16574 pop_scope ();
16575 error_at (clause_loc, "%<iterator%> modifier incompatible with %qs",
16576 dkind == OMP_CLAUSE_DOACROSS_SOURCE ? "source" : "sink");
16577 iterators = NULL_TREE;
16578 }
16579
16580 if (dkind == OMP_CLAUSE_DOACROSS_SOURCE)
16581 {
16582 c = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
16583 OMP_CLAUSE_DOACROSS_KIND (c) = dkind;
16584 OMP_CLAUSE_DOACROSS_DEPEND (c) = 1;
16585 OMP_CLAUSE_DECL (c) = NULL_TREE;
16586 OMP_CLAUSE_CHAIN (c) = list;
16587 parens.skip_until_found_close (parser);
16588 return c;
16589 }
16590
16591 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16592 goto resync_fail;
16593
16594 if (dkind == OMP_CLAUSE_DOACROSS_SINK)
16595 nl = c_parser_omp_clause_doacross_sink (parser, clause_loc, list, true);
16596 else
16597 {
16598 nl = c_parser_omp_variable_list (parser, clause_loc,
16599 OMP_CLAUSE_DEPEND, list);
16600
16601 if (iterators)
16602 {
16603 tree block = pop_scope ();
16604 if (iterators == error_mark_node)
16605 iterators = NULL_TREE;
16606 else
16607 TREE_VEC_ELT (iterators, 5) = block;
16608 }
16609
16610 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
16611 {
16612 OMP_CLAUSE_DEPEND_KIND (c) = kind;
16613 if (iterators)
16614 OMP_CLAUSE_DECL (c)
16615 = build_tree_list (iterators, OMP_CLAUSE_DECL (c));
16616 }
16617 }
16618
16619 parens.skip_until_found_close (parser);
16620 return nl;
16621
16622 invalid_kind:
16623 c_parser_error (parser, "invalid depend kind");
16624 resync_fail:
16625 parens.skip_until_found_close (parser);
16626 if (iterators)
16627 pop_scope ();
16628 return list;
16629 }
16630
16631 /* OpenMP 5.2:
16632 doacross ( source : )
16633 doacross ( source : omp_cur_iteration )
16634
16635 doacross ( sink : vec )
16636 doacross ( sink : omp_cur_iteration - logical_iteration ) */
16637
16638 static tree
16639 c_parser_omp_clause_doacross (c_parser *parser, tree list)
16640 {
16641 location_t clause_loc = c_parser_peek_token (parser)->location;
16642 enum omp_clause_doacross_kind kind = OMP_CLAUSE_DOACROSS_LAST;
16643 tree nl;
16644 const char *p;
16645
16646 matching_parens parens;
16647 if (!parens.require_open (parser))
16648 return list;
16649
16650 if (c_parser_next_token_is_not (parser, CPP_NAME))
16651 goto invalid_kind;
16652
16653 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16654 if (strcmp ("sink", p) == 0)
16655 kind = OMP_CLAUSE_DOACROSS_SINK;
16656 else if (strcmp ("source", p) == 0)
16657 kind = OMP_CLAUSE_DOACROSS_SOURCE;
16658 else
16659 goto invalid_kind;
16660
16661 c_parser_consume_token (parser);
16662
16663 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16664 goto resync_fail;
16665
16666 if (kind == OMP_CLAUSE_DOACROSS_SOURCE)
16667 {
16668 if (c_parser_next_token_is (parser, CPP_NAME)
16669 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
16670 "omp_cur_iteration") == 0)
16671 c_parser_consume_token (parser);
16672 nl = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
16673 OMP_CLAUSE_DOACROSS_KIND (nl) = OMP_CLAUSE_DOACROSS_SOURCE;
16674 OMP_CLAUSE_DECL (nl) = NULL_TREE;
16675 OMP_CLAUSE_CHAIN (nl) = list;
16676 }
16677 else
16678 nl = c_parser_omp_clause_doacross_sink (parser, clause_loc, list, false);
16679
16680 parens.skip_until_found_close (parser);
16681 return nl;
16682
16683 invalid_kind:
16684 c_parser_error (parser, "invalid doacross kind");
16685 resync_fail:
16686 parens.skip_until_found_close (parser);
16687 return list;
16688 }
16689
16690 /* OpenMP 4.0:
16691 map ( map-kind: variable-list )
16692 map ( variable-list )
16693
16694 map-kind:
16695 alloc | to | from | tofrom
16696
16697 OpenMP 4.5:
16698 map-kind:
16699 alloc | to | from | tofrom | release | delete
16700
16701 map ( always [,] map-kind: variable-list )
16702
16703 OpenMP 5.0:
16704 map ( [map-type-modifier[,] ...] map-kind: variable-list )
16705
16706 map-type-modifier:
16707 always | close */
16708
16709 static tree
16710 c_parser_omp_clause_map (c_parser *parser, tree list)
16711 {
16712 location_t clause_loc = c_parser_peek_token (parser)->location;
16713 enum gomp_map_kind kind = GOMP_MAP_TOFROM;
16714 tree nl, c;
16715
16716 matching_parens parens;
16717 if (!parens.require_open (parser))
16718 return list;
16719
16720 int pos = 1;
16721 int map_kind_pos = 0;
16722 while (c_parser_peek_nth_token_raw (parser, pos)->type == CPP_NAME)
16723 {
16724 if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COLON)
16725 {
16726 map_kind_pos = pos;
16727 break;
16728 }
16729
16730 if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COMMA)
16731 pos++;
16732 pos++;
16733 }
16734
16735 int always_modifier = 0;
16736 int close_modifier = 0;
16737 for (int pos = 1; pos < map_kind_pos; ++pos)
16738 {
16739 c_token *tok = c_parser_peek_token (parser);
16740
16741 if (tok->type == CPP_COMMA)
16742 {
16743 c_parser_consume_token (parser);
16744 continue;
16745 }
16746
16747 const char *p = IDENTIFIER_POINTER (tok->value);
16748 if (strcmp ("always", p) == 0)
16749 {
16750 if (always_modifier)
16751 {
16752 c_parser_error (parser, "too many %<always%> modifiers");
16753 parens.skip_until_found_close (parser);
16754 return list;
16755 }
16756 always_modifier++;
16757 }
16758 else if (strcmp ("close", p) == 0)
16759 {
16760 if (close_modifier)
16761 {
16762 c_parser_error (parser, "too many %<close%> modifiers");
16763 parens.skip_until_found_close (parser);
16764 return list;
16765 }
16766 close_modifier++;
16767 }
16768 else
16769 {
16770 c_parser_error (parser, "%<#pragma omp target%> with "
16771 "modifier other than %<always%> or "
16772 "%<close%> on %<map%> clause");
16773 parens.skip_until_found_close (parser);
16774 return list;
16775 }
16776
16777 c_parser_consume_token (parser);
16778 }
16779
16780 if (c_parser_next_token_is (parser, CPP_NAME)
16781 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
16782 {
16783 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16784 if (strcmp ("alloc", p) == 0)
16785 kind = GOMP_MAP_ALLOC;
16786 else if (strcmp ("to", p) == 0)
16787 kind = always_modifier ? GOMP_MAP_ALWAYS_TO : GOMP_MAP_TO;
16788 else if (strcmp ("from", p) == 0)
16789 kind = always_modifier ? GOMP_MAP_ALWAYS_FROM : GOMP_MAP_FROM;
16790 else if (strcmp ("tofrom", p) == 0)
16791 kind = always_modifier ? GOMP_MAP_ALWAYS_TOFROM : GOMP_MAP_TOFROM;
16792 else if (strcmp ("release", p) == 0)
16793 kind = GOMP_MAP_RELEASE;
16794 else if (strcmp ("delete", p) == 0)
16795 kind = GOMP_MAP_DELETE;
16796 else
16797 {
16798 c_parser_error (parser, "invalid map kind");
16799 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
16800 "expected %<)%>");
16801 return list;
16802 }
16803 c_parser_consume_token (parser);
16804 c_parser_consume_token (parser);
16805 }
16806
16807 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_MAP, list,
16808 true);
16809
16810 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
16811 OMP_CLAUSE_SET_MAP_KIND (c, kind);
16812
16813 parens.skip_until_found_close (parser);
16814 return nl;
16815 }
16816
16817 /* OpenMP 4.0:
16818 device ( expression )
16819
16820 OpenMP 5.0:
16821 device ( [device-modifier :] integer-expression )
16822
16823 device-modifier:
16824 ancestor | device_num */
16825
16826 static tree
16827 c_parser_omp_clause_device (c_parser *parser, tree list)
16828 {
16829 location_t clause_loc = c_parser_peek_token (parser)->location;
16830 location_t expr_loc;
16831 c_expr expr;
16832 tree c, t;
16833 bool ancestor = false;
16834
16835 matching_parens parens;
16836 if (!parens.require_open (parser))
16837 return list;
16838
16839 if (c_parser_next_token_is (parser, CPP_NAME)
16840 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
16841 {
16842 c_token *tok = c_parser_peek_token (parser);
16843 const char *p = IDENTIFIER_POINTER (tok->value);
16844 if (strcmp ("ancestor", p) == 0)
16845 {
16846 /* A requires directive with the reverse_offload clause must be
16847 specified. */
16848 if ((omp_requires_mask & OMP_REQUIRES_REVERSE_OFFLOAD) == 0)
16849 {
16850 error_at (tok->location, "%<ancestor%> device modifier not "
16851 "preceded by %<requires%> directive "
16852 "with %<reverse_offload%> clause");
16853 parens.skip_until_found_close (parser);
16854 return list;
16855 }
16856 ancestor = true;
16857 }
16858 else if (strcmp ("device_num", p) == 0)
16859 ;
16860 else
16861 {
16862 error_at (tok->location, "expected %<ancestor%> or %<device_num%>");
16863 parens.skip_until_found_close (parser);
16864 return list;
16865 }
16866 c_parser_consume_token (parser);
16867 c_parser_consume_token (parser);
16868 }
16869
16870 expr_loc = c_parser_peek_token (parser)->location;
16871 expr = c_parser_expr_no_commas (parser, NULL);
16872 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16873 t = expr.value;
16874 t = c_fully_fold (t, false, NULL);
16875
16876 parens.skip_until_found_close (parser);
16877
16878 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16879 {
16880 c_parser_error (parser, "expected integer expression");
16881 return list;
16882 }
16883 if (ancestor && TREE_CODE (t) == INTEGER_CST && !integer_onep (t))
16884 {
16885 error_at (expr_loc, "the %<device%> clause expression must evaluate to "
16886 "%<1%>");
16887 return list;
16888 }
16889
16890 check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE, "device");
16891
16892 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE);
16893
16894 OMP_CLAUSE_DEVICE_ID (c) = t;
16895 OMP_CLAUSE_CHAIN (c) = list;
16896 OMP_CLAUSE_DEVICE_ANCESTOR (c) = ancestor;
16897
16898 list = c;
16899 return list;
16900 }
16901
16902 /* OpenMP 4.0:
16903 dist_schedule ( static )
16904 dist_schedule ( static , expression ) */
16905
16906 static tree
16907 c_parser_omp_clause_dist_schedule (c_parser *parser, tree list)
16908 {
16909 tree c, t = NULL_TREE;
16910 location_t loc = c_parser_peek_token (parser)->location;
16911
16912 matching_parens parens;
16913 if (!parens.require_open (parser))
16914 return list;
16915
16916 if (!c_parser_next_token_is_keyword (parser, RID_STATIC))
16917 {
16918 c_parser_error (parser, "invalid dist_schedule kind");
16919 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
16920 "expected %<)%>");
16921 return list;
16922 }
16923
16924 c_parser_consume_token (parser);
16925 if (c_parser_next_token_is (parser, CPP_COMMA))
16926 {
16927 c_parser_consume_token (parser);
16928
16929 location_t expr_loc = c_parser_peek_token (parser)->location;
16930 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16931 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16932 t = expr.value;
16933 t = c_fully_fold (t, false, NULL);
16934 parens.skip_until_found_close (parser);
16935 }
16936 else
16937 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
16938 "expected %<,%> or %<)%>");
16939
16940 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
16941 "dist_schedule"); */
16942 if (omp_find_clause (list, OMP_CLAUSE_DIST_SCHEDULE))
16943 warning_at (loc, 0, "too many %qs clauses", "dist_schedule");
16944 if (t == error_mark_node)
16945 return list;
16946
16947 c = build_omp_clause (loc, OMP_CLAUSE_DIST_SCHEDULE);
16948 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t;
16949 OMP_CLAUSE_CHAIN (c) = list;
16950 return c;
16951 }
16952
16953 /* OpenMP 4.0:
16954 proc_bind ( proc-bind-kind )
16955
16956 proc-bind-kind:
16957 primary | master | close | spread
16958 where OpenMP 5.1 added 'primary' and deprecated the alias 'master'. */
16959
16960 static tree
16961 c_parser_omp_clause_proc_bind (c_parser *parser, tree list)
16962 {
16963 location_t clause_loc = c_parser_peek_token (parser)->location;
16964 enum omp_clause_proc_bind_kind kind;
16965 tree c;
16966
16967 matching_parens parens;
16968 if (!parens.require_open (parser))
16969 return list;
16970
16971 if (c_parser_next_token_is (parser, CPP_NAME))
16972 {
16973 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16974 if (strcmp ("primary", p) == 0)
16975 kind = OMP_CLAUSE_PROC_BIND_PRIMARY;
16976 else if (strcmp ("master", p) == 0)
16977 kind = OMP_CLAUSE_PROC_BIND_MASTER;
16978 else if (strcmp ("close", p) == 0)
16979 kind = OMP_CLAUSE_PROC_BIND_CLOSE;
16980 else if (strcmp ("spread", p) == 0)
16981 kind = OMP_CLAUSE_PROC_BIND_SPREAD;
16982 else
16983 goto invalid_kind;
16984 }
16985 else
16986 goto invalid_kind;
16987
16988 check_no_duplicate_clause (list, OMP_CLAUSE_PROC_BIND, "proc_bind");
16989 c_parser_consume_token (parser);
16990 parens.skip_until_found_close (parser);
16991 c = build_omp_clause (clause_loc, OMP_CLAUSE_PROC_BIND);
16992 OMP_CLAUSE_PROC_BIND_KIND (c) = kind;
16993 OMP_CLAUSE_CHAIN (c) = list;
16994 return c;
16995
16996 invalid_kind:
16997 c_parser_error (parser, "invalid proc_bind kind");
16998 parens.skip_until_found_close (parser);
16999 return list;
17000 }
17001
17002 /* OpenMP 5.0:
17003 device_type ( host | nohost | any ) */
17004
17005 static tree
17006 c_parser_omp_clause_device_type (c_parser *parser, tree list)
17007 {
17008 location_t clause_loc = c_parser_peek_token (parser)->location;
17009 enum omp_clause_device_type_kind kind;
17010 tree c;
17011
17012 matching_parens parens;
17013 if (!parens.require_open (parser))
17014 return list;
17015
17016 if (c_parser_next_token_is (parser, CPP_NAME))
17017 {
17018 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17019 if (strcmp ("host", p) == 0)
17020 kind = OMP_CLAUSE_DEVICE_TYPE_HOST;
17021 else if (strcmp ("nohost", p) == 0)
17022 kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
17023 else if (strcmp ("any", p) == 0)
17024 kind = OMP_CLAUSE_DEVICE_TYPE_ANY;
17025 else
17026 goto invalid_kind;
17027 }
17028 else
17029 goto invalid_kind;
17030
17031 check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE,
17032 "device_type");
17033 c_parser_consume_token (parser);
17034 parens.skip_until_found_close (parser);
17035 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE_TYPE);
17036 OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind;
17037 OMP_CLAUSE_CHAIN (c) = list;
17038 return c;
17039
17040 invalid_kind:
17041 c_parser_error (parser, "expected %<host%>, %<nohost%> or %<any%>");
17042 parens.skip_until_found_close (parser);
17043 return list;
17044 }
17045
17046 /* OpenMP 4.0:
17047 to ( variable-list ) */
17048
17049 static tree
17050 c_parser_omp_clause_to (c_parser *parser, tree list)
17051 {
17052 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO, list, true);
17053 }
17054
17055 /* OpenMP 4.0:
17056 from ( variable-list ) */
17057
17058 static tree
17059 c_parser_omp_clause_from (c_parser *parser, tree list)
17060 {
17061 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FROM, list, true);
17062 }
17063
17064 /* OpenMP 4.0:
17065 uniform ( variable-list ) */
17066
17067 static tree
17068 c_parser_omp_clause_uniform (c_parser *parser, tree list)
17069 {
17070 /* The clauses location. */
17071 location_t loc = c_parser_peek_token (parser)->location;
17072
17073 matching_parens parens;
17074 if (parens.require_open (parser))
17075 {
17076 list = c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_UNIFORM,
17077 list);
17078 parens.skip_until_found_close (parser);
17079 }
17080 return list;
17081 }
17082
17083 /* OpenMP 5.0:
17084 detach ( event-handle ) */
17085
17086 static tree
17087 c_parser_omp_clause_detach (c_parser *parser, tree list)
17088 {
17089 matching_parens parens;
17090 location_t clause_loc = c_parser_peek_token (parser)->location;
17091
17092 if (!parens.require_open (parser))
17093 return list;
17094
17095 if (c_parser_next_token_is_not (parser, CPP_NAME)
17096 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
17097 {
17098 c_parser_error (parser, "expected identifier");
17099 parens.skip_until_found_close (parser);
17100 return list;
17101 }
17102
17103 tree t = lookup_name (c_parser_peek_token (parser)->value);
17104 if (t == NULL_TREE)
17105 {
17106 undeclared_variable (c_parser_peek_token (parser)->location,
17107 c_parser_peek_token (parser)->value);
17108 parens.skip_until_found_close (parser);
17109 return list;
17110 }
17111 c_parser_consume_token (parser);
17112
17113 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (t));
17114 if (!INTEGRAL_TYPE_P (type)
17115 || TREE_CODE (type) != ENUMERAL_TYPE
17116 || TYPE_NAME (type) != get_identifier ("omp_event_handle_t"))
17117 {
17118 error_at (clause_loc, "%<detach%> clause event handle "
17119 "has type %qT rather than "
17120 "%<omp_event_handle_t%>",
17121 type);
17122 parens.skip_until_found_close (parser);
17123 return list;
17124 }
17125
17126 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DETACH);
17127 OMP_CLAUSE_DECL (u) = t;
17128 OMP_CLAUSE_CHAIN (u) = list;
17129 parens.skip_until_found_close (parser);
17130 return u;
17131 }
17132
17133 /* Parse all OpenACC clauses. The set clauses allowed by the directive
17134 is a bitmask in MASK. Return the list of clauses found. */
17135
17136 static tree
17137 c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask,
17138 const char *where, bool finish_p = true)
17139 {
17140 tree clauses = NULL;
17141 bool first = true;
17142
17143 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
17144 {
17145 location_t here;
17146 pragma_omp_clause c_kind;
17147 const char *c_name;
17148 tree prev = clauses;
17149
17150 if (!first && c_parser_next_token_is (parser, CPP_COMMA))
17151 c_parser_consume_token (parser);
17152
17153 here = c_parser_peek_token (parser)->location;
17154 c_kind = c_parser_omp_clause_name (parser);
17155
17156 switch (c_kind)
17157 {
17158 case PRAGMA_OACC_CLAUSE_ASYNC:
17159 clauses = c_parser_oacc_clause_async (parser, clauses);
17160 c_name = "async";
17161 break;
17162 case PRAGMA_OACC_CLAUSE_AUTO:
17163 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_AUTO,
17164 clauses);
17165 c_name = "auto";
17166 break;
17167 case PRAGMA_OACC_CLAUSE_ATTACH:
17168 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
17169 c_name = "attach";
17170 break;
17171 case PRAGMA_OACC_CLAUSE_COLLAPSE:
17172 clauses = c_parser_omp_clause_collapse (parser, clauses);
17173 c_name = "collapse";
17174 break;
17175 case PRAGMA_OACC_CLAUSE_COPY:
17176 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
17177 c_name = "copy";
17178 break;
17179 case PRAGMA_OACC_CLAUSE_COPYIN:
17180 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
17181 c_name = "copyin";
17182 break;
17183 case PRAGMA_OACC_CLAUSE_COPYOUT:
17184 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
17185 c_name = "copyout";
17186 break;
17187 case PRAGMA_OACC_CLAUSE_CREATE:
17188 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
17189 c_name = "create";
17190 break;
17191 case PRAGMA_OACC_CLAUSE_DELETE:
17192 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
17193 c_name = "delete";
17194 break;
17195 case PRAGMA_OMP_CLAUSE_DEFAULT:
17196 clauses = c_parser_omp_clause_default (parser, clauses, true);
17197 c_name = "default";
17198 break;
17199 case PRAGMA_OACC_CLAUSE_DETACH:
17200 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
17201 c_name = "detach";
17202 break;
17203 case PRAGMA_OACC_CLAUSE_DEVICE:
17204 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
17205 c_name = "device";
17206 break;
17207 case PRAGMA_OACC_CLAUSE_DEVICEPTR:
17208 clauses = c_parser_oacc_data_clause_deviceptr (parser, clauses);
17209 c_name = "deviceptr";
17210 break;
17211 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
17212 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
17213 c_name = "device_resident";
17214 break;
17215 case PRAGMA_OACC_CLAUSE_FINALIZE:
17216 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_FINALIZE,
17217 clauses);
17218 c_name = "finalize";
17219 break;
17220 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE:
17221 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
17222 c_name = "firstprivate";
17223 break;
17224 case PRAGMA_OACC_CLAUSE_GANG:
17225 c_name = "gang";
17226 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_GANG,
17227 c_name, clauses);
17228 break;
17229 case PRAGMA_OACC_CLAUSE_HOST:
17230 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
17231 c_name = "host";
17232 break;
17233 case PRAGMA_OACC_CLAUSE_IF:
17234 clauses = c_parser_omp_clause_if (parser, clauses, false);
17235 c_name = "if";
17236 break;
17237 case PRAGMA_OACC_CLAUSE_IF_PRESENT:
17238 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_IF_PRESENT,
17239 clauses);
17240 c_name = "if_present";
17241 break;
17242 case PRAGMA_OACC_CLAUSE_INDEPENDENT:
17243 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_INDEPENDENT,
17244 clauses);
17245 c_name = "independent";
17246 break;
17247 case PRAGMA_OACC_CLAUSE_LINK:
17248 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
17249 c_name = "link";
17250 break;
17251 case PRAGMA_OACC_CLAUSE_NO_CREATE:
17252 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
17253 c_name = "no_create";
17254 break;
17255 case PRAGMA_OACC_CLAUSE_NOHOST:
17256 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_NOHOST,
17257 clauses);
17258 c_name = "nohost";
17259 break;
17260 case PRAGMA_OACC_CLAUSE_NUM_GANGS:
17261 clauses = c_parser_oacc_single_int_clause (parser,
17262 OMP_CLAUSE_NUM_GANGS,
17263 clauses);
17264 c_name = "num_gangs";
17265 break;
17266 case PRAGMA_OACC_CLAUSE_NUM_WORKERS:
17267 clauses = c_parser_oacc_single_int_clause (parser,
17268 OMP_CLAUSE_NUM_WORKERS,
17269 clauses);
17270 c_name = "num_workers";
17271 break;
17272 case PRAGMA_OACC_CLAUSE_PRESENT:
17273 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
17274 c_name = "present";
17275 break;
17276 case PRAGMA_OACC_CLAUSE_PRIVATE:
17277 clauses = c_parser_omp_clause_private (parser, clauses);
17278 c_name = "private";
17279 break;
17280 case PRAGMA_OACC_CLAUSE_REDUCTION:
17281 clauses
17282 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
17283 false, clauses);
17284 c_name = "reduction";
17285 break;
17286 case PRAGMA_OACC_CLAUSE_SEQ:
17287 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_SEQ,
17288 clauses);
17289 c_name = "seq";
17290 break;
17291 case PRAGMA_OACC_CLAUSE_TILE:
17292 clauses = c_parser_oacc_clause_tile (parser, clauses);
17293 c_name = "tile";
17294 break;
17295 case PRAGMA_OACC_CLAUSE_USE_DEVICE:
17296 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
17297 c_name = "use_device";
17298 break;
17299 case PRAGMA_OACC_CLAUSE_VECTOR:
17300 c_name = "vector";
17301 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_VECTOR,
17302 c_name, clauses);
17303 break;
17304 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH:
17305 clauses = c_parser_oacc_single_int_clause (parser,
17306 OMP_CLAUSE_VECTOR_LENGTH,
17307 clauses);
17308 c_name = "vector_length";
17309 break;
17310 case PRAGMA_OACC_CLAUSE_WAIT:
17311 clauses = c_parser_oacc_clause_wait (parser, clauses);
17312 c_name = "wait";
17313 break;
17314 case PRAGMA_OACC_CLAUSE_WORKER:
17315 c_name = "worker";
17316 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_WORKER,
17317 c_name, clauses);
17318 break;
17319 default:
17320 c_parser_error (parser, "expected %<#pragma acc%> clause");
17321 goto saw_error;
17322 }
17323
17324 first = false;
17325
17326 if (((mask >> c_kind) & 1) == 0)
17327 {
17328 /* Remove the invalid clause(s) from the list to avoid
17329 confusing the rest of the compiler. */
17330 clauses = prev;
17331 error_at (here, "%qs is not valid for %qs", c_name, where);
17332 }
17333 }
17334
17335 saw_error:
17336 c_parser_skip_to_pragma_eol (parser);
17337
17338 if (finish_p)
17339 return c_finish_omp_clauses (clauses, C_ORT_ACC);
17340
17341 return clauses;
17342 }
17343
17344 /* Parse all OpenMP clauses. The set clauses allowed by the directive
17345 is a bitmask in MASK. Return the list of clauses found.
17346 FINISH_P set if c_finish_omp_clauses should be called.
17347 NESTED non-zero if clauses should be terminated by closing paren instead
17348 of end of pragma. If it is 2, additionally commas are required in between
17349 the clauses. */
17350
17351 static tree
17352 c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
17353 const char *where, bool finish_p = true,
17354 int nested = 0)
17355 {
17356 tree clauses = NULL;
17357 bool first = true;
17358
17359 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
17360 {
17361 location_t here;
17362 pragma_omp_clause c_kind;
17363 const char *c_name;
17364 tree prev = clauses;
17365
17366 if (nested && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
17367 break;
17368
17369 if (!first)
17370 {
17371 if (c_parser_next_token_is (parser, CPP_COMMA))
17372 c_parser_consume_token (parser);
17373 else if (nested == 2)
17374 error_at (c_parser_peek_token (parser)->location,
17375 "clauses in %<simd%> trait should be separated "
17376 "by %<,%>");
17377 }
17378
17379 here = c_parser_peek_token (parser)->location;
17380 c_kind = c_parser_omp_clause_name (parser);
17381
17382 switch (c_kind)
17383 {
17384 case PRAGMA_OMP_CLAUSE_BIND:
17385 clauses = c_parser_omp_clause_bind (parser, clauses);
17386 c_name = "bind";
17387 break;
17388 case PRAGMA_OMP_CLAUSE_COLLAPSE:
17389 clauses = c_parser_omp_clause_collapse (parser, clauses);
17390 c_name = "collapse";
17391 break;
17392 case PRAGMA_OMP_CLAUSE_COPYIN:
17393 clauses = c_parser_omp_clause_copyin (parser, clauses);
17394 c_name = "copyin";
17395 break;
17396 case PRAGMA_OMP_CLAUSE_COPYPRIVATE:
17397 clauses = c_parser_omp_clause_copyprivate (parser, clauses);
17398 c_name = "copyprivate";
17399 break;
17400 case PRAGMA_OMP_CLAUSE_DEFAULT:
17401 clauses = c_parser_omp_clause_default (parser, clauses, false);
17402 c_name = "default";
17403 break;
17404 case PRAGMA_OMP_CLAUSE_DETACH:
17405 clauses = c_parser_omp_clause_detach (parser, clauses);
17406 c_name = "detach";
17407 break;
17408 case PRAGMA_OMP_CLAUSE_FILTER:
17409 clauses = c_parser_omp_clause_filter (parser, clauses);
17410 c_name = "filter";
17411 break;
17412 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
17413 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
17414 c_name = "firstprivate";
17415 break;
17416 case PRAGMA_OMP_CLAUSE_FINAL:
17417 clauses = c_parser_omp_clause_final (parser, clauses);
17418 c_name = "final";
17419 break;
17420 case PRAGMA_OMP_CLAUSE_GRAINSIZE:
17421 clauses = c_parser_omp_clause_grainsize (parser, clauses);
17422 c_name = "grainsize";
17423 break;
17424 case PRAGMA_OMP_CLAUSE_HINT:
17425 clauses = c_parser_omp_clause_hint (parser, clauses);
17426 c_name = "hint";
17427 break;
17428 case PRAGMA_OMP_CLAUSE_DEFAULTMAP:
17429 clauses = c_parser_omp_clause_defaultmap (parser, clauses);
17430 c_name = "defaultmap";
17431 break;
17432 case PRAGMA_OMP_CLAUSE_IF:
17433 clauses = c_parser_omp_clause_if (parser, clauses, true);
17434 c_name = "if";
17435 break;
17436 case PRAGMA_OMP_CLAUSE_IN_REDUCTION:
17437 clauses
17438 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION,
17439 true, clauses);
17440 c_name = "in_reduction";
17441 break;
17442 case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
17443 clauses = c_parser_omp_clause_lastprivate (parser, clauses);
17444 c_name = "lastprivate";
17445 break;
17446 case PRAGMA_OMP_CLAUSE_MERGEABLE:
17447 clauses = c_parser_omp_clause_mergeable (parser, clauses);
17448 c_name = "mergeable";
17449 break;
17450 case PRAGMA_OMP_CLAUSE_NOWAIT:
17451 clauses = c_parser_omp_clause_nowait (parser, clauses);
17452 c_name = "nowait";
17453 break;
17454 case PRAGMA_OMP_CLAUSE_NUM_TASKS:
17455 clauses = c_parser_omp_clause_num_tasks (parser, clauses);
17456 c_name = "num_tasks";
17457 break;
17458 case PRAGMA_OMP_CLAUSE_NUM_THREADS:
17459 clauses = c_parser_omp_clause_num_threads (parser, clauses);
17460 c_name = "num_threads";
17461 break;
17462 case PRAGMA_OMP_CLAUSE_ORDER:
17463 clauses = c_parser_omp_clause_order (parser, clauses);
17464 c_name = "order";
17465 break;
17466 case PRAGMA_OMP_CLAUSE_ORDERED:
17467 clauses = c_parser_omp_clause_ordered (parser, clauses);
17468 c_name = "ordered";
17469 break;
17470 case PRAGMA_OMP_CLAUSE_PRIORITY:
17471 clauses = c_parser_omp_clause_priority (parser, clauses);
17472 c_name = "priority";
17473 break;
17474 case PRAGMA_OMP_CLAUSE_PRIVATE:
17475 clauses = c_parser_omp_clause_private (parser, clauses);
17476 c_name = "private";
17477 break;
17478 case PRAGMA_OMP_CLAUSE_REDUCTION:
17479 clauses
17480 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
17481 true, clauses);
17482 c_name = "reduction";
17483 break;
17484 case PRAGMA_OMP_CLAUSE_SCHEDULE:
17485 clauses = c_parser_omp_clause_schedule (parser, clauses);
17486 c_name = "schedule";
17487 break;
17488 case PRAGMA_OMP_CLAUSE_SHARED:
17489 clauses = c_parser_omp_clause_shared (parser, clauses);
17490 c_name = "shared";
17491 break;
17492 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION:
17493 clauses
17494 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_TASK_REDUCTION,
17495 true, clauses);
17496 c_name = "task_reduction";
17497 break;
17498 case PRAGMA_OMP_CLAUSE_UNTIED:
17499 clauses = c_parser_omp_clause_untied (parser, clauses);
17500 c_name = "untied";
17501 break;
17502 case PRAGMA_OMP_CLAUSE_INBRANCH:
17503 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_INBRANCH,
17504 clauses);
17505 c_name = "inbranch";
17506 break;
17507 case PRAGMA_OMP_CLAUSE_NONTEMPORAL:
17508 clauses = c_parser_omp_clause_nontemporal (parser, clauses);
17509 c_name = "nontemporal";
17510 break;
17511 case PRAGMA_OMP_CLAUSE_NOTINBRANCH:
17512 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_NOTINBRANCH,
17513 clauses);
17514 c_name = "notinbranch";
17515 break;
17516 case PRAGMA_OMP_CLAUSE_PARALLEL:
17517 clauses
17518 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_PARALLEL,
17519 clauses);
17520 c_name = "parallel";
17521 if (!first)
17522 {
17523 clause_not_first:
17524 error_at (here, "%qs must be the first clause of %qs",
17525 c_name, where);
17526 clauses = prev;
17527 }
17528 break;
17529 case PRAGMA_OMP_CLAUSE_FOR:
17530 clauses
17531 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_FOR,
17532 clauses);
17533 c_name = "for";
17534 if (!first)
17535 goto clause_not_first;
17536 break;
17537 case PRAGMA_OMP_CLAUSE_SECTIONS:
17538 clauses
17539 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_SECTIONS,
17540 clauses);
17541 c_name = "sections";
17542 if (!first)
17543 goto clause_not_first;
17544 break;
17545 case PRAGMA_OMP_CLAUSE_TASKGROUP:
17546 clauses
17547 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_TASKGROUP,
17548 clauses);
17549 c_name = "taskgroup";
17550 if (!first)
17551 goto clause_not_first;
17552 break;
17553 case PRAGMA_OMP_CLAUSE_LINK:
17554 clauses
17555 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LINK, clauses);
17556 c_name = "link";
17557 break;
17558 case PRAGMA_OMP_CLAUSE_TO:
17559 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0)
17560 {
17561 tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
17562 clauses);
17563 for (tree c = nl; c != clauses; c = OMP_CLAUSE_CHAIN (c))
17564 OMP_CLAUSE_ENTER_TO (c) = 1;
17565 clauses = nl;
17566 }
17567 else
17568 clauses = c_parser_omp_clause_to (parser, clauses);
17569 c_name = "to";
17570 break;
17571 case PRAGMA_OMP_CLAUSE_FROM:
17572 clauses = c_parser_omp_clause_from (parser, clauses);
17573 c_name = "from";
17574 break;
17575 case PRAGMA_OMP_CLAUSE_UNIFORM:
17576 clauses = c_parser_omp_clause_uniform (parser, clauses);
17577 c_name = "uniform";
17578 break;
17579 case PRAGMA_OMP_CLAUSE_NUM_TEAMS:
17580 clauses = c_parser_omp_clause_num_teams (parser, clauses);
17581 c_name = "num_teams";
17582 break;
17583 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT:
17584 clauses = c_parser_omp_clause_thread_limit (parser, clauses);
17585 c_name = "thread_limit";
17586 break;
17587 case PRAGMA_OMP_CLAUSE_ALIGNED:
17588 clauses = c_parser_omp_clause_aligned (parser, clauses);
17589 c_name = "aligned";
17590 break;
17591 case PRAGMA_OMP_CLAUSE_ALLOCATE:
17592 clauses = c_parser_omp_clause_allocate (parser, clauses);
17593 c_name = "allocate";
17594 break;
17595 case PRAGMA_OMP_CLAUSE_LINEAR:
17596 clauses = c_parser_omp_clause_linear (parser, clauses);
17597 c_name = "linear";
17598 break;
17599 case PRAGMA_OMP_CLAUSE_AFFINITY:
17600 clauses = c_parser_omp_clause_affinity (parser, clauses);
17601 c_name = "affinity";
17602 break;
17603 case PRAGMA_OMP_CLAUSE_DEPEND:
17604 clauses = c_parser_omp_clause_depend (parser, clauses);
17605 c_name = "depend";
17606 break;
17607 case PRAGMA_OMP_CLAUSE_DOACROSS:
17608 clauses = c_parser_omp_clause_doacross (parser, clauses);
17609 c_name = "doacross";
17610 break;
17611 case PRAGMA_OMP_CLAUSE_MAP:
17612 clauses = c_parser_omp_clause_map (parser, clauses);
17613 c_name = "map";
17614 break;
17615 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR:
17616 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
17617 c_name = "use_device_ptr";
17618 break;
17619 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR:
17620 clauses = c_parser_omp_clause_use_device_addr (parser, clauses);
17621 c_name = "use_device_addr";
17622 break;
17623 case PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR:
17624 clauses = c_parser_omp_clause_has_device_addr (parser, clauses);
17625 c_name = "has_device_addr";
17626 break;
17627 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR:
17628 clauses = c_parser_omp_clause_is_device_ptr (parser, clauses);
17629 c_name = "is_device_ptr";
17630 break;
17631 case PRAGMA_OMP_CLAUSE_DEVICE:
17632 clauses = c_parser_omp_clause_device (parser, clauses);
17633 c_name = "device";
17634 break;
17635 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE:
17636 clauses = c_parser_omp_clause_dist_schedule (parser, clauses);
17637 c_name = "dist_schedule";
17638 break;
17639 case PRAGMA_OMP_CLAUSE_PROC_BIND:
17640 clauses = c_parser_omp_clause_proc_bind (parser, clauses);
17641 c_name = "proc_bind";
17642 break;
17643 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE:
17644 clauses = c_parser_omp_clause_device_type (parser, clauses);
17645 c_name = "device_type";
17646 break;
17647 case PRAGMA_OMP_CLAUSE_SAFELEN:
17648 clauses = c_parser_omp_clause_safelen (parser, clauses);
17649 c_name = "safelen";
17650 break;
17651 case PRAGMA_OMP_CLAUSE_SIMDLEN:
17652 clauses = c_parser_omp_clause_simdlen (parser, clauses);
17653 c_name = "simdlen";
17654 break;
17655 case PRAGMA_OMP_CLAUSE_NOGROUP:
17656 clauses = c_parser_omp_clause_nogroup (parser, clauses);
17657 c_name = "nogroup";
17658 break;
17659 case PRAGMA_OMP_CLAUSE_THREADS:
17660 clauses
17661 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_THREADS,
17662 clauses);
17663 c_name = "threads";
17664 break;
17665 case PRAGMA_OMP_CLAUSE_SIMD:
17666 clauses
17667 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_SIMD,
17668 clauses);
17669 c_name = "simd";
17670 break;
17671 case PRAGMA_OMP_CLAUSE_ENTER:
17672 clauses
17673 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
17674 clauses);
17675 c_name = "enter";
17676 break;
17677 default:
17678 c_parser_error (parser, "expected %<#pragma omp%> clause");
17679 goto saw_error;
17680 }
17681
17682 first = false;
17683
17684 if (((mask >> c_kind) & 1) == 0)
17685 {
17686 /* Remove the invalid clause(s) from the list to avoid
17687 confusing the rest of the compiler. */
17688 clauses = prev;
17689 error_at (here, "%qs is not valid for %qs", c_name, where);
17690 }
17691 }
17692
17693 saw_error:
17694 if (!nested)
17695 c_parser_skip_to_pragma_eol (parser);
17696
17697 if (finish_p)
17698 {
17699 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)) != 0)
17700 return c_finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD);
17701 return c_finish_omp_clauses (clauses, C_ORT_OMP);
17702 }
17703
17704 return clauses;
17705 }
17706
17707 /* OpenACC 2.0, OpenMP 2.5:
17708 structured-block:
17709 statement
17710
17711 In practice, we're also interested in adding the statement to an
17712 outer node. So it is convenient if we work around the fact that
17713 c_parser_statement calls add_stmt. */
17714
17715 static tree
17716 c_parser_omp_structured_block (c_parser *parser, bool *if_p)
17717 {
17718 tree stmt = push_stmt_list ();
17719 c_parser_statement (parser, if_p);
17720 return pop_stmt_list (stmt);
17721 }
17722
17723 /* OpenACC 2.0:
17724 # pragma acc cache (variable-list) new-line
17725
17726 LOC is the location of the #pragma token.
17727 */
17728
17729 static tree
17730 c_parser_oacc_cache (location_t loc, c_parser *parser)
17731 {
17732 tree stmt, clauses;
17733
17734 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE__CACHE_, NULL);
17735 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
17736
17737 c_parser_skip_to_pragma_eol (parser);
17738
17739 stmt = make_node (OACC_CACHE);
17740 TREE_TYPE (stmt) = void_type_node;
17741 OACC_CACHE_CLAUSES (stmt) = clauses;
17742 SET_EXPR_LOCATION (stmt, loc);
17743 add_stmt (stmt);
17744
17745 return stmt;
17746 }
17747
17748 /* OpenACC 2.0:
17749 # pragma acc data oacc-data-clause[optseq] new-line
17750 structured-block
17751
17752 LOC is the location of the #pragma token.
17753 */
17754
17755 #define OACC_DATA_CLAUSE_MASK \
17756 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17757 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17758 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17759 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17760 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17761 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17762 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17763 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17764 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
17765
17766 static tree
17767 c_parser_oacc_data (location_t loc, c_parser *parser, bool *if_p)
17768 {
17769 tree stmt, clauses, block;
17770
17771 clauses = c_parser_oacc_all_clauses (parser, OACC_DATA_CLAUSE_MASK,
17772 "#pragma acc data");
17773
17774 block = c_begin_omp_parallel ();
17775 add_stmt (c_parser_omp_structured_block (parser, if_p));
17776
17777 stmt = c_finish_oacc_data (loc, clauses, block);
17778
17779 return stmt;
17780 }
17781
17782 /* OpenACC 2.0:
17783 # pragma acc declare oacc-data-clause[optseq] new-line
17784 */
17785
17786 #define OACC_DECLARE_CLAUSE_MASK \
17787 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17788 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17789 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17790 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17791 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17792 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
17793 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
17794 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
17795
17796 static void
17797 c_parser_oacc_declare (c_parser *parser)
17798 {
17799 location_t pragma_loc = c_parser_peek_token (parser)->location;
17800 tree clauses, stmt, t, decl;
17801
17802 bool error = false;
17803
17804 c_parser_consume_pragma (parser);
17805
17806 clauses = c_parser_oacc_all_clauses (parser, OACC_DECLARE_CLAUSE_MASK,
17807 "#pragma acc declare");
17808 if (!clauses)
17809 {
17810 error_at (pragma_loc,
17811 "no valid clauses specified in %<#pragma acc declare%>");
17812 return;
17813 }
17814
17815 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
17816 {
17817 location_t loc = OMP_CLAUSE_LOCATION (t);
17818 decl = OMP_CLAUSE_DECL (t);
17819 if (!DECL_P (decl))
17820 {
17821 error_at (loc, "array section in %<#pragma acc declare%>");
17822 error = true;
17823 continue;
17824 }
17825
17826 switch (OMP_CLAUSE_MAP_KIND (t))
17827 {
17828 case GOMP_MAP_FIRSTPRIVATE_POINTER:
17829 case GOMP_MAP_ALLOC:
17830 case GOMP_MAP_TO:
17831 case GOMP_MAP_FORCE_DEVICEPTR:
17832 case GOMP_MAP_DEVICE_RESIDENT:
17833 break;
17834
17835 case GOMP_MAP_LINK:
17836 if (!global_bindings_p ()
17837 && (TREE_STATIC (decl)
17838 || !DECL_EXTERNAL (decl)))
17839 {
17840 error_at (loc,
17841 "%qD must be a global variable in "
17842 "%<#pragma acc declare link%>",
17843 decl);
17844 error = true;
17845 continue;
17846 }
17847 break;
17848
17849 default:
17850 if (global_bindings_p ())
17851 {
17852 error_at (loc, "invalid OpenACC clause at file scope");
17853 error = true;
17854 continue;
17855 }
17856 if (DECL_EXTERNAL (decl))
17857 {
17858 error_at (loc,
17859 "invalid use of %<extern%> variable %qD "
17860 "in %<#pragma acc declare%>", decl);
17861 error = true;
17862 continue;
17863 }
17864 else if (TREE_PUBLIC (decl))
17865 {
17866 error_at (loc,
17867 "invalid use of %<global%> variable %qD "
17868 "in %<#pragma acc declare%>", decl);
17869 error = true;
17870 continue;
17871 }
17872 break;
17873 }
17874
17875 if (!c_check_in_current_scope (decl))
17876 {
17877 error_at (loc,
17878 "%qD must be a variable declared in the same scope as "
17879 "%<#pragma acc declare%>", decl);
17880 error = true;
17881 continue;
17882 }
17883
17884 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl))
17885 || lookup_attribute ("omp declare target link",
17886 DECL_ATTRIBUTES (decl)))
17887 {
17888 error_at (loc, "variable %qD used more than once with "
17889 "%<#pragma acc declare%>", decl);
17890 error = true;
17891 continue;
17892 }
17893
17894 if (!error)
17895 {
17896 tree id;
17897
17898 if (OMP_CLAUSE_MAP_KIND (t) == GOMP_MAP_LINK)
17899 id = get_identifier ("omp declare target link");
17900 else
17901 id = get_identifier ("omp declare target");
17902
17903 DECL_ATTRIBUTES (decl)
17904 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
17905
17906 if (global_bindings_p ())
17907 {
17908 symtab_node *node = symtab_node::get (decl);
17909 if (node != NULL)
17910 {
17911 node->offloadable = 1;
17912 if (ENABLE_OFFLOADING)
17913 {
17914 g->have_offload = true;
17915 if (is_a <varpool_node *> (node))
17916 vec_safe_push (offload_vars, decl);
17917 }
17918 }
17919 }
17920 }
17921 }
17922
17923 if (error || global_bindings_p ())
17924 return;
17925
17926 stmt = make_node (OACC_DECLARE);
17927 TREE_TYPE (stmt) = void_type_node;
17928 OACC_DECLARE_CLAUSES (stmt) = clauses;
17929 SET_EXPR_LOCATION (stmt, pragma_loc);
17930
17931 add_stmt (stmt);
17932
17933 return;
17934 }
17935
17936 /* OpenACC 2.0:
17937 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
17938
17939 or
17940
17941 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
17942
17943
17944 LOC is the location of the #pragma token.
17945 */
17946
17947 #define OACC_ENTER_DATA_CLAUSE_MASK \
17948 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17949 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17950 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17951 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17952 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17953 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17954
17955 #define OACC_EXIT_DATA_CLAUSE_MASK \
17956 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17957 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17958 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17959 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
17960 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \
17961 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \
17962 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17963
17964 static void
17965 c_parser_oacc_enter_exit_data (c_parser *parser, bool enter)
17966 {
17967 location_t loc = c_parser_peek_token (parser)->location;
17968 tree clauses, stmt;
17969 const char *p = "";
17970
17971 c_parser_consume_pragma (parser);
17972
17973 if (c_parser_next_token_is (parser, CPP_NAME))
17974 {
17975 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17976 c_parser_consume_token (parser);
17977 }
17978
17979 if (strcmp (p, "data") != 0)
17980 {
17981 error_at (loc, "expected %<data%> after %<#pragma acc %s%>",
17982 enter ? "enter" : "exit");
17983 parser->error = true;
17984 c_parser_skip_to_pragma_eol (parser);
17985 return;
17986 }
17987
17988 if (enter)
17989 clauses = c_parser_oacc_all_clauses (parser, OACC_ENTER_DATA_CLAUSE_MASK,
17990 "#pragma acc enter data");
17991 else
17992 clauses = c_parser_oacc_all_clauses (parser, OACC_EXIT_DATA_CLAUSE_MASK,
17993 "#pragma acc exit data");
17994
17995 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
17996 {
17997 error_at (loc, "%<#pragma acc %s data%> has no data movement clause",
17998 enter ? "enter" : "exit");
17999 return;
18000 }
18001
18002 stmt = enter ? make_node (OACC_ENTER_DATA) : make_node (OACC_EXIT_DATA);
18003 TREE_TYPE (stmt) = void_type_node;
18004 OMP_STANDALONE_CLAUSES (stmt) = clauses;
18005 SET_EXPR_LOCATION (stmt, loc);
18006 add_stmt (stmt);
18007 }
18008
18009
18010 /* OpenACC 2.0:
18011 # pragma acc host_data oacc-data-clause[optseq] new-line
18012 structured-block
18013 */
18014
18015 #define OACC_HOST_DATA_CLAUSE_MASK \
18016 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) \
18017 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
18018 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
18019
18020 static tree
18021 c_parser_oacc_host_data (location_t loc, c_parser *parser, bool *if_p)
18022 {
18023 tree stmt, clauses, block;
18024
18025 clauses = c_parser_oacc_all_clauses (parser, OACC_HOST_DATA_CLAUSE_MASK,
18026 "#pragma acc host_data");
18027
18028 block = c_begin_omp_parallel ();
18029 add_stmt (c_parser_omp_structured_block (parser, if_p));
18030 stmt = c_finish_oacc_host_data (loc, clauses, block);
18031 return stmt;
18032 }
18033
18034
18035 /* OpenACC 2.0:
18036
18037 # pragma acc loop oacc-loop-clause[optseq] new-line
18038 structured-block
18039
18040 LOC is the location of the #pragma token.
18041 */
18042
18043 #define OACC_LOOP_CLAUSE_MASK \
18044 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
18045 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
18046 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
18047 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
18048 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
18049 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
18050 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
18051 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
18052 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
18053 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
18054 static tree
18055 c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name,
18056 omp_clause_mask mask, tree *cclauses, bool *if_p)
18057 {
18058 bool is_parallel = ((mask >> PRAGMA_OACC_CLAUSE_REDUCTION) & 1) == 1;
18059
18060 strcat (p_name, " loop");
18061 mask |= OACC_LOOP_CLAUSE_MASK;
18062
18063 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name,
18064 cclauses == NULL);
18065 if (cclauses)
18066 {
18067 clauses = c_oacc_split_loop_clauses (clauses, cclauses, is_parallel);
18068 if (*cclauses)
18069 *cclauses = c_finish_omp_clauses (*cclauses, C_ORT_ACC);
18070 if (clauses)
18071 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
18072 }
18073
18074 tree block = c_begin_compound_stmt (true);
18075 tree stmt = c_parser_omp_for_loop (loc, parser, OACC_LOOP, clauses, NULL,
18076 if_p);
18077 block = c_end_compound_stmt (loc, block, true);
18078 add_stmt (block);
18079
18080 return stmt;
18081 }
18082
18083 /* OpenACC 2.0:
18084 # pragma acc kernels oacc-kernels-clause[optseq] new-line
18085 structured-block
18086
18087 or
18088
18089 # pragma acc parallel oacc-parallel-clause[optseq] new-line
18090 structured-block
18091
18092 OpenACC 2.6:
18093
18094 # pragma acc serial oacc-serial-clause[optseq] new-line
18095 structured-block
18096
18097 LOC is the location of the #pragma token.
18098 */
18099
18100 #define OACC_KERNELS_CLAUSE_MASK \
18101 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
18102 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
18103 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
18104 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
18105 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
18106 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
18107 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
18108 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
18109 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
18110 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
18111 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
18112 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
18113 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
18114 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
18115 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
18116
18117 #define OACC_PARALLEL_CLAUSE_MASK \
18118 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
18119 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
18120 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
18121 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
18122 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
18123 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
18124 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
18125 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
18126 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
18127 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
18128 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
18129 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
18130 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
18131 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
18132 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
18133 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
18134 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
18135 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
18136
18137 #define OACC_SERIAL_CLAUSE_MASK \
18138 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
18139 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
18140 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
18141 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
18142 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
18143 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
18144 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
18145 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
18146 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
18147 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
18148 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
18149 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
18150 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
18151 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
18152 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
18153
18154 static tree
18155 c_parser_oacc_compute (location_t loc, c_parser *parser,
18156 enum pragma_kind p_kind, char *p_name, bool *if_p)
18157 {
18158 omp_clause_mask mask;
18159 enum tree_code code;
18160 switch (p_kind)
18161 {
18162 case PRAGMA_OACC_KERNELS:
18163 strcat (p_name, " kernels");
18164 mask = OACC_KERNELS_CLAUSE_MASK;
18165 code = OACC_KERNELS;
18166 break;
18167 case PRAGMA_OACC_PARALLEL:
18168 strcat (p_name, " parallel");
18169 mask = OACC_PARALLEL_CLAUSE_MASK;
18170 code = OACC_PARALLEL;
18171 break;
18172 case PRAGMA_OACC_SERIAL:
18173 strcat (p_name, " serial");
18174 mask = OACC_SERIAL_CLAUSE_MASK;
18175 code = OACC_SERIAL;
18176 break;
18177 default:
18178 gcc_unreachable ();
18179 }
18180
18181 if (c_parser_next_token_is (parser, CPP_NAME))
18182 {
18183 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18184 if (strcmp (p, "loop") == 0)
18185 {
18186 c_parser_consume_token (parser);
18187 tree block = c_begin_omp_parallel ();
18188 tree clauses;
18189 c_parser_oacc_loop (loc, parser, p_name, mask, &clauses, if_p);
18190 return c_finish_omp_construct (loc, code, block, clauses);
18191 }
18192 }
18193
18194 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name);
18195
18196 tree block = c_begin_omp_parallel ();
18197 add_stmt (c_parser_omp_structured_block (parser, if_p));
18198
18199 return c_finish_omp_construct (loc, code, block, clauses);
18200 }
18201
18202 /* OpenACC 2.0:
18203 # pragma acc routine oacc-routine-clause[optseq] new-line
18204 function-definition
18205
18206 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
18207 */
18208
18209 #define OACC_ROUTINE_CLAUSE_MASK \
18210 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
18211 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
18212 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
18213 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
18214 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NOHOST) )
18215
18216 /* Parse an OpenACC routine directive. For named directives, we apply
18217 immediately to the named function. For unnamed ones we then parse
18218 a declaration or definition, which must be for a function. */
18219
18220 static void
18221 c_parser_oacc_routine (c_parser *parser, enum pragma_context context)
18222 {
18223 gcc_checking_assert (context == pragma_external);
18224
18225 oacc_routine_data data;
18226 data.error_seen = false;
18227 data.fndecl_seen = false;
18228 data.loc = c_parser_peek_token (parser)->location;
18229
18230 c_parser_consume_pragma (parser);
18231
18232 /* Look for optional '( name )'. */
18233 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
18234 {
18235 c_parser_consume_token (parser); /* '(' */
18236
18237 tree decl = NULL_TREE;
18238 c_token *name_token = c_parser_peek_token (parser);
18239 location_t name_loc = name_token->location;
18240 if (name_token->type == CPP_NAME
18241 && (name_token->id_kind == C_ID_ID
18242 || name_token->id_kind == C_ID_TYPENAME))
18243 {
18244 decl = lookup_name (name_token->value);
18245 if (!decl)
18246 error_at (name_loc,
18247 "%qE has not been declared", name_token->value);
18248 c_parser_consume_token (parser);
18249 }
18250 else
18251 c_parser_error (parser, "expected function name");
18252
18253 if (!decl
18254 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
18255 {
18256 c_parser_skip_to_pragma_eol (parser, false);
18257 return;
18258 }
18259
18260 data.clauses
18261 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
18262 "#pragma acc routine");
18263 /* The clauses are in reverse order; fix that to make later diagnostic
18264 emission easier. */
18265 data.clauses = nreverse (data.clauses);
18266
18267 if (TREE_CODE (decl) != FUNCTION_DECL)
18268 {
18269 error_at (name_loc, "%qD does not refer to a function", decl);
18270 return;
18271 }
18272
18273 c_finish_oacc_routine (&data, decl, false);
18274 }
18275 else /* No optional '( name )'. */
18276 {
18277 data.clauses
18278 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
18279 "#pragma acc routine");
18280 /* The clauses are in reverse order; fix that to make later diagnostic
18281 emission easier. */
18282 data.clauses = nreverse (data.clauses);
18283
18284 /* Emit a helpful diagnostic if there's another pragma following this
18285 one. Also don't allow a static assertion declaration, as in the
18286 following we'll just parse a *single* "declaration or function
18287 definition", and the static assertion counts an one. */
18288 if (c_parser_next_token_is (parser, CPP_PRAGMA)
18289 || c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
18290 {
18291 error_at (data.loc,
18292 "%<#pragma acc routine%> not immediately followed by"
18293 " function declaration or definition");
18294 /* ..., and then just keep going. */
18295 return;
18296 }
18297
18298 /* We only have to consider the pragma_external case here. */
18299 if (c_parser_next_token_is (parser, CPP_KEYWORD)
18300 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
18301 {
18302 int ext = disable_extension_diagnostics ();
18303 do
18304 c_parser_consume_token (parser);
18305 while (c_parser_next_token_is (parser, CPP_KEYWORD)
18306 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
18307 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
18308 NULL, NULL, false, NULL, &data);
18309 restore_extension_diagnostics (ext);
18310 }
18311 else
18312 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
18313 NULL, NULL, false, NULL, &data);
18314 }
18315 }
18316
18317 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
18318 IS_DEFN is true if we're applying it to the definition. */
18319
18320 static void
18321 c_finish_oacc_routine (struct oacc_routine_data *data, tree fndecl,
18322 bool is_defn)
18323 {
18324 /* Keep going if we're in error reporting mode. */
18325 if (data->error_seen
18326 || fndecl == error_mark_node)
18327 return;
18328
18329 if (data->fndecl_seen)
18330 {
18331 error_at (data->loc,
18332 "%<#pragma acc routine%> not immediately followed by"
18333 " a single function declaration or definition");
18334 data->error_seen = true;
18335 return;
18336 }
18337 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
18338 {
18339 error_at (data->loc,
18340 "%<#pragma acc routine%> not immediately followed by"
18341 " function declaration or definition");
18342 data->error_seen = true;
18343 return;
18344 }
18345
18346 int compatible
18347 = oacc_verify_routine_clauses (fndecl, &data->clauses, data->loc,
18348 "#pragma acc routine");
18349 if (compatible < 0)
18350 {
18351 data->error_seen = true;
18352 return;
18353 }
18354 if (compatible > 0)
18355 {
18356 }
18357 else
18358 {
18359 if (TREE_USED (fndecl) || (!is_defn && DECL_SAVED_TREE (fndecl)))
18360 {
18361 error_at (data->loc,
18362 TREE_USED (fndecl)
18363 ? G_("%<#pragma acc routine%> must be applied before use")
18364 : G_("%<#pragma acc routine%> must be applied before"
18365 " definition"));
18366 data->error_seen = true;
18367 return;
18368 }
18369
18370 /* Set the routine's level of parallelism. */
18371 tree dims = oacc_build_routine_dims (data->clauses);
18372 oacc_replace_fn_attrib (fndecl, dims);
18373
18374 /* Add an "omp declare target" attribute. */
18375 DECL_ATTRIBUTES (fndecl)
18376 = tree_cons (get_identifier ("omp declare target"),
18377 data->clauses, DECL_ATTRIBUTES (fndecl));
18378 }
18379
18380 /* Remember that we've used this "#pragma acc routine". */
18381 data->fndecl_seen = true;
18382 }
18383
18384 /* OpenACC 2.0:
18385 # pragma acc update oacc-update-clause[optseq] new-line
18386 */
18387
18388 #define OACC_UPDATE_CLAUSE_MASK \
18389 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
18390 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
18391 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
18392 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
18393 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
18394 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
18395
18396 static void
18397 c_parser_oacc_update (c_parser *parser)
18398 {
18399 location_t loc = c_parser_peek_token (parser)->location;
18400
18401 c_parser_consume_pragma (parser);
18402
18403 tree clauses = c_parser_oacc_all_clauses (parser, OACC_UPDATE_CLAUSE_MASK,
18404 "#pragma acc update");
18405 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
18406 {
18407 error_at (loc,
18408 "%<#pragma acc update%> must contain at least one "
18409 "%<device%> or %<host%> or %<self%> clause");
18410 return;
18411 }
18412
18413 if (parser->error)
18414 return;
18415
18416 tree stmt = make_node (OACC_UPDATE);
18417 TREE_TYPE (stmt) = void_type_node;
18418 OACC_UPDATE_CLAUSES (stmt) = clauses;
18419 SET_EXPR_LOCATION (stmt, loc);
18420 add_stmt (stmt);
18421 }
18422
18423 /* OpenACC 2.0:
18424 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
18425
18426 LOC is the location of the #pragma token.
18427 */
18428
18429 #define OACC_WAIT_CLAUSE_MASK \
18430 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
18431
18432 static tree
18433 c_parser_oacc_wait (location_t loc, c_parser *parser, char *p_name)
18434 {
18435 tree clauses, list = NULL_TREE, stmt = NULL_TREE;
18436
18437 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
18438 list = c_parser_oacc_wait_list (parser, loc, list);
18439
18440 strcpy (p_name, " wait");
18441 clauses = c_parser_oacc_all_clauses (parser, OACC_WAIT_CLAUSE_MASK, p_name);
18442 stmt = c_finish_oacc_wait (loc, list, clauses);
18443 add_stmt (stmt);
18444
18445 return stmt;
18446 }
18447
18448 /* OpenMP 5.0:
18449 # pragma omp allocate (list) [allocator(allocator)] */
18450
18451 static void
18452 c_parser_omp_allocate (location_t loc, c_parser *parser)
18453 {
18454 tree allocator = NULL_TREE;
18455 tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ALLOCATE, NULL_TREE);
18456 if (c_parser_next_token_is (parser, CPP_NAME))
18457 {
18458 matching_parens parens;
18459 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18460 c_parser_consume_token (parser);
18461 if (strcmp ("allocator", p) != 0)
18462 error_at (c_parser_peek_token (parser)->location,
18463 "expected %<allocator%>");
18464 else if (parens.require_open (parser))
18465 {
18466 location_t expr_loc = c_parser_peek_token (parser)->location;
18467 c_expr expr = c_parser_expr_no_commas (parser, NULL);
18468 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
18469 allocator = expr.value;
18470 allocator = c_fully_fold (allocator, false, NULL);
18471 tree orig_type
18472 = expr.original_type ? expr.original_type : TREE_TYPE (allocator);
18473 orig_type = TYPE_MAIN_VARIANT (orig_type);
18474 if (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
18475 || TREE_CODE (orig_type) != ENUMERAL_TYPE
18476 || TYPE_NAME (orig_type)
18477 != get_identifier ("omp_allocator_handle_t"))
18478 {
18479 error_at (expr_loc, "%<allocator%> clause allocator expression "
18480 "has type %qT rather than "
18481 "%<omp_allocator_handle_t%>",
18482 TREE_TYPE (allocator));
18483 allocator = NULL_TREE;
18484 }
18485 parens.skip_until_found_close (parser);
18486 }
18487 }
18488 c_parser_skip_to_pragma_eol (parser);
18489
18490 if (allocator)
18491 for (tree c = nl; c != NULL_TREE; c = OMP_CLAUSE_CHAIN (c))
18492 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
18493
18494 sorry_at (loc, "%<#pragma omp allocate%> not yet supported");
18495 }
18496
18497 /* OpenMP 2.5:
18498 # pragma omp atomic new-line
18499 expression-stmt
18500
18501 expression-stmt:
18502 x binop= expr | x++ | ++x | x-- | --x
18503 binop:
18504 +, *, -, /, &, ^, |, <<, >>
18505
18506 where x is an lvalue expression with scalar type.
18507
18508 OpenMP 3.1:
18509 # pragma omp atomic new-line
18510 update-stmt
18511
18512 # pragma omp atomic read new-line
18513 read-stmt
18514
18515 # pragma omp atomic write new-line
18516 write-stmt
18517
18518 # pragma omp atomic update new-line
18519 update-stmt
18520
18521 # pragma omp atomic capture new-line
18522 capture-stmt
18523
18524 # pragma omp atomic capture new-line
18525 capture-block
18526
18527 read-stmt:
18528 v = x
18529 write-stmt:
18530 x = expr
18531 update-stmt:
18532 expression-stmt | x = x binop expr
18533 capture-stmt:
18534 v = expression-stmt
18535 capture-block:
18536 { v = x; update-stmt; } | { update-stmt; v = x; }
18537
18538 OpenMP 4.0:
18539 update-stmt:
18540 expression-stmt | x = x binop expr | x = expr binop x
18541 capture-stmt:
18542 v = update-stmt
18543 capture-block:
18544 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
18545
18546 OpenMP 5.1:
18547 # pragma omp atomic compare new-line
18548 conditional-update-atomic
18549
18550 # pragma omp atomic compare capture new-line
18551 conditional-update-capture-atomic
18552
18553 conditional-update-atomic:
18554 cond-expr-stmt | cond-update-stmt
18555 cond-expr-stmt:
18556 x = expr ordop x ? expr : x;
18557 x = x ordop expr ? expr : x;
18558 x = x == e ? d : x;
18559 cond-update-stmt:
18560 if (expr ordop x) { x = expr; }
18561 if (x ordop expr) { x = expr; }
18562 if (x == e) { x = d; }
18563 ordop:
18564 <, >
18565 conditional-update-capture-atomic:
18566 v = cond-expr-stmt
18567 { v = x; cond-expr-stmt }
18568 { cond-expr-stmt v = x; }
18569 { v = x; cond-update-stmt }
18570 { cond-update-stmt v = x; }
18571 if (x == e) { x = d; } else { v = x; }
18572 { r = x == e; if (r) { x = d; } }
18573 { r = x == e; if (r) { x = d; } else { v = x; } }
18574
18575 where x, r and v are lvalue expressions with scalar type,
18576 expr, e and d are expressions with scalar type and e might be
18577 the same as v.
18578
18579 LOC is the location of the #pragma token. */
18580
18581 static void
18582 c_parser_omp_atomic (location_t loc, c_parser *parser, bool openacc)
18583 {
18584 tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE, r = NULL_TREE;
18585 tree lhs1 = NULL_TREE, rhs1 = NULL_TREE;
18586 tree stmt, orig_lhs, unfolded_lhs = NULL_TREE, unfolded_lhs1 = NULL_TREE;
18587 enum tree_code code = ERROR_MARK, opcode = NOP_EXPR;
18588 enum omp_memory_order memory_order = OMP_MEMORY_ORDER_UNSPECIFIED;
18589 struct c_expr expr;
18590 location_t eloc;
18591 bool structured_block = false;
18592 bool swapped = false;
18593 bool non_lvalue_p;
18594 bool first = true;
18595 tree clauses = NULL_TREE;
18596 bool capture = false;
18597 bool compare = false;
18598 bool weak = false;
18599 enum omp_memory_order fail = OMP_MEMORY_ORDER_UNSPECIFIED;
18600 bool no_semicolon = false;
18601 bool extra_scope = false;
18602
18603 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
18604 {
18605 if (!first
18606 && c_parser_next_token_is (parser, CPP_COMMA)
18607 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
18608 c_parser_consume_token (parser);
18609
18610 first = false;
18611
18612 if (c_parser_next_token_is (parser, CPP_NAME))
18613 {
18614 const char *p
18615 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18616 location_t cloc = c_parser_peek_token (parser)->location;
18617 enum tree_code new_code = ERROR_MARK;
18618 enum omp_memory_order new_memory_order
18619 = OMP_MEMORY_ORDER_UNSPECIFIED;
18620 bool new_capture = false;
18621 bool new_compare = false;
18622 bool new_weak = false;
18623 enum omp_memory_order new_fail = OMP_MEMORY_ORDER_UNSPECIFIED;
18624
18625 if (!strcmp (p, "read"))
18626 new_code = OMP_ATOMIC_READ;
18627 else if (!strcmp (p, "write"))
18628 new_code = NOP_EXPR;
18629 else if (!strcmp (p, "update"))
18630 new_code = OMP_ATOMIC;
18631 else if (openacc && !strcmp (p, "capture"))
18632 new_code = OMP_ATOMIC_CAPTURE_NEW;
18633 else if (openacc)
18634 {
18635 p = NULL;
18636 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
18637 "or %<capture%> clause");
18638 }
18639 else if (!strcmp (p, "capture"))
18640 new_capture = true;
18641 else if (!strcmp (p, "compare"))
18642 new_compare = true;
18643 else if (!strcmp (p, "weak"))
18644 new_weak = true;
18645 else if (!strcmp (p, "fail"))
18646 {
18647 matching_parens parens;
18648
18649 c_parser_consume_token (parser);
18650 if (!parens.require_open (parser))
18651 continue;
18652
18653 if (c_parser_next_token_is (parser, CPP_NAME))
18654 {
18655 const char *q
18656 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18657
18658 if (!strcmp (q, "seq_cst"))
18659 new_fail = OMP_MEMORY_ORDER_SEQ_CST;
18660 else if (!strcmp (q, "acquire"))
18661 new_fail = OMP_MEMORY_ORDER_ACQUIRE;
18662 else if (!strcmp (q, "relaxed"))
18663 new_fail = OMP_MEMORY_ORDER_RELAXED;
18664 }
18665
18666 if (new_fail != OMP_MEMORY_ORDER_UNSPECIFIED)
18667 {
18668 c_parser_consume_token (parser);
18669 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
18670 error_at (cloc, "too many %qs clauses", "fail");
18671 else
18672 fail = new_fail;
18673 }
18674 else
18675 c_parser_error (parser, "expected %<seq_cst%>, %<acquire%> "
18676 "or %<relaxed%>");
18677 parens.skip_until_found_close (parser);
18678 continue;
18679 }
18680 else if (!strcmp (p, "seq_cst"))
18681 new_memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18682 else if (!strcmp (p, "acq_rel"))
18683 new_memory_order = OMP_MEMORY_ORDER_ACQ_REL;
18684 else if (!strcmp (p, "release"))
18685 new_memory_order = OMP_MEMORY_ORDER_RELEASE;
18686 else if (!strcmp (p, "acquire"))
18687 new_memory_order = OMP_MEMORY_ORDER_ACQUIRE;
18688 else if (!strcmp (p, "relaxed"))
18689 new_memory_order = OMP_MEMORY_ORDER_RELAXED;
18690 else if (!strcmp (p, "hint"))
18691 {
18692 c_parser_consume_token (parser);
18693 clauses = c_parser_omp_clause_hint (parser, clauses);
18694 continue;
18695 }
18696 else
18697 {
18698 p = NULL;
18699 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
18700 "%<capture%>, %<compare%>, %<weak%>, %<fail%>, "
18701 "%<seq_cst%>, %<acq_rel%>, %<release%>, "
18702 "%<relaxed%> or %<hint%> clause");
18703 }
18704 if (p)
18705 {
18706 if (new_code != ERROR_MARK)
18707 {
18708 /* OpenACC permits 'update capture'. */
18709 if (openacc
18710 && code == OMP_ATOMIC
18711 && new_code == OMP_ATOMIC_CAPTURE_NEW)
18712 code = new_code;
18713 else if (code != ERROR_MARK)
18714 error_at (cloc, "too many atomic clauses");
18715 else
18716 code = new_code;
18717 }
18718 else if (new_memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
18719 {
18720 if (memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
18721 error_at (cloc, "too many memory order clauses");
18722 else
18723 memory_order = new_memory_order;
18724 }
18725 else if (new_capture)
18726 {
18727 if (capture)
18728 error_at (cloc, "too many %qs clauses", "capture");
18729 else
18730 capture = true;
18731 }
18732 else if (new_compare)
18733 {
18734 if (compare)
18735 error_at (cloc, "too many %qs clauses", "compare");
18736 else
18737 compare = true;
18738 }
18739 else if (new_weak)
18740 {
18741 if (weak)
18742 error_at (cloc, "too many %qs clauses", "weak");
18743 else
18744 weak = true;
18745 }
18746 c_parser_consume_token (parser);
18747 continue;
18748 }
18749 }
18750 break;
18751 }
18752 c_parser_skip_to_pragma_eol (parser);
18753
18754 if (code == ERROR_MARK)
18755 code = OMP_ATOMIC;
18756 if (capture)
18757 {
18758 if (code != OMP_ATOMIC)
18759 error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
18760 "clauses", "capture");
18761 else
18762 code = OMP_ATOMIC_CAPTURE_NEW;
18763 }
18764 if (compare && code != OMP_ATOMIC && code != OMP_ATOMIC_CAPTURE_NEW)
18765 {
18766 error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
18767 "clauses", "compare");
18768 compare = false;
18769 }
18770 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED && !compare)
18771 {
18772 error_at (loc, "%qs clause requires %qs clause", "fail", "compare");
18773 fail = OMP_MEMORY_ORDER_UNSPECIFIED;
18774 }
18775 if (weak && !compare)
18776 {
18777 error_at (loc, "%qs clause requires %qs clause", "weak", "compare");
18778 weak = false;
18779 }
18780 if (openacc)
18781 memory_order = OMP_MEMORY_ORDER_RELAXED;
18782 else if (memory_order == OMP_MEMORY_ORDER_UNSPECIFIED)
18783 {
18784 omp_requires_mask
18785 = (enum omp_requires) (omp_requires_mask
18786 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED);
18787 switch ((enum omp_memory_order)
18788 (omp_requires_mask & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER))
18789 {
18790 case OMP_MEMORY_ORDER_UNSPECIFIED:
18791 case OMP_MEMORY_ORDER_RELAXED:
18792 memory_order = OMP_MEMORY_ORDER_RELAXED;
18793 break;
18794 case OMP_MEMORY_ORDER_SEQ_CST:
18795 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18796 break;
18797 case OMP_MEMORY_ORDER_ACQ_REL:
18798 switch (code)
18799 {
18800 case OMP_ATOMIC_READ:
18801 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
18802 break;
18803 case NOP_EXPR: /* atomic write */
18804 memory_order = OMP_MEMORY_ORDER_RELEASE;
18805 break;
18806 default:
18807 memory_order = OMP_MEMORY_ORDER_ACQ_REL;
18808 break;
18809 }
18810 break;
18811 default:
18812 gcc_unreachable ();
18813 }
18814 }
18815 else
18816 switch (code)
18817 {
18818 case OMP_ATOMIC_READ:
18819 if (memory_order == OMP_MEMORY_ORDER_RELEASE)
18820 {
18821 error_at (loc, "%<#pragma omp atomic read%> incompatible with "
18822 "%<release%> clause");
18823 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18824 }
18825 else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
18826 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
18827 break;
18828 case NOP_EXPR: /* atomic write */
18829 if (memory_order == OMP_MEMORY_ORDER_ACQUIRE)
18830 {
18831 error_at (loc, "%<#pragma omp atomic write%> incompatible with "
18832 "%<acquire%> clause");
18833 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18834 }
18835 else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
18836 memory_order = OMP_MEMORY_ORDER_RELEASE;
18837 break;
18838 default:
18839 break;
18840 }
18841 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
18842 memory_order
18843 = (enum omp_memory_order) (memory_order
18844 | (fail << OMP_FAIL_MEMORY_ORDER_SHIFT));
18845
18846 switch (code)
18847 {
18848 case OMP_ATOMIC_READ:
18849 case NOP_EXPR: /* atomic write */
18850 v = c_parser_cast_expression (parser, NULL).value;
18851 non_lvalue_p = !lvalue_p (v);
18852 v = c_fully_fold (v, false, NULL, true);
18853 if (v == error_mark_node)
18854 goto saw_error;
18855 if (non_lvalue_p)
18856 v = non_lvalue (v);
18857 loc = c_parser_peek_token (parser)->location;
18858 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18859 goto saw_error;
18860 if (code == NOP_EXPR)
18861 {
18862 lhs = c_parser_expression (parser).value;
18863 lhs = c_fully_fold (lhs, false, NULL);
18864 if (lhs == error_mark_node)
18865 goto saw_error;
18866 }
18867 else
18868 {
18869 lhs = c_parser_cast_expression (parser, NULL).value;
18870 non_lvalue_p = !lvalue_p (lhs);
18871 lhs = c_fully_fold (lhs, false, NULL, true);
18872 if (lhs == error_mark_node)
18873 goto saw_error;
18874 if (non_lvalue_p)
18875 lhs = non_lvalue (lhs);
18876 }
18877 if (code == NOP_EXPR)
18878 {
18879 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
18880 opcode. */
18881 code = OMP_ATOMIC;
18882 rhs = lhs;
18883 lhs = v;
18884 v = NULL_TREE;
18885 }
18886 goto done;
18887 case OMP_ATOMIC_CAPTURE_NEW:
18888 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
18889 {
18890 c_parser_consume_token (parser);
18891 structured_block = true;
18892 }
18893 else if (compare
18894 && c_parser_next_token_is_keyword (parser, RID_IF))
18895 break;
18896 else
18897 {
18898 v = c_parser_cast_expression (parser, NULL).value;
18899 non_lvalue_p = !lvalue_p (v);
18900 v = c_fully_fold (v, false, NULL, true);
18901 if (v == error_mark_node)
18902 goto saw_error;
18903 if (non_lvalue_p)
18904 v = non_lvalue (v);
18905 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18906 goto saw_error;
18907 if (compare && c_parser_next_token_is_keyword (parser, RID_IF))
18908 {
18909 eloc = c_parser_peek_token (parser)->location;
18910 error_at (eloc, "expected expression");
18911 goto saw_error;
18912 }
18913 }
18914 break;
18915 default:
18916 break;
18917 }
18918
18919 /* For structured_block case we don't know yet whether
18920 old or new x should be captured. */
18921 restart:
18922 if (compare && c_parser_next_token_is_keyword (parser, RID_IF))
18923 {
18924 c_parser_consume_token (parser);
18925
18926 matching_parens parens;
18927 if (!parens.require_open (parser))
18928 goto saw_error;
18929 eloc = c_parser_peek_token (parser)->location;
18930 c_expr cmp_expr;
18931 if (r)
18932 {
18933 cmp_expr = c_parser_cast_expression (parser, NULL);
18934 cmp_expr = default_function_array_conversion (eloc, cmp_expr);
18935 }
18936 else
18937 cmp_expr = c_parser_binary_expression (parser, NULL, void_list_node);
18938 parens.skip_until_found_close (parser);
18939 if (cmp_expr.value == error_mark_node)
18940 goto saw_error;
18941 if (r)
18942 {
18943 if (!c_tree_equal (cmp_expr.value, unfolded_lhs))
18944 goto bad_if;
18945 cmp_expr.value = rhs1;
18946 rhs1 = NULL_TREE;
18947 gcc_assert (TREE_CODE (cmp_expr.value) == EQ_EXPR);
18948 }
18949 if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
18950 ;
18951 else if (!structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
18952 {
18953 error_at (EXPR_LOC_OR_LOC (cmp_expr.value, eloc),
18954 "expected %<==%> comparison in %<if%> condition");
18955 goto saw_error;
18956 }
18957 else if (TREE_CODE (cmp_expr.value) != GT_EXPR
18958 && TREE_CODE (cmp_expr.value) != LT_EXPR)
18959 {
18960 error_at (EXPR_LOC_OR_LOC (cmp_expr.value, eloc),
18961 "expected %<==%>, %<<%> or %<>%> comparison in %<if%> "
18962 "condition");
18963 goto saw_error;
18964 }
18965 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
18966 goto saw_error;
18967
18968 extra_scope = true;
18969 eloc = c_parser_peek_token (parser)->location;
18970 expr = c_parser_cast_expression (parser, NULL);
18971 lhs = expr.value;
18972 expr = default_function_array_conversion (eloc, expr);
18973 unfolded_lhs = expr.value;
18974 lhs = c_fully_fold (lhs, false, NULL, true);
18975 orig_lhs = lhs;
18976 if (lhs == error_mark_node)
18977 goto saw_error;
18978 if (!lvalue_p (unfolded_lhs))
18979 lhs = non_lvalue (lhs);
18980 if (!c_parser_next_token_is (parser, CPP_EQ))
18981 {
18982 c_parser_error (parser, "expected %<=%>");
18983 goto saw_error;
18984 }
18985 c_parser_consume_token (parser);
18986 eloc = c_parser_peek_token (parser)->location;
18987 expr = c_parser_expr_no_commas (parser, NULL);
18988 rhs1 = expr.value;
18989
18990 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
18991 goto saw_error;
18992
18993 if (!c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
18994 goto saw_error;
18995
18996 extra_scope = false;
18997 no_semicolon = true;
18998
18999 if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 0), unfolded_lhs))
19000 {
19001 if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
19002 {
19003 opcode = COND_EXPR;
19004 rhs = c_fully_fold (TREE_OPERAND (cmp_expr.value, 1),
19005 false, NULL, true);
19006 rhs1 = c_fully_fold (rhs1, false, NULL, true);
19007 }
19008 else if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 1), rhs1))
19009 {
19010 opcode = (TREE_CODE (cmp_expr.value) == GT_EXPR
19011 ? MIN_EXPR : MAX_EXPR);
19012 rhs = c_fully_fold (rhs1, false, NULL, true);
19013 rhs1 = c_fully_fold (TREE_OPERAND (cmp_expr.value, 0),
19014 false, NULL, true);
19015 }
19016 else
19017 goto bad_if;
19018 }
19019 else if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
19020 goto bad_if;
19021 else if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 1), unfolded_lhs)
19022 && c_tree_equal (TREE_OPERAND (cmp_expr.value, 0), rhs1))
19023 {
19024 opcode = (TREE_CODE (cmp_expr.value) == GT_EXPR
19025 ? MAX_EXPR : MIN_EXPR);
19026 rhs = c_fully_fold (rhs1, false, NULL, true);
19027 rhs1 = c_fully_fold (TREE_OPERAND (cmp_expr.value, 1),
19028 false, NULL, true);
19029 }
19030 else
19031 {
19032 bad_if:
19033 c_parser_error (parser,
19034 "invalid form of %<#pragma omp atomic compare%>");
19035 goto saw_error;
19036 }
19037
19038 if (c_parser_next_token_is_keyword (parser, RID_ELSE))
19039 {
19040 if (code != OMP_ATOMIC_CAPTURE_NEW
19041 || (structured_block && r == NULL_TREE)
19042 || TREE_CODE (cmp_expr.value) != EQ_EXPR)
19043 {
19044 eloc = c_parser_peek_token (parser)->location;
19045 error_at (eloc, "unexpected %<else%>");
19046 goto saw_error;
19047 }
19048
19049 c_parser_consume_token (parser);
19050
19051 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
19052 goto saw_error;
19053
19054 extra_scope = true;
19055 v = c_parser_cast_expression (parser, NULL).value;
19056 non_lvalue_p = !lvalue_p (v);
19057 v = c_fully_fold (v, false, NULL, true);
19058 if (v == error_mark_node)
19059 goto saw_error;
19060 if (non_lvalue_p)
19061 v = non_lvalue (v);
19062 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
19063 goto saw_error;
19064
19065 expr = c_parser_expr_no_commas (parser, NULL);
19066
19067 if (!c_tree_equal (expr.value, unfolded_lhs))
19068 goto bad_if;
19069
19070 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
19071 goto saw_error;
19072
19073 if (!c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
19074 goto saw_error;
19075
19076 extra_scope = false;
19077 code = OMP_ATOMIC_CAPTURE_OLD;
19078 if (r == NULL_TREE)
19079 /* Signal to c_finish_omp_atomic that in
19080 if (x == e) { x = d; } else { v = x; }
19081 case the store to v should be conditional. */
19082 r = void_list_node;
19083 }
19084 else if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
19085 {
19086 c_parser_require_keyword (parser, RID_ELSE, "expected %<else%>");
19087 goto saw_error;
19088 }
19089 else if (code == OMP_ATOMIC_CAPTURE_NEW
19090 && r != NULL_TREE
19091 && v == NULL_TREE)
19092 code = OMP_ATOMIC;
19093 goto stmt_done;
19094 }
19095 eloc = c_parser_peek_token (parser)->location;
19096 expr = c_parser_cast_expression (parser, NULL);
19097 lhs = expr.value;
19098 expr = default_function_array_conversion (eloc, expr);
19099 unfolded_lhs = expr.value;
19100 lhs = c_fully_fold (lhs, false, NULL, true);
19101 orig_lhs = lhs;
19102 switch (TREE_CODE (lhs))
19103 {
19104 invalid_compare:
19105 error_at (eloc, "invalid form of %<pragma omp atomic compare%>");
19106 /* FALLTHRU */
19107 case ERROR_MARK:
19108 saw_error:
19109 c_parser_skip_to_end_of_block_or_statement (parser);
19110 if (extra_scope && c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
19111 c_parser_consume_token (parser);
19112 if (structured_block)
19113 {
19114 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
19115 c_parser_consume_token (parser);
19116 else if (code == OMP_ATOMIC_CAPTURE_NEW)
19117 {
19118 c_parser_skip_to_end_of_block_or_statement (parser);
19119 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
19120 c_parser_consume_token (parser);
19121 }
19122 }
19123 return;
19124
19125 case POSTINCREMENT_EXPR:
19126 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
19127 code = OMP_ATOMIC_CAPTURE_OLD;
19128 /* FALLTHROUGH */
19129 case PREINCREMENT_EXPR:
19130 lhs = TREE_OPERAND (lhs, 0);
19131 unfolded_lhs = NULL_TREE;
19132 opcode = PLUS_EXPR;
19133 rhs = integer_one_node;
19134 if (compare)
19135 goto invalid_compare;
19136 break;
19137
19138 case POSTDECREMENT_EXPR:
19139 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
19140 code = OMP_ATOMIC_CAPTURE_OLD;
19141 /* FALLTHROUGH */
19142 case PREDECREMENT_EXPR:
19143 lhs = TREE_OPERAND (lhs, 0);
19144 unfolded_lhs = NULL_TREE;
19145 opcode = MINUS_EXPR;
19146 rhs = integer_one_node;
19147 if (compare)
19148 goto invalid_compare;
19149 break;
19150
19151 case COMPOUND_EXPR:
19152 if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR
19153 && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR
19154 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR
19155 && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0)
19156 && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
19157 (TREE_OPERAND (lhs, 1), 0), 0)))
19158 == BOOLEAN_TYPE)
19159 /* Undo effects of boolean_increment for post {in,de}crement. */
19160 lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
19161 /* FALLTHRU */
19162 case MODIFY_EXPR:
19163 if (TREE_CODE (lhs) == MODIFY_EXPR
19164 && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) == BOOLEAN_TYPE)
19165 {
19166 /* Undo effects of boolean_increment. */
19167 if (integer_onep (TREE_OPERAND (lhs, 1)))
19168 {
19169 /* This is pre or post increment. */
19170 rhs = TREE_OPERAND (lhs, 1);
19171 lhs = TREE_OPERAND (lhs, 0);
19172 unfolded_lhs = NULL_TREE;
19173 opcode = NOP_EXPR;
19174 if (code == OMP_ATOMIC_CAPTURE_NEW
19175 && !structured_block
19176 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
19177 code = OMP_ATOMIC_CAPTURE_OLD;
19178 if (compare)
19179 goto invalid_compare;
19180 break;
19181 }
19182 if (TREE_CODE (TREE_OPERAND (lhs, 1)) == TRUTH_NOT_EXPR
19183 && TREE_OPERAND (lhs, 0)
19184 == TREE_OPERAND (TREE_OPERAND (lhs, 1), 0))
19185 {
19186 /* This is pre or post decrement. */
19187 rhs = TREE_OPERAND (lhs, 1);
19188 lhs = TREE_OPERAND (lhs, 0);
19189 unfolded_lhs = NULL_TREE;
19190 opcode = NOP_EXPR;
19191 if (code == OMP_ATOMIC_CAPTURE_NEW
19192 && !structured_block
19193 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
19194 code = OMP_ATOMIC_CAPTURE_OLD;
19195 if (compare)
19196 goto invalid_compare;
19197 break;
19198 }
19199 }
19200 /* FALLTHRU */
19201 default:
19202 if (!lvalue_p (unfolded_lhs))
19203 lhs = non_lvalue (lhs);
19204 if (compare && !c_parser_next_token_is (parser, CPP_EQ))
19205 {
19206 c_parser_error (parser, "expected %<=%>");
19207 goto saw_error;
19208 }
19209 switch (c_parser_peek_token (parser)->type)
19210 {
19211 case CPP_MULT_EQ:
19212 opcode = MULT_EXPR;
19213 break;
19214 case CPP_DIV_EQ:
19215 opcode = TRUNC_DIV_EXPR;
19216 break;
19217 case CPP_PLUS_EQ:
19218 opcode = PLUS_EXPR;
19219 break;
19220 case CPP_MINUS_EQ:
19221 opcode = MINUS_EXPR;
19222 break;
19223 case CPP_LSHIFT_EQ:
19224 opcode = LSHIFT_EXPR;
19225 break;
19226 case CPP_RSHIFT_EQ:
19227 opcode = RSHIFT_EXPR;
19228 break;
19229 case CPP_AND_EQ:
19230 opcode = BIT_AND_EXPR;
19231 break;
19232 case CPP_OR_EQ:
19233 opcode = BIT_IOR_EXPR;
19234 break;
19235 case CPP_XOR_EQ:
19236 opcode = BIT_XOR_EXPR;
19237 break;
19238 case CPP_EQ:
19239 c_parser_consume_token (parser);
19240 eloc = c_parser_peek_token (parser)->location;
19241 expr = c_parser_expr_no_commas (parser, NULL, unfolded_lhs);
19242 rhs1 = expr.value;
19243 switch (TREE_CODE (rhs1))
19244 {
19245 case MULT_EXPR:
19246 case TRUNC_DIV_EXPR:
19247 case RDIV_EXPR:
19248 case PLUS_EXPR:
19249 case MINUS_EXPR:
19250 case LSHIFT_EXPR:
19251 case RSHIFT_EXPR:
19252 case BIT_AND_EXPR:
19253 case BIT_IOR_EXPR:
19254 case BIT_XOR_EXPR:
19255 if (compare)
19256 break;
19257 if (c_tree_equal (TREE_OPERAND (rhs1, 0), unfolded_lhs))
19258 {
19259 opcode = TREE_CODE (rhs1);
19260 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
19261 true);
19262 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
19263 true);
19264 goto stmt_done;
19265 }
19266 if (c_tree_equal (TREE_OPERAND (rhs1, 1), unfolded_lhs))
19267 {
19268 opcode = TREE_CODE (rhs1);
19269 rhs = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
19270 true);
19271 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
19272 true);
19273 swapped = !commutative_tree_code (opcode);
19274 goto stmt_done;
19275 }
19276 break;
19277 case COND_EXPR:
19278 if (!compare)
19279 break;
19280 if (TREE_CODE (TREE_OPERAND (rhs1, 0)) != GT_EXPR
19281 && TREE_CODE (TREE_OPERAND (rhs1, 0)) != LT_EXPR
19282 && TREE_CODE (TREE_OPERAND (rhs1, 0)) != EQ_EXPR)
19283 break;
19284 if (!TREE_OPERAND (rhs1, 1))
19285 break;
19286 if (!c_tree_equal (TREE_OPERAND (rhs1, 2), unfolded_lhs))
19287 break;
19288 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0),
19289 unfolded_lhs))
19290 {
19291 if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == EQ_EXPR)
19292 {
19293 opcode = COND_EXPR;
19294 rhs = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
19295 0), 1),
19296 false, NULL, true);
19297 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false,
19298 NULL, true);
19299 goto stmt_done;
19300 }
19301 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1),
19302 TREE_OPERAND (rhs1, 1)))
19303 {
19304 opcode = (TREE_CODE (TREE_OPERAND (rhs1, 0)) == GT_EXPR
19305 ? MIN_EXPR : MAX_EXPR);
19306 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
19307 true);
19308 rhs1 = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
19309 0), 0),
19310 false, NULL, true);
19311 goto stmt_done;
19312 }
19313 }
19314 else if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == EQ_EXPR)
19315 break;
19316 else if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1),
19317 unfolded_lhs))
19318 {
19319 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0),
19320 TREE_OPERAND (rhs1, 1)))
19321 {
19322 opcode = (TREE_CODE (TREE_OPERAND (rhs1, 0)) == GT_EXPR
19323 ? MAX_EXPR : MIN_EXPR);
19324 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
19325 true);
19326 rhs1 = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
19327 0), 1),
19328 false, NULL, true);
19329 goto stmt_done;
19330 }
19331 }
19332 break;
19333 case EQ_EXPR:
19334 if (!compare
19335 || code != OMP_ATOMIC_CAPTURE_NEW
19336 || !structured_block
19337 || v
19338 || r)
19339 break;
19340 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
19341 && c_parser_peek_2nd_token (parser)->keyword == RID_IF)
19342 {
19343 r = lhs;
19344 lhs = NULL_TREE;
19345 c_parser_consume_token (parser);
19346 goto restart;
19347 }
19348 break;
19349 case ERROR_MARK:
19350 goto saw_error;
19351 default:
19352 break;
19353 }
19354 if (c_parser_peek_token (parser)->type == CPP_SEMICOLON)
19355 {
19356 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
19357 {
19358 code = OMP_ATOMIC_CAPTURE_OLD;
19359 v = lhs;
19360 lhs = NULL_TREE;
19361 expr = default_function_array_read_conversion (eloc, expr);
19362 unfolded_lhs1 = expr.value;
19363 lhs1 = c_fully_fold (unfolded_lhs1, false, NULL, true);
19364 rhs1 = NULL_TREE;
19365 c_parser_consume_token (parser);
19366 goto restart;
19367 }
19368 if (structured_block && !compare)
19369 {
19370 opcode = NOP_EXPR;
19371 expr = default_function_array_read_conversion (eloc, expr);
19372 rhs = c_fully_fold (expr.value, false, NULL, true);
19373 rhs1 = NULL_TREE;
19374 goto stmt_done;
19375 }
19376 }
19377 c_parser_error (parser, "invalid form of %<#pragma omp atomic%>");
19378 goto saw_error;
19379 default:
19380 c_parser_error (parser,
19381 "invalid operator for %<#pragma omp atomic%>");
19382 goto saw_error;
19383 }
19384
19385 /* Arrange to pass the location of the assignment operator to
19386 c_finish_omp_atomic. */
19387 loc = c_parser_peek_token (parser)->location;
19388 c_parser_consume_token (parser);
19389 eloc = c_parser_peek_token (parser)->location;
19390 expr = c_parser_expression (parser);
19391 expr = default_function_array_read_conversion (eloc, expr);
19392 rhs = expr.value;
19393 rhs = c_fully_fold (rhs, false, NULL, true);
19394 break;
19395 }
19396 stmt_done:
19397 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW && r == NULL_TREE)
19398 {
19399 if (!no_semicolon
19400 && !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
19401 goto saw_error;
19402 no_semicolon = false;
19403 v = c_parser_cast_expression (parser, NULL).value;
19404 non_lvalue_p = !lvalue_p (v);
19405 v = c_fully_fold (v, false, NULL, true);
19406 if (v == error_mark_node)
19407 goto saw_error;
19408 if (non_lvalue_p)
19409 v = non_lvalue (v);
19410 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
19411 goto saw_error;
19412 eloc = c_parser_peek_token (parser)->location;
19413 expr = c_parser_cast_expression (parser, NULL);
19414 lhs1 = expr.value;
19415 expr = default_function_array_read_conversion (eloc, expr);
19416 unfolded_lhs1 = expr.value;
19417 lhs1 = c_fully_fold (lhs1, false, NULL, true);
19418 if (lhs1 == error_mark_node)
19419 goto saw_error;
19420 if (!lvalue_p (unfolded_lhs1))
19421 lhs1 = non_lvalue (lhs1);
19422 }
19423 if (structured_block)
19424 {
19425 if (!no_semicolon)
19426 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
19427 c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>");
19428 }
19429 done:
19430 if (weak && opcode != COND_EXPR)
19431 {
19432 error_at (loc, "%<weak%> clause requires atomic equality comparison");
19433 weak = false;
19434 }
19435 if (unfolded_lhs && unfolded_lhs1
19436 && !c_tree_equal (unfolded_lhs, unfolded_lhs1))
19437 {
19438 error ("%<#pragma omp atomic capture%> uses two different "
19439 "expressions for memory");
19440 stmt = error_mark_node;
19441 }
19442 else
19443 stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs, v, lhs1, rhs1, r,
19444 swapped, memory_order, weak);
19445 if (stmt != error_mark_node)
19446 add_stmt (stmt);
19447
19448 if (!structured_block && !no_semicolon)
19449 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
19450 }
19451
19452
19453 /* OpenMP 2.5:
19454 # pragma omp barrier new-line
19455 */
19456
19457 static void
19458 c_parser_omp_barrier (c_parser *parser)
19459 {
19460 location_t loc = c_parser_peek_token (parser)->location;
19461 c_parser_consume_pragma (parser);
19462 c_parser_skip_to_pragma_eol (parser);
19463
19464 c_finish_omp_barrier (loc);
19465 }
19466
19467 /* OpenMP 2.5:
19468 # pragma omp critical [(name)] new-line
19469 structured-block
19470
19471 OpenMP 4.5:
19472 # pragma omp critical [(name) [hint(expression)]] new-line
19473
19474 LOC is the location of the #pragma itself. */
19475
19476 #define OMP_CRITICAL_CLAUSE_MASK \
19477 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
19478
19479 static tree
19480 c_parser_omp_critical (location_t loc, c_parser *parser, bool *if_p)
19481 {
19482 tree stmt, name = NULL_TREE, clauses = NULL_TREE;
19483
19484 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
19485 {
19486 c_parser_consume_token (parser);
19487 if (c_parser_next_token_is (parser, CPP_NAME))
19488 {
19489 name = c_parser_peek_token (parser)->value;
19490 c_parser_consume_token (parser);
19491 c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
19492 }
19493 else
19494 c_parser_error (parser, "expected identifier");
19495
19496 if (c_parser_next_token_is (parser, CPP_COMMA)
19497 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
19498 c_parser_consume_token (parser);
19499 }
19500 clauses = c_parser_omp_all_clauses (parser, OMP_CRITICAL_CLAUSE_MASK,
19501 "#pragma omp critical");
19502 stmt = c_parser_omp_structured_block (parser, if_p);
19503 return c_finish_omp_critical (loc, stmt, name, clauses);
19504 }
19505
19506 /* OpenMP 5.0:
19507 # pragma omp depobj ( depobj ) depobj-clause new-line
19508
19509 depobj-clause:
19510 depend (dependence-type : locator)
19511 destroy
19512 update (dependence-type)
19513
19514 dependence-type:
19515 in
19516 out
19517 inout
19518 mutexinout */
19519
19520 static void
19521 c_parser_omp_depobj (c_parser *parser)
19522 {
19523 location_t loc = c_parser_peek_token (parser)->location;
19524 c_parser_consume_pragma (parser);
19525 matching_parens parens;
19526 if (!parens.require_open (parser))
19527 {
19528 c_parser_skip_to_pragma_eol (parser);
19529 return;
19530 }
19531
19532 tree depobj = c_parser_expr_no_commas (parser, NULL).value;
19533 if (depobj != error_mark_node)
19534 {
19535 if (!lvalue_p (depobj))
19536 {
19537 error_at (EXPR_LOC_OR_LOC (depobj, loc),
19538 "%<depobj%> expression is not lvalue expression");
19539 depobj = error_mark_node;
19540 }
19541 else
19542 {
19543 tree addr = build_unary_op (EXPR_LOC_OR_LOC (depobj, loc), ADDR_EXPR,
19544 depobj, false);
19545 if (addr == error_mark_node)
19546 depobj = error_mark_node;
19547 else
19548 depobj = build_indirect_ref (EXPR_LOC_OR_LOC (depobj, loc),
19549 addr, RO_UNARY_STAR);
19550 }
19551 }
19552
19553 parens.skip_until_found_close (parser);
19554 tree clause = NULL_TREE;
19555 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_INVALID;
19556 location_t c_loc = c_parser_peek_token (parser)->location;
19557 if (c_parser_next_token_is (parser, CPP_NAME))
19558 {
19559 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19560
19561 c_parser_consume_token (parser);
19562 if (!strcmp ("depend", p))
19563 {
19564 clause = c_parser_omp_clause_depend (parser, NULL_TREE);
19565 clause = c_finish_omp_clauses (clause, C_ORT_OMP);
19566 if (!clause)
19567 clause = error_mark_node;
19568 }
19569 else if (!strcmp ("destroy", p))
19570 kind = OMP_CLAUSE_DEPEND_LAST;
19571 else if (!strcmp ("update", p))
19572 {
19573 matching_parens c_parens;
19574 if (c_parens.require_open (parser))
19575 {
19576 location_t c2_loc = c_parser_peek_token (parser)->location;
19577 if (c_parser_next_token_is (parser, CPP_NAME))
19578 {
19579 const char *p2
19580 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19581
19582 c_parser_consume_token (parser);
19583 if (!strcmp ("in", p2))
19584 kind = OMP_CLAUSE_DEPEND_IN;
19585 else if (!strcmp ("out", p2))
19586 kind = OMP_CLAUSE_DEPEND_OUT;
19587 else if (!strcmp ("inout", p2))
19588 kind = OMP_CLAUSE_DEPEND_INOUT;
19589 else if (!strcmp ("mutexinoutset", p2))
19590 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
19591 else if (!strcmp ("inoutset", p2))
19592 kind = OMP_CLAUSE_DEPEND_INOUTSET;
19593 }
19594 if (kind == OMP_CLAUSE_DEPEND_INVALID)
19595 {
19596 clause = error_mark_node;
19597 error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%>, "
19598 "%<mutexinoutset%> or %<inoutset%>");
19599 }
19600 c_parens.skip_until_found_close (parser);
19601 }
19602 else
19603 clause = error_mark_node;
19604 }
19605 }
19606 if (!clause && kind == OMP_CLAUSE_DEPEND_INVALID)
19607 {
19608 clause = error_mark_node;
19609 error_at (c_loc, "expected %<depend%>, %<destroy%> or %<update%> clause");
19610 }
19611 c_parser_skip_to_pragma_eol (parser);
19612
19613 c_finish_omp_depobj (loc, depobj, kind, clause);
19614 }
19615
19616
19617 /* OpenMP 2.5:
19618 # pragma omp flush flush-vars[opt] new-line
19619
19620 flush-vars:
19621 ( variable-list )
19622
19623 OpenMP 5.0:
19624 # pragma omp flush memory-order-clause new-line */
19625
19626 static void
19627 c_parser_omp_flush (c_parser *parser)
19628 {
19629 location_t loc = c_parser_peek_token (parser)->location;
19630 c_parser_consume_pragma (parser);
19631 enum memmodel mo = MEMMODEL_LAST;
19632 if (c_parser_next_token_is (parser, CPP_NAME))
19633 {
19634 const char *p
19635 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19636
19637 if (!strcmp (p, "seq_cst"))
19638 mo = MEMMODEL_SEQ_CST;
19639 else if (!strcmp (p, "acq_rel"))
19640 mo = MEMMODEL_ACQ_REL;
19641 else if (!strcmp (p, "release"))
19642 mo = MEMMODEL_RELEASE;
19643 else if (!strcmp (p, "acquire"))
19644 mo = MEMMODEL_ACQUIRE;
19645 else
19646 error_at (c_parser_peek_token (parser)->location,
19647 "expected %<seq_cst%>, %<acq_rel%>, %<release%> or "
19648 "%<acquire%>");
19649 c_parser_consume_token (parser);
19650 }
19651 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
19652 {
19653 if (mo != MEMMODEL_LAST)
19654 error_at (c_parser_peek_token (parser)->location,
19655 "%<flush%> list specified together with memory order "
19656 "clause");
19657 c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
19658 }
19659 else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
19660 c_parser_error (parser, "expected %<(%> or end of line");
19661 c_parser_skip_to_pragma_eol (parser);
19662
19663 c_finish_omp_flush (loc, mo);
19664 }
19665
19666 /* Parse an OpenMP structured block sequence. KIND is the corresponding
19667 separating directive. */
19668
19669 static tree
19670 c_parser_omp_structured_block_sequence (c_parser *parser,
19671 enum pragma_kind kind)
19672 {
19673 tree stmt = push_stmt_list ();
19674 c_parser_statement (parser, NULL);
19675 do
19676 {
19677 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
19678 break;
19679 if (c_parser_next_token_is (parser, CPP_EOF))
19680 break;
19681
19682 if (kind != PRAGMA_NONE
19683 && c_parser_peek_token (parser)->pragma_kind == kind)
19684 break;
19685 c_parser_statement (parser, NULL);
19686 }
19687 while (1);
19688 return pop_stmt_list (stmt);
19689 }
19690
19691 /* OpenMP 5.0:
19692
19693 scan-loop-body:
19694 { structured-block scan-directive structured-block } */
19695
19696 static void
19697 c_parser_omp_scan_loop_body (c_parser *parser, bool open_brace_parsed)
19698 {
19699 tree substmt;
19700 location_t loc;
19701 tree clauses = NULL_TREE;
19702
19703 loc = c_parser_peek_token (parser)->location;
19704 if (!open_brace_parsed
19705 && !c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
19706 {
19707 /* Avoid skipping until the end of the block. */
19708 parser->error = false;
19709 return;
19710 }
19711
19712 substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_OMP_SCAN);
19713 substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE);
19714 SET_EXPR_LOCATION (substmt, loc);
19715 add_stmt (substmt);
19716
19717 loc = c_parser_peek_token (parser)->location;
19718 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SCAN)
19719 {
19720 enum omp_clause_code clause = OMP_CLAUSE_ERROR;
19721
19722 c_parser_consume_pragma (parser);
19723
19724 if (c_parser_next_token_is (parser, CPP_NAME))
19725 {
19726 const char *p
19727 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19728 if (strcmp (p, "inclusive") == 0)
19729 clause = OMP_CLAUSE_INCLUSIVE;
19730 else if (strcmp (p, "exclusive") == 0)
19731 clause = OMP_CLAUSE_EXCLUSIVE;
19732 }
19733 if (clause != OMP_CLAUSE_ERROR)
19734 {
19735 c_parser_consume_token (parser);
19736 clauses = c_parser_omp_var_list_parens (parser, clause, NULL_TREE);
19737 }
19738 else
19739 c_parser_error (parser, "expected %<inclusive%> or "
19740 "%<exclusive%> clause");
19741 c_parser_skip_to_pragma_eol (parser);
19742 }
19743 else
19744 error ("expected %<#pragma omp scan%>");
19745
19746 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
19747 substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_NONE);
19748 substmt = build2 (OMP_SCAN, void_type_node, substmt, clauses);
19749 SET_EXPR_LOCATION (substmt, loc);
19750 add_stmt (substmt);
19751
19752 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
19753 "expected %<}%>");
19754 }
19755
19756 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
19757 The real trick here is to determine the loop control variable early
19758 so that we can push a new decl if necessary to make it private.
19759 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
19760 respectively. */
19761
19762 static tree
19763 c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
19764 tree clauses, tree *cclauses, bool *if_p)
19765 {
19766 tree decl, cond, incr, body, init, stmt, cl;
19767 unsigned char save_in_statement;
19768 tree declv, condv, incrv, initv, ret = NULL_TREE;
19769 tree pre_body = NULL_TREE, this_pre_body;
19770 tree ordered_cl = NULL_TREE;
19771 bool fail = false, open_brace_parsed = false;
19772 int i, collapse = 1, ordered = 0, count, nbraces = 0;
19773 location_t for_loc;
19774 bool tiling = false;
19775 bool inscan = false;
19776 vec<tree, va_gc> *for_block = make_tree_vector ();
19777
19778 for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
19779 if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
19780 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl));
19781 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_TILE)
19782 {
19783 tiling = true;
19784 collapse = list_length (OMP_CLAUSE_TILE_LIST (cl));
19785 }
19786 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED
19787 && OMP_CLAUSE_ORDERED_EXPR (cl))
19788 {
19789 ordered_cl = cl;
19790 ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
19791 }
19792 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_REDUCTION
19793 && OMP_CLAUSE_REDUCTION_INSCAN (cl)
19794 && (code == OMP_SIMD || code == OMP_FOR))
19795 inscan = true;
19796
19797 if (ordered && ordered < collapse)
19798 {
19799 error_at (OMP_CLAUSE_LOCATION (ordered_cl),
19800 "%<ordered%> clause parameter is less than %<collapse%>");
19801 OMP_CLAUSE_ORDERED_EXPR (ordered_cl)
19802 = build_int_cst (NULL_TREE, collapse);
19803 ordered = collapse;
19804 }
19805
19806 gcc_assert (tiling || (collapse >= 1 && ordered >= 0));
19807 count = ordered ? ordered : collapse;
19808
19809 declv = make_tree_vec (count);
19810 initv = make_tree_vec (count);
19811 condv = make_tree_vec (count);
19812 incrv = make_tree_vec (count);
19813
19814 if (!c_parser_next_token_is_keyword (parser, RID_FOR))
19815 {
19816 c_parser_error (parser, "for statement expected");
19817 return NULL;
19818 }
19819 for_loc = c_parser_peek_token (parser)->location;
19820 c_parser_consume_token (parser);
19821
19822 /* Forbid break/continue in the loop initializer, condition, and
19823 increment expressions. */
19824 save_in_statement = in_statement;
19825 in_statement = IN_OMP_BLOCK;
19826
19827 for (i = 0; i < count; i++)
19828 {
19829 int bracecount = 0;
19830
19831 matching_parens parens;
19832 if (!parens.require_open (parser))
19833 goto pop_scopes;
19834
19835 /* Parse the initialization declaration or expression. */
19836 if (c_parser_next_tokens_start_declaration (parser))
19837 {
19838 if (i > 0)
19839 vec_safe_push (for_block, c_begin_compound_stmt (true));
19840 this_pre_body = push_stmt_list ();
19841 c_in_omp_for = true;
19842 c_parser_declaration_or_fndef (parser, true, true, true, true, true);
19843 c_in_omp_for = false;
19844 if (this_pre_body)
19845 {
19846 this_pre_body = pop_stmt_list (this_pre_body);
19847 if (pre_body)
19848 {
19849 tree t = pre_body;
19850 pre_body = push_stmt_list ();
19851 add_stmt (t);
19852 add_stmt (this_pre_body);
19853 pre_body = pop_stmt_list (pre_body);
19854 }
19855 else
19856 pre_body = this_pre_body;
19857 }
19858 decl = check_for_loop_decls (for_loc, flag_isoc99);
19859 if (decl == NULL)
19860 goto error_init;
19861 if (DECL_INITIAL (decl) == error_mark_node)
19862 decl = error_mark_node;
19863 init = decl;
19864 }
19865 else if (c_parser_next_token_is (parser, CPP_NAME)
19866 && c_parser_peek_2nd_token (parser)->type == CPP_EQ)
19867 {
19868 struct c_expr decl_exp;
19869 struct c_expr init_exp;
19870 location_t init_loc;
19871
19872 decl_exp = c_parser_postfix_expression (parser);
19873 decl = decl_exp.value;
19874
19875 c_parser_require (parser, CPP_EQ, "expected %<=%>");
19876
19877 init_loc = c_parser_peek_token (parser)->location;
19878 init_exp = c_parser_expr_no_commas (parser, NULL);
19879 init_exp = default_function_array_read_conversion (init_loc,
19880 init_exp);
19881 c_in_omp_for = true;
19882 init = build_modify_expr (init_loc, decl, decl_exp.original_type,
19883 NOP_EXPR, init_loc, init_exp.value,
19884 init_exp.original_type);
19885 c_in_omp_for = false;
19886 init = c_process_expr_stmt (init_loc, init);
19887
19888 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
19889 }
19890 else
19891 {
19892 error_init:
19893 c_parser_error (parser,
19894 "expected iteration declaration or initialization");
19895 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
19896 "expected %<)%>");
19897 fail = true;
19898 goto parse_next;
19899 }
19900
19901 /* Parse the loop condition. */
19902 cond = NULL_TREE;
19903 if (c_parser_next_token_is_not (parser, CPP_SEMICOLON))
19904 {
19905 location_t cond_loc = c_parser_peek_token (parser)->location;
19906 c_in_omp_for = true;
19907 struct c_expr cond_expr
19908 = c_parser_binary_expression (parser, NULL, NULL_TREE);
19909 c_in_omp_for = false;
19910
19911 cond = cond_expr.value;
19912 cond = c_objc_common_truthvalue_conversion (cond_loc, cond);
19913 switch (cond_expr.original_code)
19914 {
19915 case GT_EXPR:
19916 case GE_EXPR:
19917 case LT_EXPR:
19918 case LE_EXPR:
19919 break;
19920 case NE_EXPR:
19921 if (code != OACC_LOOP)
19922 break;
19923 /* FALLTHRU. */
19924 default:
19925 /* Can't be cond = error_mark_node, because we want to preserve
19926 the location until c_finish_omp_for. */
19927 cond = build1 (NOP_EXPR, boolean_type_node, error_mark_node);
19928 break;
19929 }
19930 protected_set_expr_location (cond, cond_loc);
19931 }
19932 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
19933
19934 /* Parse the increment expression. */
19935 incr = NULL_TREE;
19936 if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
19937 {
19938 location_t incr_loc = c_parser_peek_token (parser)->location;
19939
19940 incr = c_process_expr_stmt (incr_loc,
19941 c_parser_expression (parser).value);
19942 }
19943 parens.skip_until_found_close (parser);
19944
19945 if (decl == NULL || decl == error_mark_node || init == error_mark_node)
19946 fail = true;
19947 else
19948 {
19949 TREE_VEC_ELT (declv, i) = decl;
19950 TREE_VEC_ELT (initv, i) = init;
19951 TREE_VEC_ELT (condv, i) = cond;
19952 TREE_VEC_ELT (incrv, i) = incr;
19953 }
19954
19955 parse_next:
19956 if (i == count - 1)
19957 break;
19958
19959 /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
19960 in between the collapsed for loops to be still considered perfectly
19961 nested. Hopefully the final version clarifies this.
19962 For now handle (multiple) {'s and empty statements. */
19963 do
19964 {
19965 if (c_parser_next_token_is_keyword (parser, RID_FOR))
19966 {
19967 c_parser_consume_token (parser);
19968 break;
19969 }
19970 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
19971 {
19972 c_parser_consume_token (parser);
19973 bracecount++;
19974 }
19975 else if (bracecount
19976 && c_parser_next_token_is (parser, CPP_SEMICOLON))
19977 c_parser_consume_token (parser);
19978 else
19979 {
19980 c_parser_error (parser, "not enough perfectly nested loops");
19981 if (bracecount)
19982 {
19983 open_brace_parsed = true;
19984 bracecount--;
19985 }
19986 fail = true;
19987 count = 0;
19988 break;
19989 }
19990 }
19991 while (1);
19992
19993 nbraces += bracecount;
19994 }
19995
19996 if (nbraces)
19997 if_p = NULL;
19998
19999 in_statement = IN_OMP_FOR;
20000 body = push_stmt_list ();
20001
20002 if (inscan)
20003 c_parser_omp_scan_loop_body (parser, open_brace_parsed);
20004 else if (open_brace_parsed)
20005 {
20006 location_t here = c_parser_peek_token (parser)->location;
20007 stmt = c_begin_compound_stmt (true);
20008 c_parser_compound_statement_nostart (parser);
20009 add_stmt (c_end_compound_stmt (here, stmt, true));
20010 }
20011 else
20012 add_stmt (c_parser_c99_block_statement (parser, if_p));
20013
20014 body = pop_stmt_list (body);
20015 in_statement = save_in_statement;
20016
20017 while (nbraces)
20018 {
20019 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
20020 {
20021 c_parser_consume_token (parser);
20022 nbraces--;
20023 }
20024 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
20025 c_parser_consume_token (parser);
20026 else
20027 {
20028 c_parser_error (parser, "collapsed loops not perfectly nested");
20029 while (nbraces)
20030 {
20031 location_t here = c_parser_peek_token (parser)->location;
20032 stmt = c_begin_compound_stmt (true);
20033 add_stmt (body);
20034 c_parser_compound_statement_nostart (parser);
20035 body = c_end_compound_stmt (here, stmt, true);
20036 nbraces--;
20037 }
20038 goto pop_scopes;
20039 }
20040 }
20041
20042 /* Only bother calling c_finish_omp_for if we haven't already generated
20043 an error from the initialization parsing. */
20044 if (!fail)
20045 {
20046 c_in_omp_for = true;
20047 stmt = c_finish_omp_for (loc, code, declv, NULL, initv, condv,
20048 incrv, body, pre_body, true);
20049 c_in_omp_for = false;
20050
20051 /* Check for iterators appearing in lb, b or incr expressions. */
20052 if (stmt && !c_omp_check_loop_iv (stmt, declv, NULL))
20053 stmt = NULL_TREE;
20054
20055 if (stmt)
20056 {
20057 add_stmt (stmt);
20058
20059 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (stmt)); i++)
20060 {
20061 tree init = TREE_VEC_ELT (OMP_FOR_INIT (stmt), i);
20062 gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
20063 tree decl = TREE_OPERAND (init, 0);
20064 tree cond = TREE_VEC_ELT (OMP_FOR_COND (stmt), i);
20065 gcc_assert (COMPARISON_CLASS_P (cond));
20066 gcc_assert (TREE_OPERAND (cond, 0) == decl);
20067
20068 tree op0 = TREE_OPERAND (init, 1);
20069 if (!OMP_FOR_NON_RECTANGULAR (stmt)
20070 || TREE_CODE (op0) != TREE_VEC)
20071 TREE_OPERAND (init, 1) = c_fully_fold (op0, false, NULL);
20072 else
20073 {
20074 TREE_VEC_ELT (op0, 1)
20075 = c_fully_fold (TREE_VEC_ELT (op0, 1), false, NULL);
20076 TREE_VEC_ELT (op0, 2)
20077 = c_fully_fold (TREE_VEC_ELT (op0, 2), false, NULL);
20078 }
20079
20080 tree op1 = TREE_OPERAND (cond, 1);
20081 if (!OMP_FOR_NON_RECTANGULAR (stmt)
20082 || TREE_CODE (op1) != TREE_VEC)
20083 TREE_OPERAND (cond, 1) = c_fully_fold (op1, false, NULL);
20084 else
20085 {
20086 TREE_VEC_ELT (op1, 1)
20087 = c_fully_fold (TREE_VEC_ELT (op1, 1), false, NULL);
20088 TREE_VEC_ELT (op1, 2)
20089 = c_fully_fold (TREE_VEC_ELT (op1, 2), false, NULL);
20090 }
20091 }
20092
20093 if (cclauses != NULL
20094 && cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL)
20095 {
20096 tree *c;
20097 for (c = &cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; *c ; )
20098 if (OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_FIRSTPRIVATE
20099 && OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_LASTPRIVATE)
20100 c = &OMP_CLAUSE_CHAIN (*c);
20101 else
20102 {
20103 for (i = 0; i < count; i++)
20104 if (TREE_VEC_ELT (declv, i) == OMP_CLAUSE_DECL (*c))
20105 break;
20106 if (i == count)
20107 c = &OMP_CLAUSE_CHAIN (*c);
20108 else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE)
20109 {
20110 error_at (loc,
20111 "iteration variable %qD should not be firstprivate",
20112 OMP_CLAUSE_DECL (*c));
20113 *c = OMP_CLAUSE_CHAIN (*c);
20114 }
20115 else
20116 {
20117 /* Move lastprivate (decl) clause to OMP_FOR_CLAUSES. */
20118 tree l = *c;
20119 *c = OMP_CLAUSE_CHAIN (*c);
20120 if (code == OMP_SIMD)
20121 {
20122 OMP_CLAUSE_CHAIN (l)
20123 = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
20124 cclauses[C_OMP_CLAUSE_SPLIT_FOR] = l;
20125 }
20126 else
20127 {
20128 OMP_CLAUSE_CHAIN (l) = clauses;
20129 clauses = l;
20130 }
20131 }
20132 }
20133 }
20134 OMP_FOR_CLAUSES (stmt) = clauses;
20135 }
20136 ret = stmt;
20137 }
20138 pop_scopes:
20139 while (!for_block->is_empty ())
20140 {
20141 /* FIXME diagnostics: LOC below should be the actual location of
20142 this particular for block. We need to build a list of
20143 locations to go along with FOR_BLOCK. */
20144 stmt = c_end_compound_stmt (loc, for_block->pop (), true);
20145 add_stmt (stmt);
20146 }
20147 release_tree_vector (for_block);
20148 return ret;
20149 }
20150
20151 /* Helper function for OpenMP parsing, split clauses and call
20152 finish_omp_clauses on each of the set of clauses afterwards. */
20153
20154 static void
20155 omp_split_clauses (location_t loc, enum tree_code code,
20156 omp_clause_mask mask, tree clauses, tree *cclauses)
20157 {
20158 int i;
20159 c_omp_split_clauses (loc, code, mask, clauses, cclauses);
20160 for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
20161 if (cclauses[i])
20162 cclauses[i] = c_finish_omp_clauses (cclauses[i],
20163 i == C_OMP_CLAUSE_SPLIT_TARGET
20164 ? C_ORT_OMP_TARGET : C_ORT_OMP);
20165 }
20166
20167 /* OpenMP 5.0:
20168 #pragma omp loop loop-clause[optseq] new-line
20169 for-loop
20170
20171 LOC is the location of the #pragma token.
20172 */
20173
20174 #define OMP_LOOP_CLAUSE_MASK \
20175 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20176 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20177 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20178 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
20179 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
20180 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
20181
20182 static tree
20183 c_parser_omp_loop (location_t loc, c_parser *parser,
20184 char *p_name, omp_clause_mask mask, tree *cclauses,
20185 bool *if_p)
20186 {
20187 tree block, clauses, ret;
20188
20189 strcat (p_name, " loop");
20190 mask |= OMP_LOOP_CLAUSE_MASK;
20191
20192 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20193 if (cclauses)
20194 {
20195 omp_split_clauses (loc, OMP_LOOP, mask, clauses, cclauses);
20196 clauses = cclauses[C_OMP_CLAUSE_SPLIT_LOOP];
20197 }
20198
20199 block = c_begin_compound_stmt (true);
20200 ret = c_parser_omp_for_loop (loc, parser, OMP_LOOP, clauses, cclauses, if_p);
20201 block = c_end_compound_stmt (loc, block, true);
20202 add_stmt (block);
20203
20204 return ret;
20205 }
20206
20207 /* OpenMP 4.0:
20208 #pragma omp simd simd-clause[optseq] new-line
20209 for-loop
20210
20211 LOC is the location of the #pragma token.
20212 */
20213
20214 #define OMP_SIMD_CLAUSE_MASK \
20215 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
20216 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
20217 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
20218 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
20219 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20220 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20221 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20222 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
20223 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20224 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
20225 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
20226
20227 static tree
20228 c_parser_omp_simd (location_t loc, c_parser *parser,
20229 char *p_name, omp_clause_mask mask, tree *cclauses,
20230 bool *if_p)
20231 {
20232 tree block, clauses, ret;
20233
20234 strcat (p_name, " simd");
20235 mask |= OMP_SIMD_CLAUSE_MASK;
20236
20237 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20238 if (cclauses)
20239 {
20240 omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses);
20241 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
20242 }
20243
20244 block = c_begin_compound_stmt (true);
20245 ret = c_parser_omp_for_loop (loc, parser, OMP_SIMD, clauses, cclauses, if_p);
20246 block = c_end_compound_stmt (loc, block, true);
20247 add_stmt (block);
20248
20249 return ret;
20250 }
20251
20252 /* OpenMP 2.5:
20253 #pragma omp for for-clause[optseq] new-line
20254 for-loop
20255
20256 OpenMP 4.0:
20257 #pragma omp for simd for-simd-clause[optseq] new-line
20258 for-loop
20259
20260 LOC is the location of the #pragma token.
20261 */
20262
20263 #define OMP_FOR_CLAUSE_MASK \
20264 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20265 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20266 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20267 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
20268 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20269 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
20270 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
20271 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
20272 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
20273 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20274 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
20275
20276 static tree
20277 c_parser_omp_for (location_t loc, c_parser *parser,
20278 char *p_name, omp_clause_mask mask, tree *cclauses,
20279 bool *if_p)
20280 {
20281 tree block, clauses, ret;
20282
20283 strcat (p_name, " for");
20284 mask |= OMP_FOR_CLAUSE_MASK;
20285 /* parallel for{, simd} disallows nowait clause, but for
20286 target {teams distribute ,}parallel for{, simd} it should be accepted. */
20287 if (cclauses && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0)
20288 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
20289 /* Composite distribute parallel for{, simd} disallows ordered clause. */
20290 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
20291 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED);
20292
20293 if (c_parser_next_token_is (parser, CPP_NAME))
20294 {
20295 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20296
20297 if (strcmp (p, "simd") == 0)
20298 {
20299 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20300 if (cclauses == NULL)
20301 cclauses = cclauses_buf;
20302
20303 c_parser_consume_token (parser);
20304 if (!flag_openmp) /* flag_openmp_simd */
20305 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
20306 if_p);
20307 block = c_begin_compound_stmt (true);
20308 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
20309 block = c_end_compound_stmt (loc, block, true);
20310 if (ret == NULL_TREE)
20311 return ret;
20312 ret = make_node (OMP_FOR);
20313 TREE_TYPE (ret) = void_type_node;
20314 OMP_FOR_BODY (ret) = block;
20315 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
20316 SET_EXPR_LOCATION (ret, loc);
20317 add_stmt (ret);
20318 return ret;
20319 }
20320 }
20321 if (!flag_openmp) /* flag_openmp_simd */
20322 {
20323 c_parser_skip_to_pragma_eol (parser, false);
20324 return NULL_TREE;
20325 }
20326
20327 /* Composite distribute parallel for disallows linear clause. */
20328 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
20329 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR);
20330
20331 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20332 if (cclauses)
20333 {
20334 omp_split_clauses (loc, OMP_FOR, mask, clauses, cclauses);
20335 clauses = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
20336 }
20337
20338 block = c_begin_compound_stmt (true);
20339 ret = c_parser_omp_for_loop (loc, parser, OMP_FOR, clauses, cclauses, if_p);
20340 block = c_end_compound_stmt (loc, block, true);
20341 add_stmt (block);
20342
20343 return ret;
20344 }
20345
20346 static tree c_parser_omp_taskloop (location_t, c_parser *, char *,
20347 omp_clause_mask, tree *, bool *);
20348
20349 /* OpenMP 2.5:
20350 # pragma omp master new-line
20351 structured-block
20352
20353 LOC is the location of the #pragma token.
20354 */
20355
20356 static tree
20357 c_parser_omp_master (location_t loc, c_parser *parser,
20358 char *p_name, omp_clause_mask mask, tree *cclauses,
20359 bool *if_p)
20360 {
20361 tree block, clauses, ret;
20362
20363 strcat (p_name, " master");
20364
20365 if (c_parser_next_token_is (parser, CPP_NAME))
20366 {
20367 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20368
20369 if (strcmp (p, "taskloop") == 0)
20370 {
20371 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20372 if (cclauses == NULL)
20373 cclauses = cclauses_buf;
20374
20375 c_parser_consume_token (parser);
20376 if (!flag_openmp) /* flag_openmp_simd */
20377 return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
20378 if_p);
20379 block = c_begin_compound_stmt (true);
20380 ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
20381 if_p);
20382 block = c_end_compound_stmt (loc, block, true);
20383 if (ret == NULL_TREE)
20384 return ret;
20385 ret = c_finish_omp_master (loc, block);
20386 OMP_MASTER_COMBINED (ret) = 1;
20387 return ret;
20388 }
20389 }
20390 if (!flag_openmp) /* flag_openmp_simd */
20391 {
20392 c_parser_skip_to_pragma_eol (parser, false);
20393 return NULL_TREE;
20394 }
20395
20396 if (cclauses)
20397 {
20398 clauses = c_parser_omp_all_clauses (parser, mask, p_name, false);
20399 omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses);
20400 }
20401 else
20402 c_parser_skip_to_pragma_eol (parser);
20403
20404 return c_finish_omp_master (loc, c_parser_omp_structured_block (parser,
20405 if_p));
20406 }
20407
20408 /* OpenMP 5.1:
20409 # pragma omp masked masked-clauses new-line
20410 structured-block
20411
20412 LOC is the location of the #pragma token.
20413 */
20414
20415 #define OMP_MASKED_CLAUSE_MASK \
20416 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER)
20417
20418 static tree
20419 c_parser_omp_masked (location_t loc, c_parser *parser,
20420 char *p_name, omp_clause_mask mask, tree *cclauses,
20421 bool *if_p)
20422 {
20423 tree block, clauses, ret;
20424
20425 strcat (p_name, " masked");
20426 mask |= OMP_MASKED_CLAUSE_MASK;
20427
20428 if (c_parser_next_token_is (parser, CPP_NAME))
20429 {
20430 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20431
20432 if (strcmp (p, "taskloop") == 0)
20433 {
20434 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20435 if (cclauses == NULL)
20436 cclauses = cclauses_buf;
20437
20438 c_parser_consume_token (parser);
20439 if (!flag_openmp) /* flag_openmp_simd */
20440 return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
20441 if_p);
20442 block = c_begin_compound_stmt (true);
20443 ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
20444 if_p);
20445 block = c_end_compound_stmt (loc, block, true);
20446 if (ret == NULL_TREE)
20447 return ret;
20448 ret = c_finish_omp_masked (loc, block,
20449 cclauses[C_OMP_CLAUSE_SPLIT_MASKED]);
20450 OMP_MASKED_COMBINED (ret) = 1;
20451 return ret;
20452 }
20453 }
20454 if (!flag_openmp) /* flag_openmp_simd */
20455 {
20456 c_parser_skip_to_pragma_eol (parser, false);
20457 return NULL_TREE;
20458 }
20459
20460 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20461 if (cclauses)
20462 {
20463 omp_split_clauses (loc, OMP_MASKED, mask, clauses, cclauses);
20464 clauses = cclauses[C_OMP_CLAUSE_SPLIT_MASKED];
20465 }
20466
20467 return c_finish_omp_masked (loc, c_parser_omp_structured_block (parser,
20468 if_p),
20469 clauses);
20470 }
20471
20472 /* OpenMP 2.5:
20473 # pragma omp ordered new-line
20474 structured-block
20475
20476 OpenMP 4.5:
20477 # pragma omp ordered ordered-clauses new-line
20478 structured-block
20479
20480 # pragma omp ordered depend-clauses new-line
20481
20482 OpenMP 5.2
20483 # pragma omp ordered doacross-clauses new-line */
20484
20485 #define OMP_ORDERED_CLAUSE_MASK \
20486 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
20487 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
20488
20489 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \
20490 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20491 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DOACROSS))
20492
20493 static bool
20494 c_parser_omp_ordered (c_parser *parser, enum pragma_context context,
20495 bool *if_p)
20496 {
20497 location_t loc = c_parser_peek_token (parser)->location;
20498 c_parser_consume_pragma (parser);
20499
20500 if (context != pragma_stmt && context != pragma_compound)
20501 {
20502 c_parser_error (parser, "expected declaration specifiers");
20503 c_parser_skip_to_pragma_eol (parser, false);
20504 return false;
20505 }
20506
20507 if (c_parser_next_token_is (parser, CPP_NAME))
20508 {
20509 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20510
20511 if (!strcmp ("depend", p) || !strcmp ("doacross", p))
20512 {
20513 if (!flag_openmp) /* flag_openmp_simd */
20514 {
20515 c_parser_skip_to_pragma_eol (parser, false);
20516 return false;
20517 }
20518 if (context == pragma_stmt)
20519 {
20520 error_at (loc,
20521 "%<#pragma omp ordered%> with %qs clause may "
20522 "only be used in compound statements", p);
20523 c_parser_skip_to_pragma_eol (parser, false);
20524 return true;
20525 }
20526
20527 tree clauses
20528 = c_parser_omp_all_clauses (parser,
20529 OMP_ORDERED_DEPEND_CLAUSE_MASK,
20530 "#pragma omp ordered");
20531 c_finish_omp_ordered (loc, clauses, NULL_TREE);
20532 return false;
20533 }
20534 }
20535
20536 tree clauses = c_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK,
20537 "#pragma omp ordered");
20538
20539 if (!flag_openmp /* flag_openmp_simd */
20540 && omp_find_clause (clauses, OMP_CLAUSE_SIMD) == NULL_TREE)
20541 return false;
20542
20543 c_finish_omp_ordered (loc, clauses,
20544 c_parser_omp_structured_block (parser, if_p));
20545 return true;
20546 }
20547
20548 /* OpenMP 2.5:
20549
20550 section-scope:
20551 { section-sequence }
20552
20553 section-sequence:
20554 section-directive[opt] structured-block
20555 section-sequence section-directive structured-block
20556
20557 OpenMP 5.1 allows structured-block-sequence instead of structured-block.
20558
20559 SECTIONS_LOC is the location of the #pragma omp sections. */
20560
20561 static tree
20562 c_parser_omp_sections_scope (location_t sections_loc, c_parser *parser)
20563 {
20564 tree stmt, substmt;
20565 bool error_suppress = false;
20566 location_t loc;
20567
20568 loc = c_parser_peek_token (parser)->location;
20569 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
20570 {
20571 /* Avoid skipping until the end of the block. */
20572 parser->error = false;
20573 return NULL_TREE;
20574 }
20575
20576 stmt = push_stmt_list ();
20577
20578 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION)
20579 {
20580 substmt = c_parser_omp_structured_block_sequence (parser,
20581 PRAGMA_OMP_SECTION);
20582 substmt = build1 (OMP_SECTION, void_type_node, substmt);
20583 SET_EXPR_LOCATION (substmt, loc);
20584 add_stmt (substmt);
20585 }
20586
20587 while (1)
20588 {
20589 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
20590 break;
20591 if (c_parser_next_token_is (parser, CPP_EOF))
20592 break;
20593
20594 loc = c_parser_peek_token (parser)->location;
20595 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION)
20596 {
20597 c_parser_consume_pragma (parser);
20598 c_parser_skip_to_pragma_eol (parser);
20599 error_suppress = false;
20600 }
20601 else if (!error_suppress)
20602 {
20603 error_at (loc, "expected %<#pragma omp section%> or %<}%>");
20604 error_suppress = true;
20605 }
20606
20607 substmt = c_parser_omp_structured_block_sequence (parser,
20608 PRAGMA_OMP_SECTION);
20609 substmt = build1 (OMP_SECTION, void_type_node, substmt);
20610 SET_EXPR_LOCATION (substmt, loc);
20611 add_stmt (substmt);
20612 }
20613 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
20614 "expected %<#pragma omp section%> or %<}%>");
20615
20616 substmt = pop_stmt_list (stmt);
20617
20618 stmt = make_node (OMP_SECTIONS);
20619 SET_EXPR_LOCATION (stmt, sections_loc);
20620 TREE_TYPE (stmt) = void_type_node;
20621 OMP_SECTIONS_BODY (stmt) = substmt;
20622
20623 return add_stmt (stmt);
20624 }
20625
20626 /* OpenMP 2.5:
20627 # pragma omp sections sections-clause[optseq] newline
20628 sections-scope
20629
20630 LOC is the location of the #pragma token.
20631 */
20632
20633 #define OMP_SECTIONS_CLAUSE_MASK \
20634 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20635 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20636 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20637 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20638 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20639 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20640
20641 static tree
20642 c_parser_omp_sections (location_t loc, c_parser *parser,
20643 char *p_name, omp_clause_mask mask, tree *cclauses)
20644 {
20645 tree block, clauses, ret;
20646
20647 strcat (p_name, " sections");
20648 mask |= OMP_SECTIONS_CLAUSE_MASK;
20649 if (cclauses)
20650 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
20651
20652 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20653 if (cclauses)
20654 {
20655 omp_split_clauses (loc, OMP_SECTIONS, mask, clauses, cclauses);
20656 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS];
20657 }
20658
20659 block = c_begin_compound_stmt (true);
20660 ret = c_parser_omp_sections_scope (loc, parser);
20661 if (ret)
20662 OMP_SECTIONS_CLAUSES (ret) = clauses;
20663 block = c_end_compound_stmt (loc, block, true);
20664 add_stmt (block);
20665
20666 return ret;
20667 }
20668
20669 /* OpenMP 2.5:
20670 # pragma omp parallel parallel-clause[optseq] new-line
20671 structured-block
20672 # pragma omp parallel for parallel-for-clause[optseq] new-line
20673 structured-block
20674 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
20675 structured-block
20676
20677 OpenMP 4.0:
20678 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
20679 structured-block
20680
20681 LOC is the location of the #pragma token.
20682 */
20683
20684 #define OMP_PARALLEL_CLAUSE_MASK \
20685 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20686 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20687 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20688 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
20689 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20690 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
20691 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20692 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
20693 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20694 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
20695
20696 static tree
20697 c_parser_omp_parallel (location_t loc, c_parser *parser,
20698 char *p_name, omp_clause_mask mask, tree *cclauses,
20699 bool *if_p)
20700 {
20701 tree stmt, clauses, block;
20702
20703 strcat (p_name, " parallel");
20704 mask |= OMP_PARALLEL_CLAUSE_MASK;
20705 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
20706 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0
20707 && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
20708 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN);
20709
20710 if (c_parser_next_token_is_keyword (parser, RID_FOR))
20711 {
20712 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20713 if (cclauses == NULL)
20714 cclauses = cclauses_buf;
20715
20716 c_parser_consume_token (parser);
20717 if (!flag_openmp) /* flag_openmp_simd */
20718 return c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
20719 block = c_begin_omp_parallel ();
20720 tree ret = c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
20721 stmt
20722 = c_finish_omp_parallel (loc, cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20723 block);
20724 if (ret == NULL_TREE)
20725 return ret;
20726 OMP_PARALLEL_COMBINED (stmt) = 1;
20727 return stmt;
20728 }
20729 /* When combined with distribute, parallel has to be followed by for.
20730 #pragma omp target parallel is allowed though. */
20731 else if (cclauses
20732 && (mask & (OMP_CLAUSE_MASK_1
20733 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
20734 {
20735 error_at (loc, "expected %<for%> after %qs", p_name);
20736 c_parser_skip_to_pragma_eol (parser);
20737 return NULL_TREE;
20738 }
20739 else if (c_parser_next_token_is (parser, CPP_NAME))
20740 {
20741 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20742 if (cclauses == NULL && strcmp (p, "masked") == 0)
20743 {
20744 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20745 cclauses = cclauses_buf;
20746
20747 c_parser_consume_token (parser);
20748 if (!flag_openmp) /* flag_openmp_simd */
20749 return c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
20750 if_p);
20751 block = c_begin_omp_parallel ();
20752 tree ret = c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
20753 if_p);
20754 stmt = c_finish_omp_parallel (loc,
20755 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20756 block);
20757 if (ret == NULL)
20758 return ret;
20759 /* masked does have just filter clause, but during gimplification
20760 isn't represented by a gimplification omp context, so for
20761 #pragma omp parallel masked don't set OMP_PARALLEL_COMBINED,
20762 so that
20763 #pragma omp parallel masked
20764 #pragma omp taskloop simd lastprivate (x)
20765 isn't confused with
20766 #pragma omp parallel masked taskloop simd lastprivate (x) */
20767 if (OMP_MASKED_COMBINED (ret))
20768 OMP_PARALLEL_COMBINED (stmt) = 1;
20769 return stmt;
20770 }
20771 else if (cclauses == NULL && strcmp (p, "master") == 0)
20772 {
20773 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20774 cclauses = cclauses_buf;
20775
20776 c_parser_consume_token (parser);
20777 if (!flag_openmp) /* flag_openmp_simd */
20778 return c_parser_omp_master (loc, parser, p_name, mask, cclauses,
20779 if_p);
20780 block = c_begin_omp_parallel ();
20781 tree ret = c_parser_omp_master (loc, parser, p_name, mask, cclauses,
20782 if_p);
20783 stmt = c_finish_omp_parallel (loc,
20784 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20785 block);
20786 if (ret == NULL)
20787 return ret;
20788 /* master doesn't have any clauses and during gimplification
20789 isn't represented by a gimplification omp context, so for
20790 #pragma omp parallel master don't set OMP_PARALLEL_COMBINED,
20791 so that
20792 #pragma omp parallel master
20793 #pragma omp taskloop simd lastprivate (x)
20794 isn't confused with
20795 #pragma omp parallel master taskloop simd lastprivate (x) */
20796 if (OMP_MASTER_COMBINED (ret))
20797 OMP_PARALLEL_COMBINED (stmt) = 1;
20798 return stmt;
20799 }
20800 else if (strcmp (p, "loop") == 0)
20801 {
20802 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20803 if (cclauses == NULL)
20804 cclauses = cclauses_buf;
20805
20806 c_parser_consume_token (parser);
20807 if (!flag_openmp) /* flag_openmp_simd */
20808 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
20809 if_p);
20810 block = c_begin_omp_parallel ();
20811 tree ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
20812 if_p);
20813 stmt
20814 = c_finish_omp_parallel (loc,
20815 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20816 block);
20817 if (ret == NULL_TREE)
20818 return ret;
20819 OMP_PARALLEL_COMBINED (stmt) = 1;
20820 return stmt;
20821 }
20822 else if (!flag_openmp) /* flag_openmp_simd */
20823 {
20824 c_parser_skip_to_pragma_eol (parser, false);
20825 return NULL_TREE;
20826 }
20827 else if (cclauses == NULL && strcmp (p, "sections") == 0)
20828 {
20829 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20830 cclauses = cclauses_buf;
20831
20832 c_parser_consume_token (parser);
20833 block = c_begin_omp_parallel ();
20834 c_parser_omp_sections (loc, parser, p_name, mask, cclauses);
20835 stmt = c_finish_omp_parallel (loc,
20836 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20837 block);
20838 OMP_PARALLEL_COMBINED (stmt) = 1;
20839 return stmt;
20840 }
20841 }
20842 else if (!flag_openmp) /* flag_openmp_simd */
20843 {
20844 c_parser_skip_to_pragma_eol (parser, false);
20845 return NULL_TREE;
20846 }
20847
20848 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20849 if (cclauses)
20850 {
20851 omp_split_clauses (loc, OMP_PARALLEL, mask, clauses, cclauses);
20852 clauses = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
20853 }
20854
20855 block = c_begin_omp_parallel ();
20856 c_parser_statement (parser, if_p);
20857 stmt = c_finish_omp_parallel (loc, clauses, block);
20858
20859 return stmt;
20860 }
20861
20862 /* OpenMP 2.5:
20863 # pragma omp single single-clause[optseq] new-line
20864 structured-block
20865
20866 LOC is the location of the #pragma.
20867 */
20868
20869 #define OMP_SINGLE_CLAUSE_MASK \
20870 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20871 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20872 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
20873 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20874 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20875
20876 static tree
20877 c_parser_omp_single (location_t loc, c_parser *parser, bool *if_p)
20878 {
20879 tree stmt = make_node (OMP_SINGLE);
20880 SET_EXPR_LOCATION (stmt, loc);
20881 TREE_TYPE (stmt) = void_type_node;
20882
20883 OMP_SINGLE_CLAUSES (stmt)
20884 = c_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK,
20885 "#pragma omp single");
20886 OMP_SINGLE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
20887
20888 return add_stmt (stmt);
20889 }
20890
20891 /* OpenMP 5.1:
20892 # pragma omp scope scope-clause[optseq] new-line
20893 structured-block
20894
20895 LOC is the location of the #pragma.
20896 */
20897
20898 #define OMP_SCOPE_CLAUSE_MASK \
20899 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20900 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20901 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20902 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20903 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20904
20905 static tree
20906 c_parser_omp_scope (location_t loc, c_parser *parser, bool *if_p)
20907 {
20908 tree stmt = make_node (OMP_SCOPE);
20909 SET_EXPR_LOCATION (stmt, loc);
20910 TREE_TYPE (stmt) = void_type_node;
20911
20912 OMP_SCOPE_CLAUSES (stmt)
20913 = c_parser_omp_all_clauses (parser, OMP_SCOPE_CLAUSE_MASK,
20914 "#pragma omp scope");
20915 OMP_SCOPE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
20916
20917 return add_stmt (stmt);
20918 }
20919
20920 /* OpenMP 3.0:
20921 # pragma omp task task-clause[optseq] new-line
20922
20923 LOC is the location of the #pragma.
20924 */
20925
20926 #define OMP_TASK_CLAUSE_MASK \
20927 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20928 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
20929 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
20930 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20931 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20932 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20933 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
20934 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
20935 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20936 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
20937 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20938 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
20939 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH) \
20940 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_AFFINITY))
20941
20942 static tree
20943 c_parser_omp_task (location_t loc, c_parser *parser, bool *if_p)
20944 {
20945 tree clauses, block;
20946
20947 clauses = c_parser_omp_all_clauses (parser, OMP_TASK_CLAUSE_MASK,
20948 "#pragma omp task");
20949
20950 block = c_begin_omp_task ();
20951 c_parser_statement (parser, if_p);
20952 return c_finish_omp_task (loc, clauses, block);
20953 }
20954
20955 /* OpenMP 3.0:
20956 # pragma omp taskwait new-line
20957
20958 OpenMP 5.0:
20959 # pragma omp taskwait taskwait-clause[optseq] new-line
20960 */
20961
20962 #define OMP_TASKWAIT_CLAUSE_MASK \
20963 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20964 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20965
20966 static void
20967 c_parser_omp_taskwait (c_parser *parser)
20968 {
20969 location_t loc = c_parser_peek_token (parser)->location;
20970 c_parser_consume_pragma (parser);
20971
20972 tree clauses
20973 = c_parser_omp_all_clauses (parser, OMP_TASKWAIT_CLAUSE_MASK,
20974 "#pragma omp taskwait");
20975
20976 if (clauses)
20977 {
20978 tree stmt = make_node (OMP_TASK);
20979 TREE_TYPE (stmt) = void_node;
20980 OMP_TASK_CLAUSES (stmt) = clauses;
20981 OMP_TASK_BODY (stmt) = NULL_TREE;
20982 SET_EXPR_LOCATION (stmt, loc);
20983 add_stmt (stmt);
20984 }
20985 else
20986 c_finish_omp_taskwait (loc);
20987 }
20988
20989 /* OpenMP 3.1:
20990 # pragma omp taskyield new-line
20991 */
20992
20993 static void
20994 c_parser_omp_taskyield (c_parser *parser)
20995 {
20996 location_t loc = c_parser_peek_token (parser)->location;
20997 c_parser_consume_pragma (parser);
20998 c_parser_skip_to_pragma_eol (parser);
20999
21000 c_finish_omp_taskyield (loc);
21001 }
21002
21003 /* OpenMP 4.0:
21004 # pragma omp taskgroup new-line
21005
21006 OpenMP 5.0:
21007 # pragma omp taskgroup taskgroup-clause[optseq] new-line
21008 */
21009
21010 #define OMP_TASKGROUP_CLAUSE_MASK \
21011 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21012 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
21013
21014 static tree
21015 c_parser_omp_taskgroup (location_t loc, c_parser *parser, bool *if_p)
21016 {
21017 tree clauses = c_parser_omp_all_clauses (parser, OMP_TASKGROUP_CLAUSE_MASK,
21018 "#pragma omp taskgroup");
21019
21020 tree body = c_parser_omp_structured_block (parser, if_p);
21021 return c_finish_omp_taskgroup (loc, body, clauses);
21022 }
21023
21024 /* OpenMP 4.0:
21025 # pragma omp cancel cancel-clause[optseq] new-line
21026
21027 LOC is the location of the #pragma.
21028 */
21029
21030 #define OMP_CANCEL_CLAUSE_MASK \
21031 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
21032 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
21033 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
21034 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
21035 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
21036
21037 static void
21038 c_parser_omp_cancel (c_parser *parser)
21039 {
21040 location_t loc = c_parser_peek_token (parser)->location;
21041
21042 c_parser_consume_pragma (parser);
21043 tree clauses = c_parser_omp_all_clauses (parser, OMP_CANCEL_CLAUSE_MASK,
21044 "#pragma omp cancel");
21045
21046 c_finish_omp_cancel (loc, clauses);
21047 }
21048
21049 /* OpenMP 4.0:
21050 # pragma omp cancellation point cancelpt-clause[optseq] new-line
21051
21052 LOC is the location of the #pragma.
21053 */
21054
21055 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \
21056 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
21057 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
21058 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
21059 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
21060
21061 static bool
21062 c_parser_omp_cancellation_point (c_parser *parser, enum pragma_context context)
21063 {
21064 location_t loc = c_parser_peek_token (parser)->location;
21065 tree clauses;
21066 bool point_seen = false;
21067
21068 c_parser_consume_pragma (parser);
21069 if (c_parser_next_token_is (parser, CPP_NAME))
21070 {
21071 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21072 if (strcmp (p, "point") == 0)
21073 {
21074 c_parser_consume_token (parser);
21075 point_seen = true;
21076 }
21077 }
21078 if (!point_seen)
21079 {
21080 c_parser_error (parser, "expected %<point%>");
21081 c_parser_skip_to_pragma_eol (parser);
21082 return false;
21083 }
21084
21085 if (context != pragma_compound)
21086 {
21087 if (context == pragma_stmt)
21088 error_at (loc,
21089 "%<#pragma %s%> may only be used in compound statements",
21090 "omp cancellation point");
21091 else
21092 c_parser_error (parser, "expected declaration specifiers");
21093 c_parser_skip_to_pragma_eol (parser, false);
21094 return true;
21095 }
21096
21097 clauses
21098 = c_parser_omp_all_clauses (parser, OMP_CANCELLATION_POINT_CLAUSE_MASK,
21099 "#pragma omp cancellation point");
21100
21101 c_finish_omp_cancellation_point (loc, clauses);
21102 return true;
21103 }
21104
21105 /* OpenMP 4.0:
21106 #pragma omp distribute distribute-clause[optseq] new-line
21107 for-loop */
21108
21109 #define OMP_DISTRIBUTE_CLAUSE_MASK \
21110 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21111 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21112 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
21113 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
21114 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21115 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
21116 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
21117
21118 static tree
21119 c_parser_omp_distribute (location_t loc, c_parser *parser,
21120 char *p_name, omp_clause_mask mask, tree *cclauses,
21121 bool *if_p)
21122 {
21123 tree clauses, block, ret;
21124
21125 strcat (p_name, " distribute");
21126 mask |= OMP_DISTRIBUTE_CLAUSE_MASK;
21127
21128 if (c_parser_next_token_is (parser, CPP_NAME))
21129 {
21130 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21131 bool simd = false;
21132 bool parallel = false;
21133
21134 if (strcmp (p, "simd") == 0)
21135 simd = true;
21136 else
21137 parallel = strcmp (p, "parallel") == 0;
21138 if (parallel || simd)
21139 {
21140 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
21141 if (cclauses == NULL)
21142 cclauses = cclauses_buf;
21143 c_parser_consume_token (parser);
21144 if (!flag_openmp) /* flag_openmp_simd */
21145 {
21146 if (simd)
21147 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
21148 if_p);
21149 else
21150 return c_parser_omp_parallel (loc, parser, p_name, mask,
21151 cclauses, if_p);
21152 }
21153 block = c_begin_compound_stmt (true);
21154 if (simd)
21155 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
21156 if_p);
21157 else
21158 ret = c_parser_omp_parallel (loc, parser, p_name, mask, cclauses,
21159 if_p);
21160 block = c_end_compound_stmt (loc, block, true);
21161 if (ret == NULL)
21162 return ret;
21163 ret = make_node (OMP_DISTRIBUTE);
21164 TREE_TYPE (ret) = void_type_node;
21165 OMP_FOR_BODY (ret) = block;
21166 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
21167 SET_EXPR_LOCATION (ret, loc);
21168 add_stmt (ret);
21169 return ret;
21170 }
21171 }
21172 if (!flag_openmp) /* flag_openmp_simd */
21173 {
21174 c_parser_skip_to_pragma_eol (parser, false);
21175 return NULL_TREE;
21176 }
21177
21178 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
21179 if (cclauses)
21180 {
21181 omp_split_clauses (loc, OMP_DISTRIBUTE, mask, clauses, cclauses);
21182 clauses = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
21183 }
21184
21185 block = c_begin_compound_stmt (true);
21186 ret = c_parser_omp_for_loop (loc, parser, OMP_DISTRIBUTE, clauses, NULL,
21187 if_p);
21188 block = c_end_compound_stmt (loc, block, true);
21189 add_stmt (block);
21190
21191 return ret;
21192 }
21193
21194 /* OpenMP 4.0:
21195 # pragma omp teams teams-clause[optseq] new-line
21196 structured-block */
21197
21198 #define OMP_TEAMS_CLAUSE_MASK \
21199 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21200 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21201 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
21202 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
21203 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
21204 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
21205 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21206 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
21207
21208 static tree
21209 c_parser_omp_teams (location_t loc, c_parser *parser,
21210 char *p_name, omp_clause_mask mask, tree *cclauses,
21211 bool *if_p)
21212 {
21213 tree clauses, block, ret;
21214
21215 strcat (p_name, " teams");
21216 mask |= OMP_TEAMS_CLAUSE_MASK;
21217
21218 if (c_parser_next_token_is (parser, CPP_NAME))
21219 {
21220 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21221 if (strcmp (p, "distribute") == 0)
21222 {
21223 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
21224 if (cclauses == NULL)
21225 cclauses = cclauses_buf;
21226
21227 c_parser_consume_token (parser);
21228 if (!flag_openmp) /* flag_openmp_simd */
21229 return c_parser_omp_distribute (loc, parser, p_name, mask,
21230 cclauses, if_p);
21231 block = c_begin_omp_parallel ();
21232 ret = c_parser_omp_distribute (loc, parser, p_name, mask, cclauses,
21233 if_p);
21234 block = c_end_compound_stmt (loc, block, true);
21235 if (ret == NULL)
21236 return ret;
21237 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
21238 ret = make_node (OMP_TEAMS);
21239 TREE_TYPE (ret) = void_type_node;
21240 OMP_TEAMS_CLAUSES (ret) = clauses;
21241 OMP_TEAMS_BODY (ret) = block;
21242 OMP_TEAMS_COMBINED (ret) = 1;
21243 SET_EXPR_LOCATION (ret, loc);
21244 return add_stmt (ret);
21245 }
21246 else if (strcmp (p, "loop") == 0)
21247 {
21248 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
21249 if (cclauses == NULL)
21250 cclauses = cclauses_buf;
21251
21252 c_parser_consume_token (parser);
21253 if (!flag_openmp) /* flag_openmp_simd */
21254 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
21255 if_p);
21256 block = c_begin_omp_parallel ();
21257 ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses, if_p);
21258 block = c_end_compound_stmt (loc, block, true);
21259 if (ret == NULL)
21260 return ret;
21261 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
21262 ret = make_node (OMP_TEAMS);
21263 TREE_TYPE (ret) = void_type_node;
21264 OMP_TEAMS_CLAUSES (ret) = clauses;
21265 OMP_TEAMS_BODY (ret) = block;
21266 OMP_TEAMS_COMBINED (ret) = 1;
21267 SET_EXPR_LOCATION (ret, loc);
21268 return add_stmt (ret);
21269 }
21270 }
21271 if (!flag_openmp) /* flag_openmp_simd */
21272 {
21273 c_parser_skip_to_pragma_eol (parser, false);
21274 return NULL_TREE;
21275 }
21276
21277 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
21278 if (cclauses)
21279 {
21280 omp_split_clauses (loc, OMP_TEAMS, mask, clauses, cclauses);
21281 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
21282 }
21283
21284 tree stmt = make_node (OMP_TEAMS);
21285 TREE_TYPE (stmt) = void_type_node;
21286 OMP_TEAMS_CLAUSES (stmt) = clauses;
21287 block = c_begin_omp_parallel ();
21288 add_stmt (c_parser_omp_structured_block (parser, if_p));
21289 OMP_TEAMS_BODY (stmt) = c_end_compound_stmt (loc, block, true);
21290 SET_EXPR_LOCATION (stmt, loc);
21291
21292 return add_stmt (stmt);
21293 }
21294
21295 /* OpenMP 4.0:
21296 # pragma omp target data target-data-clause[optseq] new-line
21297 structured-block */
21298
21299 #define OMP_TARGET_DATA_CLAUSE_MASK \
21300 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21301 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21302 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21303 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
21304 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
21305
21306 static tree
21307 c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p)
21308 {
21309 if (flag_openmp)
21310 omp_requires_mask
21311 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
21312
21313 tree clauses
21314 = c_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
21315 "#pragma omp target data");
21316 c_omp_adjust_map_clauses (clauses, false);
21317 int map_seen = 0;
21318 for (tree *pc = &clauses; *pc;)
21319 {
21320 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
21321 switch (OMP_CLAUSE_MAP_KIND (*pc))
21322 {
21323 case GOMP_MAP_TO:
21324 case GOMP_MAP_ALWAYS_TO:
21325 case GOMP_MAP_FROM:
21326 case GOMP_MAP_ALWAYS_FROM:
21327 case GOMP_MAP_TOFROM:
21328 case GOMP_MAP_ALWAYS_TOFROM:
21329 case GOMP_MAP_ALLOC:
21330 map_seen = 3;
21331 break;
21332 case GOMP_MAP_FIRSTPRIVATE_POINTER:
21333 case GOMP_MAP_ALWAYS_POINTER:
21334 case GOMP_MAP_ATTACH_DETACH:
21335 break;
21336 default:
21337 map_seen |= 1;
21338 error_at (OMP_CLAUSE_LOCATION (*pc),
21339 "%<#pragma omp target data%> with map-type other "
21340 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
21341 "on %<map%> clause");
21342 *pc = OMP_CLAUSE_CHAIN (*pc);
21343 continue;
21344 }
21345 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
21346 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
21347 map_seen = 3;
21348 pc = &OMP_CLAUSE_CHAIN (*pc);
21349 }
21350
21351 if (map_seen != 3)
21352 {
21353 if (map_seen == 0)
21354 error_at (loc,
21355 "%<#pragma omp target data%> must contain at least "
21356 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
21357 "clause");
21358 return NULL_TREE;
21359 }
21360
21361 tree stmt = make_node (OMP_TARGET_DATA);
21362 TREE_TYPE (stmt) = void_type_node;
21363 OMP_TARGET_DATA_CLAUSES (stmt) = clauses;
21364 keep_next_level ();
21365 tree block = c_begin_compound_stmt (true);
21366 add_stmt (c_parser_omp_structured_block (parser, if_p));
21367 OMP_TARGET_DATA_BODY (stmt) = c_end_compound_stmt (loc, block, true);
21368
21369 SET_EXPR_LOCATION (stmt, loc);
21370 return add_stmt (stmt);
21371 }
21372
21373 /* OpenMP 4.0:
21374 # pragma omp target update target-update-clause[optseq] new-line */
21375
21376 #define OMP_TARGET_UPDATE_CLAUSE_MASK \
21377 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
21378 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
21379 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21380 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21381 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21382 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21383
21384 static bool
21385 c_parser_omp_target_update (location_t loc, c_parser *parser,
21386 enum pragma_context context)
21387 {
21388 if (context == pragma_stmt)
21389 {
21390 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
21391 "omp target update");
21392 c_parser_skip_to_pragma_eol (parser, false);
21393 return true;
21394 }
21395
21396 tree clauses
21397 = c_parser_omp_all_clauses (parser, OMP_TARGET_UPDATE_CLAUSE_MASK,
21398 "#pragma omp target update");
21399 if (omp_find_clause (clauses, OMP_CLAUSE_TO) == NULL_TREE
21400 && omp_find_clause (clauses, OMP_CLAUSE_FROM) == NULL_TREE)
21401 {
21402 error_at (loc,
21403 "%<#pragma omp target update%> must contain at least one "
21404 "%<from%> or %<to%> clauses");
21405 return false;
21406 }
21407
21408 if (flag_openmp)
21409 omp_requires_mask
21410 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
21411
21412 tree stmt = make_node (OMP_TARGET_UPDATE);
21413 TREE_TYPE (stmt) = void_type_node;
21414 OMP_TARGET_UPDATE_CLAUSES (stmt) = clauses;
21415 SET_EXPR_LOCATION (stmt, loc);
21416 add_stmt (stmt);
21417 return false;
21418 }
21419
21420 /* OpenMP 4.5:
21421 # pragma omp target enter data target-data-clause[optseq] new-line */
21422
21423 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
21424 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21425 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21426 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21427 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21428 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21429
21430 static bool
21431 c_parser_omp_target_enter_data (location_t loc, c_parser *parser,
21432 enum pragma_context context)
21433 {
21434 bool data_seen = false;
21435 if (c_parser_next_token_is (parser, CPP_NAME))
21436 {
21437 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21438 if (strcmp (p, "data") == 0)
21439 {
21440 c_parser_consume_token (parser);
21441 data_seen = true;
21442 }
21443 }
21444 if (!data_seen)
21445 {
21446 c_parser_error (parser, "expected %<data%>");
21447 c_parser_skip_to_pragma_eol (parser);
21448 return false;
21449 }
21450
21451 if (context == pragma_stmt)
21452 {
21453 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
21454 "omp target enter data");
21455 c_parser_skip_to_pragma_eol (parser, false);
21456 return true;
21457 }
21458
21459 if (flag_openmp)
21460 omp_requires_mask
21461 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
21462
21463 tree clauses
21464 = c_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK,
21465 "#pragma omp target enter data");
21466 c_omp_adjust_map_clauses (clauses, false);
21467 int map_seen = 0;
21468 for (tree *pc = &clauses; *pc;)
21469 {
21470 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
21471 switch (OMP_CLAUSE_MAP_KIND (*pc))
21472 {
21473 case GOMP_MAP_TO:
21474 case GOMP_MAP_ALWAYS_TO:
21475 case GOMP_MAP_ALLOC:
21476 map_seen = 3;
21477 break;
21478 case GOMP_MAP_TOFROM:
21479 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_TO);
21480 map_seen = 3;
21481 break;
21482 case GOMP_MAP_ALWAYS_TOFROM:
21483 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_TO);
21484 map_seen = 3;
21485 break;
21486 case GOMP_MAP_FIRSTPRIVATE_POINTER:
21487 case GOMP_MAP_ALWAYS_POINTER:
21488 case GOMP_MAP_ATTACH_DETACH:
21489 break;
21490 default:
21491 map_seen |= 1;
21492 error_at (OMP_CLAUSE_LOCATION (*pc),
21493 "%<#pragma omp target enter data%> with map-type other "
21494 "than %<to%>, %<tofrom%> or %<alloc%> on %<map%> clause");
21495 *pc = OMP_CLAUSE_CHAIN (*pc);
21496 continue;
21497 }
21498 pc = &OMP_CLAUSE_CHAIN (*pc);
21499 }
21500
21501 if (map_seen != 3)
21502 {
21503 if (map_seen == 0)
21504 error_at (loc,
21505 "%<#pragma omp target enter data%> must contain at least "
21506 "one %<map%> clause");
21507 return true;
21508 }
21509
21510 tree stmt = make_node (OMP_TARGET_ENTER_DATA);
21511 TREE_TYPE (stmt) = void_type_node;
21512 OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses;
21513 SET_EXPR_LOCATION (stmt, loc);
21514 add_stmt (stmt);
21515 return true;
21516 }
21517
21518 /* OpenMP 4.5:
21519 # pragma omp target exit data target-data-clause[optseq] new-line */
21520
21521 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
21522 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21523 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21524 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21525 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21526 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
21527
21528 static bool
21529 c_parser_omp_target_exit_data (location_t loc, c_parser *parser,
21530 enum pragma_context context)
21531 {
21532 bool data_seen = false;
21533 if (c_parser_next_token_is (parser, CPP_NAME))
21534 {
21535 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21536 if (strcmp (p, "data") == 0)
21537 {
21538 c_parser_consume_token (parser);
21539 data_seen = true;
21540 }
21541 }
21542 if (!data_seen)
21543 {
21544 c_parser_error (parser, "expected %<data%>");
21545 c_parser_skip_to_pragma_eol (parser);
21546 return false;
21547 }
21548
21549 if (context == pragma_stmt)
21550 {
21551 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
21552 "omp target exit data");
21553 c_parser_skip_to_pragma_eol (parser, false);
21554 return true;
21555 }
21556
21557 if (flag_openmp)
21558 omp_requires_mask
21559 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
21560
21561 tree clauses
21562 = c_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK,
21563 "#pragma omp target exit data");
21564 c_omp_adjust_map_clauses (clauses, false);
21565 int map_seen = 0;
21566 for (tree *pc = &clauses; *pc;)
21567 {
21568 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
21569 switch (OMP_CLAUSE_MAP_KIND (*pc))
21570 {
21571 case GOMP_MAP_FROM:
21572 case GOMP_MAP_ALWAYS_FROM:
21573 case GOMP_MAP_RELEASE:
21574 case GOMP_MAP_DELETE:
21575 map_seen = 3;
21576 break;
21577 case GOMP_MAP_TOFROM:
21578 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_FROM);
21579 map_seen = 3;
21580 break;
21581 case GOMP_MAP_ALWAYS_TOFROM:
21582 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_FROM);
21583 map_seen = 3;
21584 break;
21585 case GOMP_MAP_FIRSTPRIVATE_POINTER:
21586 case GOMP_MAP_ALWAYS_POINTER:
21587 case GOMP_MAP_ATTACH_DETACH:
21588 break;
21589 default:
21590 map_seen |= 1;
21591 error_at (OMP_CLAUSE_LOCATION (*pc),
21592 "%<#pragma omp target exit data%> with map-type other "
21593 "than %<from%>, %<tofrom%>, %<release%> or %<delete%> "
21594 "on %<map%> clause");
21595 *pc = OMP_CLAUSE_CHAIN (*pc);
21596 continue;
21597 }
21598 pc = &OMP_CLAUSE_CHAIN (*pc);
21599 }
21600
21601 if (map_seen != 3)
21602 {
21603 if (map_seen == 0)
21604 error_at (loc,
21605 "%<#pragma omp target exit data%> must contain at least one "
21606 "%<map%> clause");
21607 return true;
21608 }
21609
21610 tree stmt = make_node (OMP_TARGET_EXIT_DATA);
21611 TREE_TYPE (stmt) = void_type_node;
21612 OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses;
21613 SET_EXPR_LOCATION (stmt, loc);
21614 add_stmt (stmt);
21615 return true;
21616 }
21617
21618 /* OpenMP 4.0:
21619 # pragma omp target target-clause[optseq] new-line
21620 structured-block */
21621
21622 #define OMP_TARGET_CLAUSE_MASK \
21623 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21624 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21625 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21626 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21627 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
21628 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21629 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21630 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21631 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
21632 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
21633 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
21634 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)\
21635 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR))
21636
21637 static bool
21638 c_parser_omp_target (c_parser *parser, enum pragma_context context, bool *if_p)
21639 {
21640 location_t loc = c_parser_peek_token (parser)->location;
21641 c_parser_consume_pragma (parser);
21642 tree *pc = NULL, stmt, block;
21643
21644 if (context != pragma_stmt && context != pragma_compound)
21645 {
21646 c_parser_error (parser, "expected declaration specifiers");
21647 c_parser_skip_to_pragma_eol (parser);
21648 return false;
21649 }
21650
21651 if (flag_openmp)
21652 omp_requires_mask
21653 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
21654
21655 if (c_parser_next_token_is (parser, CPP_NAME))
21656 {
21657 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21658 enum tree_code ccode = ERROR_MARK;
21659
21660 if (strcmp (p, "teams") == 0)
21661 ccode = OMP_TEAMS;
21662 else if (strcmp (p, "parallel") == 0)
21663 ccode = OMP_PARALLEL;
21664 else if (strcmp (p, "simd") == 0)
21665 ccode = OMP_SIMD;
21666 if (ccode != ERROR_MARK)
21667 {
21668 tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT];
21669 char p_name[sizeof ("#pragma omp target teams distribute "
21670 "parallel for simd")];
21671
21672 c_parser_consume_token (parser);
21673 strcpy (p_name, "#pragma omp target");
21674 if (!flag_openmp) /* flag_openmp_simd */
21675 {
21676 tree stmt;
21677 switch (ccode)
21678 {
21679 case OMP_TEAMS:
21680 stmt = c_parser_omp_teams (loc, parser, p_name,
21681 OMP_TARGET_CLAUSE_MASK,
21682 cclauses, if_p);
21683 break;
21684 case OMP_PARALLEL:
21685 stmt = c_parser_omp_parallel (loc, parser, p_name,
21686 OMP_TARGET_CLAUSE_MASK,
21687 cclauses, if_p);
21688 break;
21689 case OMP_SIMD:
21690 stmt = c_parser_omp_simd (loc, parser, p_name,
21691 OMP_TARGET_CLAUSE_MASK,
21692 cclauses, if_p);
21693 break;
21694 default:
21695 gcc_unreachable ();
21696 }
21697 return stmt != NULL_TREE;
21698 }
21699 keep_next_level ();
21700 tree block = c_begin_compound_stmt (true), ret;
21701 switch (ccode)
21702 {
21703 case OMP_TEAMS:
21704 ret = c_parser_omp_teams (loc, parser, p_name,
21705 OMP_TARGET_CLAUSE_MASK, cclauses,
21706 if_p);
21707 break;
21708 case OMP_PARALLEL:
21709 ret = c_parser_omp_parallel (loc, parser, p_name,
21710 OMP_TARGET_CLAUSE_MASK, cclauses,
21711 if_p);
21712 break;
21713 case OMP_SIMD:
21714 ret = c_parser_omp_simd (loc, parser, p_name,
21715 OMP_TARGET_CLAUSE_MASK, cclauses,
21716 if_p);
21717 break;
21718 default:
21719 gcc_unreachable ();
21720 }
21721 block = c_end_compound_stmt (loc, block, true);
21722 if (ret == NULL_TREE)
21723 return false;
21724 if (ccode == OMP_TEAMS)
21725 /* For combined target teams, ensure the num_teams and
21726 thread_limit clause expressions are evaluated on the host,
21727 before entering the target construct. */
21728 for (tree c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
21729 c; c = OMP_CLAUSE_CHAIN (c))
21730 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
21731 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
21732 for (int i = 0;
21733 i <= (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS); ++i)
21734 if (OMP_CLAUSE_OPERAND (c, i)
21735 && TREE_CODE (OMP_CLAUSE_OPERAND (c, i)) != INTEGER_CST)
21736 {
21737 tree expr = OMP_CLAUSE_OPERAND (c, i);
21738 tree tmp = create_tmp_var_raw (TREE_TYPE (expr));
21739 expr = build4 (TARGET_EXPR, TREE_TYPE (expr), tmp,
21740 expr, NULL_TREE, NULL_TREE);
21741 add_stmt (expr);
21742 OMP_CLAUSE_OPERAND (c, i) = expr;
21743 tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
21744 OMP_CLAUSE_FIRSTPRIVATE);
21745 OMP_CLAUSE_DECL (tc) = tmp;
21746 OMP_CLAUSE_CHAIN (tc)
21747 = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
21748 cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc;
21749 }
21750 tree stmt = make_node (OMP_TARGET);
21751 TREE_TYPE (stmt) = void_type_node;
21752 OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
21753 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
21754 OMP_TARGET_BODY (stmt) = block;
21755 OMP_TARGET_COMBINED (stmt) = 1;
21756 SET_EXPR_LOCATION (stmt, loc);
21757 add_stmt (stmt);
21758 pc = &OMP_TARGET_CLAUSES (stmt);
21759 goto check_clauses;
21760 }
21761 else if (!flag_openmp) /* flag_openmp_simd */
21762 {
21763 c_parser_skip_to_pragma_eol (parser, false);
21764 return false;
21765 }
21766 else if (strcmp (p, "data") == 0)
21767 {
21768 c_parser_consume_token (parser);
21769 c_parser_omp_target_data (loc, parser, if_p);
21770 return true;
21771 }
21772 else if (strcmp (p, "enter") == 0)
21773 {
21774 c_parser_consume_token (parser);
21775 return c_parser_omp_target_enter_data (loc, parser, context);
21776 }
21777 else if (strcmp (p, "exit") == 0)
21778 {
21779 c_parser_consume_token (parser);
21780 return c_parser_omp_target_exit_data (loc, parser, context);
21781 }
21782 else if (strcmp (p, "update") == 0)
21783 {
21784 c_parser_consume_token (parser);
21785 return c_parser_omp_target_update (loc, parser, context);
21786 }
21787 }
21788 if (!flag_openmp) /* flag_openmp_simd */
21789 {
21790 c_parser_skip_to_pragma_eol (parser, false);
21791 return false;
21792 }
21793
21794 stmt = make_node (OMP_TARGET);
21795 TREE_TYPE (stmt) = void_type_node;
21796
21797 OMP_TARGET_CLAUSES (stmt)
21798 = c_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK,
21799 "#pragma omp target", false);
21800 for (tree c = OMP_TARGET_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c))
21801 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION)
21802 {
21803 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
21804 OMP_CLAUSE_DECL (nc) = OMP_CLAUSE_DECL (c);
21805 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_ALWAYS_TOFROM);
21806 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
21807 OMP_CLAUSE_CHAIN (c) = nc;
21808 }
21809 OMP_TARGET_CLAUSES (stmt)
21810 = c_finish_omp_clauses (OMP_TARGET_CLAUSES (stmt), C_ORT_OMP_TARGET);
21811 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
21812
21813 pc = &OMP_TARGET_CLAUSES (stmt);
21814 keep_next_level ();
21815 block = c_begin_compound_stmt (true);
21816 add_stmt (c_parser_omp_structured_block (parser, if_p));
21817 OMP_TARGET_BODY (stmt) = c_end_compound_stmt (loc, block, true);
21818
21819 SET_EXPR_LOCATION (stmt, loc);
21820 add_stmt (stmt);
21821
21822 check_clauses:
21823 while (*pc)
21824 {
21825 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
21826 switch (OMP_CLAUSE_MAP_KIND (*pc))
21827 {
21828 case GOMP_MAP_TO:
21829 case GOMP_MAP_ALWAYS_TO:
21830 case GOMP_MAP_FROM:
21831 case GOMP_MAP_ALWAYS_FROM:
21832 case GOMP_MAP_TOFROM:
21833 case GOMP_MAP_ALWAYS_TOFROM:
21834 case GOMP_MAP_ALLOC:
21835 case GOMP_MAP_FIRSTPRIVATE_POINTER:
21836 case GOMP_MAP_ALWAYS_POINTER:
21837 case GOMP_MAP_ATTACH_DETACH:
21838 break;
21839 default:
21840 error_at (OMP_CLAUSE_LOCATION (*pc),
21841 "%<#pragma omp target%> with map-type other "
21842 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
21843 "on %<map%> clause");
21844 *pc = OMP_CLAUSE_CHAIN (*pc);
21845 continue;
21846 }
21847 pc = &OMP_CLAUSE_CHAIN (*pc);
21848 }
21849 cfun->has_omp_target = true;
21850 return true;
21851 }
21852
21853 /* OpenMP 4.0:
21854 # pragma omp declare simd declare-simd-clauses[optseq] new-line
21855
21856 OpenMP 5.0:
21857 # pragma omp declare variant (identifier) match(context-selector) new-line
21858 */
21859
21860 #define OMP_DECLARE_SIMD_CLAUSE_MASK \
21861 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
21862 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
21863 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
21864 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
21865 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
21866 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
21867
21868 static void
21869 c_parser_omp_declare_simd (c_parser *parser, enum pragma_context context)
21870 {
21871 c_token *token = c_parser_peek_token (parser);
21872 gcc_assert (token->type == CPP_NAME);
21873 tree kind = token->value;
21874 gcc_assert (strcmp (IDENTIFIER_POINTER (kind), "simd") == 0
21875 || strcmp (IDENTIFIER_POINTER (kind), "variant") == 0);
21876
21877 auto_vec<c_token> clauses;
21878 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
21879 {
21880 c_token *token = c_parser_peek_token (parser);
21881 if (token->type == CPP_EOF)
21882 {
21883 c_parser_skip_to_pragma_eol (parser);
21884 return;
21885 }
21886 clauses.safe_push (*token);
21887 c_parser_consume_token (parser);
21888 }
21889 clauses.safe_push (*c_parser_peek_token (parser));
21890 c_parser_skip_to_pragma_eol (parser);
21891
21892 while (c_parser_next_token_is (parser, CPP_PRAGMA))
21893 {
21894 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_DECLARE
21895 || c_parser_peek_2nd_token (parser)->type != CPP_NAME
21896 || c_parser_peek_2nd_token (parser)->value != kind)
21897 {
21898 error ("%<#pragma omp declare %s%> must be followed by "
21899 "function declaration or definition or another "
21900 "%<#pragma omp declare %s%>",
21901 IDENTIFIER_POINTER (kind), IDENTIFIER_POINTER (kind));
21902 return;
21903 }
21904 c_parser_consume_pragma (parser);
21905 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
21906 {
21907 c_token *token = c_parser_peek_token (parser);
21908 if (token->type == CPP_EOF)
21909 {
21910 c_parser_skip_to_pragma_eol (parser);
21911 return;
21912 }
21913 clauses.safe_push (*token);
21914 c_parser_consume_token (parser);
21915 }
21916 clauses.safe_push (*c_parser_peek_token (parser));
21917 c_parser_skip_to_pragma_eol (parser);
21918 }
21919
21920 /* Make sure nothing tries to read past the end of the tokens. */
21921 c_token eof_token;
21922 memset (&eof_token, 0, sizeof (eof_token));
21923 eof_token.type = CPP_EOF;
21924 clauses.safe_push (eof_token);
21925 clauses.safe_push (eof_token);
21926
21927 switch (context)
21928 {
21929 case pragma_external:
21930 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21931 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
21932 {
21933 int ext = disable_extension_diagnostics ();
21934 do
21935 c_parser_consume_token (parser);
21936 while (c_parser_next_token_is (parser, CPP_KEYWORD)
21937 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
21938 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
21939 NULL, &clauses);
21940 restore_extension_diagnostics (ext);
21941 }
21942 else
21943 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
21944 NULL, &clauses);
21945 break;
21946 case pragma_struct:
21947 case pragma_param:
21948 case pragma_stmt:
21949 error ("%<#pragma omp declare %s%> must be followed by "
21950 "function declaration or definition",
21951 IDENTIFIER_POINTER (kind));
21952 break;
21953 case pragma_compound:
21954 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21955 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
21956 {
21957 int ext = disable_extension_diagnostics ();
21958 do
21959 c_parser_consume_token (parser);
21960 while (c_parser_next_token_is (parser, CPP_KEYWORD)
21961 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
21962 if (c_parser_next_tokens_start_declaration (parser))
21963 {
21964 c_parser_declaration_or_fndef (parser, true, true, true, true,
21965 true, NULL, &clauses);
21966 restore_extension_diagnostics (ext);
21967 break;
21968 }
21969 restore_extension_diagnostics (ext);
21970 }
21971 else if (c_parser_next_tokens_start_declaration (parser))
21972 {
21973 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
21974 NULL, &clauses);
21975 break;
21976 }
21977 error ("%<#pragma omp declare %s%> must be followed by "
21978 "function declaration or definition",
21979 IDENTIFIER_POINTER (kind));
21980 break;
21981 default:
21982 gcc_unreachable ();
21983 }
21984 }
21985
21986 static const char *const omp_construct_selectors[] = {
21987 "simd", "target", "teams", "parallel", "for", NULL };
21988 static const char *const omp_device_selectors[] = {
21989 "kind", "isa", "arch", NULL };
21990 static const char *const omp_implementation_selectors[] = {
21991 "vendor", "extension", "atomic_default_mem_order", "unified_address",
21992 "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL };
21993 static const char *const omp_user_selectors[] = {
21994 "condition", NULL };
21995
21996 /* OpenMP 5.0:
21997
21998 trait-selector:
21999 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
22000
22001 trait-score:
22002 score(score-expression) */
22003
22004 static tree
22005 c_parser_omp_context_selector (c_parser *parser, tree set, tree parms)
22006 {
22007 tree ret = NULL_TREE;
22008 do
22009 {
22010 tree selector;
22011 if (c_parser_next_token_is (parser, CPP_KEYWORD)
22012 || c_parser_next_token_is (parser, CPP_NAME))
22013 selector = c_parser_peek_token (parser)->value;
22014 else
22015 {
22016 c_parser_error (parser, "expected trait selector name");
22017 return error_mark_node;
22018 }
22019
22020 tree properties = NULL_TREE;
22021 const char *const *selectors = NULL;
22022 bool allow_score = true;
22023 bool allow_user = false;
22024 int property_limit = 0;
22025 enum { CTX_PROPERTY_NONE, CTX_PROPERTY_USER, CTX_PROPERTY_NAME_LIST,
22026 CTX_PROPERTY_ID, CTX_PROPERTY_EXPR,
22027 CTX_PROPERTY_SIMD } property_kind = CTX_PROPERTY_NONE;
22028 switch (IDENTIFIER_POINTER (set)[0])
22029 {
22030 case 'c': /* construct */
22031 selectors = omp_construct_selectors;
22032 allow_score = false;
22033 property_limit = 1;
22034 property_kind = CTX_PROPERTY_SIMD;
22035 break;
22036 case 'd': /* device */
22037 selectors = omp_device_selectors;
22038 allow_score = false;
22039 allow_user = true;
22040 property_limit = 3;
22041 property_kind = CTX_PROPERTY_NAME_LIST;
22042 break;
22043 case 'i': /* implementation */
22044 selectors = omp_implementation_selectors;
22045 allow_user = true;
22046 property_limit = 3;
22047 property_kind = CTX_PROPERTY_NAME_LIST;
22048 break;
22049 case 'u': /* user */
22050 selectors = omp_user_selectors;
22051 property_limit = 1;
22052 property_kind = CTX_PROPERTY_EXPR;
22053 break;
22054 default:
22055 gcc_unreachable ();
22056 }
22057 for (int i = 0; ; i++)
22058 {
22059 if (selectors[i] == NULL)
22060 {
22061 if (allow_user)
22062 {
22063 property_kind = CTX_PROPERTY_USER;
22064 break;
22065 }
22066 else
22067 {
22068 error_at (c_parser_peek_token (parser)->location,
22069 "selector %qs not allowed for context selector "
22070 "set %qs", IDENTIFIER_POINTER (selector),
22071 IDENTIFIER_POINTER (set));
22072 c_parser_consume_token (parser);
22073 return error_mark_node;
22074 }
22075 }
22076 if (i == property_limit)
22077 property_kind = CTX_PROPERTY_NONE;
22078 if (strcmp (selectors[i], IDENTIFIER_POINTER (selector)) == 0)
22079 break;
22080 }
22081 if (property_kind == CTX_PROPERTY_NAME_LIST
22082 && IDENTIFIER_POINTER (set)[0] == 'i'
22083 && strcmp (IDENTIFIER_POINTER (selector),
22084 "atomic_default_mem_order") == 0)
22085 property_kind = CTX_PROPERTY_ID;
22086
22087 c_parser_consume_token (parser);
22088
22089 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
22090 {
22091 if (property_kind == CTX_PROPERTY_NONE)
22092 {
22093 error_at (c_parser_peek_token (parser)->location,
22094 "selector %qs does not accept any properties",
22095 IDENTIFIER_POINTER (selector));
22096 return error_mark_node;
22097 }
22098
22099 matching_parens parens;
22100 parens.require_open (parser);
22101
22102 c_token *token = c_parser_peek_token (parser);
22103 if (allow_score
22104 && c_parser_next_token_is (parser, CPP_NAME)
22105 && strcmp (IDENTIFIER_POINTER (token->value), "score") == 0
22106 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
22107 {
22108 c_parser_consume_token (parser);
22109
22110 matching_parens parens2;
22111 parens2.require_open (parser);
22112 tree score = c_parser_expr_no_commas (parser, NULL).value;
22113 parens2.skip_until_found_close (parser);
22114 c_parser_require (parser, CPP_COLON, "expected %<:%>");
22115 if (score != error_mark_node)
22116 {
22117 mark_exp_read (score);
22118 score = c_fully_fold (score, false, NULL);
22119 if (!INTEGRAL_TYPE_P (TREE_TYPE (score))
22120 || TREE_CODE (score) != INTEGER_CST)
22121 error_at (token->location, "score argument must be "
22122 "constant integer expression");
22123 else if (tree_int_cst_sgn (score) < 0)
22124 error_at (token->location, "score argument must be "
22125 "non-negative");
22126 else
22127 properties = tree_cons (get_identifier (" score"),
22128 score, properties);
22129 }
22130 token = c_parser_peek_token (parser);
22131 }
22132
22133 switch (property_kind)
22134 {
22135 tree t;
22136 case CTX_PROPERTY_USER:
22137 do
22138 {
22139 t = c_parser_expr_no_commas (parser, NULL).value;
22140 if (TREE_CODE (t) == STRING_CST)
22141 properties = tree_cons (NULL_TREE, t, properties);
22142 else if (t != error_mark_node)
22143 {
22144 mark_exp_read (t);
22145 t = c_fully_fold (t, false, NULL);
22146 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
22147 || !tree_fits_shwi_p (t))
22148 error_at (token->location, "property must be "
22149 "constant integer expression or string "
22150 "literal");
22151 else
22152 properties = tree_cons (NULL_TREE, t, properties);
22153 }
22154 else
22155 return error_mark_node;
22156
22157 if (c_parser_next_token_is (parser, CPP_COMMA))
22158 c_parser_consume_token (parser);
22159 else
22160 break;
22161 }
22162 while (1);
22163 break;
22164 case CTX_PROPERTY_ID:
22165 if (c_parser_next_token_is (parser, CPP_KEYWORD)
22166 || c_parser_next_token_is (parser, CPP_NAME))
22167 {
22168 tree prop = c_parser_peek_token (parser)->value;
22169 c_parser_consume_token (parser);
22170 properties = tree_cons (prop, NULL_TREE, properties);
22171 }
22172 else
22173 {
22174 c_parser_error (parser, "expected identifier");
22175 return error_mark_node;
22176 }
22177 break;
22178 case CTX_PROPERTY_NAME_LIST:
22179 do
22180 {
22181 tree prop = NULL_TREE, value = NULL_TREE;
22182 if (c_parser_next_token_is (parser, CPP_KEYWORD)
22183 || c_parser_next_token_is (parser, CPP_NAME))
22184 {
22185 prop = c_parser_peek_token (parser)->value;
22186 c_parser_consume_token (parser);
22187 }
22188 else if (c_parser_next_token_is (parser, CPP_STRING))
22189 value = c_parser_string_literal (parser, false,
22190 false).value;
22191 else
22192 {
22193 c_parser_error (parser, "expected identifier or "
22194 "string literal");
22195 return error_mark_node;
22196 }
22197
22198 properties = tree_cons (prop, value, properties);
22199
22200 if (c_parser_next_token_is (parser, CPP_COMMA))
22201 c_parser_consume_token (parser);
22202 else
22203 break;
22204 }
22205 while (1);
22206 break;
22207 case CTX_PROPERTY_EXPR:
22208 t = c_parser_expr_no_commas (parser, NULL).value;
22209 if (t != error_mark_node)
22210 {
22211 mark_exp_read (t);
22212 t = c_fully_fold (t, false, NULL);
22213 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
22214 || !tree_fits_shwi_p (t))
22215 error_at (token->location, "property must be "
22216 "constant integer expression");
22217 else
22218 properties = tree_cons (NULL_TREE, t, properties);
22219 }
22220 else
22221 return error_mark_node;
22222 break;
22223 case CTX_PROPERTY_SIMD:
22224 if (parms == NULL_TREE)
22225 {
22226 error_at (token->location, "properties for %<simd%> "
22227 "selector may not be specified in "
22228 "%<metadirective%>");
22229 return error_mark_node;
22230 }
22231 tree c;
22232 c = c_parser_omp_all_clauses (parser,
22233 OMP_DECLARE_SIMD_CLAUSE_MASK,
22234 "simd", true, 2);
22235 c = c_omp_declare_simd_clauses_to_numbers (parms
22236 == error_mark_node
22237 ? NULL_TREE : parms,
22238 c);
22239 properties = c;
22240 break;
22241 default:
22242 gcc_unreachable ();
22243 }
22244
22245 parens.skip_until_found_close (parser);
22246 properties = nreverse (properties);
22247 }
22248 else if (property_kind == CTX_PROPERTY_NAME_LIST
22249 || property_kind == CTX_PROPERTY_ID
22250 || property_kind == CTX_PROPERTY_EXPR)
22251 {
22252 c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>");
22253 return error_mark_node;
22254 }
22255
22256 ret = tree_cons (selector, properties, ret);
22257
22258 if (c_parser_next_token_is (parser, CPP_COMMA))
22259 c_parser_consume_token (parser);
22260 else
22261 break;
22262 }
22263 while (1);
22264
22265 return nreverse (ret);
22266 }
22267
22268 /* OpenMP 5.0:
22269
22270 trait-set-selector[,trait-set-selector[,...]]
22271
22272 trait-set-selector:
22273 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
22274
22275 trait-set-selector-name:
22276 constructor
22277 device
22278 implementation
22279 user */
22280
22281 static tree
22282 c_parser_omp_context_selector_specification (c_parser *parser, tree parms)
22283 {
22284 tree ret = NULL_TREE;
22285 do
22286 {
22287 const char *setp = "";
22288 if (c_parser_next_token_is (parser, CPP_NAME))
22289 setp = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22290 switch (setp[0])
22291 {
22292 case 'c':
22293 if (strcmp (setp, "construct") == 0)
22294 setp = NULL;
22295 break;
22296 case 'd':
22297 if (strcmp (setp, "device") == 0)
22298 setp = NULL;
22299 break;
22300 case 'i':
22301 if (strcmp (setp, "implementation") == 0)
22302 setp = NULL;
22303 break;
22304 case 'u':
22305 if (strcmp (setp, "user") == 0)
22306 setp = NULL;
22307 break;
22308 default:
22309 break;
22310 }
22311 if (setp)
22312 {
22313 c_parser_error (parser, "expected %<construct%>, %<device%>, "
22314 "%<implementation%> or %<user%>");
22315 return error_mark_node;
22316 }
22317
22318 tree set = c_parser_peek_token (parser)->value;
22319 c_parser_consume_token (parser);
22320
22321 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
22322 return error_mark_node;
22323
22324 matching_braces braces;
22325 if (!braces.require_open (parser))
22326 return error_mark_node;
22327
22328 tree selectors = c_parser_omp_context_selector (parser, set, parms);
22329 if (selectors == error_mark_node)
22330 ret = error_mark_node;
22331 else if (ret != error_mark_node)
22332 ret = tree_cons (set, selectors, ret);
22333
22334 braces.skip_until_found_close (parser);
22335
22336 if (c_parser_next_token_is (parser, CPP_COMMA))
22337 c_parser_consume_token (parser);
22338 else
22339 break;
22340 }
22341 while (1);
22342
22343 if (ret == error_mark_node)
22344 return ret;
22345 return nreverse (ret);
22346 }
22347
22348 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
22349 that into "omp declare variant base" attribute. */
22350
22351 static void
22352 c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms)
22353 {
22354 matching_parens parens;
22355 if (!parens.require_open (parser))
22356 {
22357 fail:
22358 c_parser_skip_to_pragma_eol (parser, false);
22359 return;
22360 }
22361
22362 if (c_parser_next_token_is_not (parser, CPP_NAME)
22363 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
22364 {
22365 c_parser_error (parser, "expected identifier");
22366 goto fail;
22367 }
22368
22369 c_token *token = c_parser_peek_token (parser);
22370 tree variant = lookup_name (token->value);
22371
22372 if (variant == NULL_TREE)
22373 {
22374 undeclared_variable (token->location, token->value);
22375 variant = error_mark_node;
22376 }
22377
22378 c_parser_consume_token (parser);
22379
22380 parens.require_close (parser);
22381
22382 const char *clause = "";
22383 location_t match_loc = c_parser_peek_token (parser)->location;
22384 if (c_parser_next_token_is (parser, CPP_NAME))
22385 clause = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22386 if (strcmp (clause, "match"))
22387 {
22388 c_parser_error (parser, "expected %<match%>");
22389 goto fail;
22390 }
22391
22392 c_parser_consume_token (parser);
22393
22394 if (!parens.require_open (parser))
22395 goto fail;
22396
22397 if (parms == NULL_TREE)
22398 parms = error_mark_node;
22399
22400 tree ctx = c_parser_omp_context_selector_specification (parser, parms);
22401 if (ctx == error_mark_node)
22402 goto fail;
22403 ctx = omp_check_context_selector (match_loc, ctx);
22404 if (ctx != error_mark_node && variant != error_mark_node)
22405 {
22406 if (TREE_CODE (variant) != FUNCTION_DECL)
22407 {
22408 error_at (token->location, "variant %qD is not a function", variant);
22409 variant = error_mark_node;
22410 }
22411 else if (omp_get_context_selector (ctx, "construct", "simd") == NULL_TREE
22412 && !comptypes (TREE_TYPE (fndecl), TREE_TYPE (variant)))
22413 {
22414 error_at (token->location, "variant %qD and base %qD have "
22415 "incompatible types", variant, fndecl);
22416 variant = error_mark_node;
22417 }
22418 else if (fndecl_built_in_p (variant)
22419 && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
22420 "__builtin_", strlen ("__builtin_")) == 0
22421 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
22422 "__sync_", strlen ("__sync_")) == 0
22423 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
22424 "__atomic_", strlen ("__atomic_")) == 0))
22425 {
22426 error_at (token->location, "variant %qD is a built-in", variant);
22427 variant = error_mark_node;
22428 }
22429 if (variant != error_mark_node)
22430 {
22431 C_DECL_USED (variant) = 1;
22432 tree construct = omp_get_context_selector (ctx, "construct", NULL);
22433 omp_mark_declare_variant (match_loc, variant, construct);
22434 if (omp_context_selector_matches (ctx))
22435 {
22436 tree attr
22437 = tree_cons (get_identifier ("omp declare variant base"),
22438 build_tree_list (variant, ctx),
22439 DECL_ATTRIBUTES (fndecl));
22440 DECL_ATTRIBUTES (fndecl) = attr;
22441 }
22442 }
22443 }
22444
22445 parens.require_close (parser);
22446 c_parser_skip_to_pragma_eol (parser);
22447 }
22448
22449 /* Finalize #pragma omp declare simd or #pragma omp declare variant
22450 clauses after FNDECL has been parsed, and put that into "omp declare simd"
22451 or "omp declare variant base" attribute. */
22452
22453 static void
22454 c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms,
22455 vec<c_token> *pclauses)
22456 {
22457 vec<c_token> &clauses = *pclauses;
22458
22459 /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there
22460 indicates error has been reported and CPP_PRAGMA that
22461 c_finish_omp_declare_simd has already processed the tokens. */
22462 if (clauses.exists () && clauses[0].type == CPP_EOF)
22463 return;
22464 const char *kind = "simd";
22465 if (clauses.exists ()
22466 && (clauses[0].type == CPP_NAME || clauses[0].type == CPP_PRAGMA))
22467 kind = IDENTIFIER_POINTER (clauses[0].value);
22468 gcc_assert (strcmp (kind, "simd") == 0 || strcmp (kind, "variant") == 0);
22469 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
22470 {
22471 error ("%<#pragma omp declare %s%> not immediately followed by "
22472 "a function declaration or definition", kind);
22473 clauses[0].type = CPP_EOF;
22474 return;
22475 }
22476 if (clauses.exists () && clauses[0].type != CPP_NAME)
22477 {
22478 error_at (DECL_SOURCE_LOCATION (fndecl),
22479 "%<#pragma omp declare %s%> not immediately followed by "
22480 "a single function declaration or definition", kind);
22481 clauses[0].type = CPP_EOF;
22482 return;
22483 }
22484
22485 if (parms == NULL_TREE)
22486 parms = DECL_ARGUMENTS (fndecl);
22487
22488 unsigned int tokens_avail = parser->tokens_avail;
22489 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
22490
22491 parser->tokens = clauses.address ();
22492 parser->tokens_avail = clauses.length ();
22493
22494 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
22495 while (parser->tokens_avail > 3)
22496 {
22497 c_token *token = c_parser_peek_token (parser);
22498 gcc_assert (token->type == CPP_NAME
22499 && strcmp (IDENTIFIER_POINTER (token->value), kind) == 0);
22500 c_parser_consume_token (parser);
22501 parser->in_pragma = true;
22502
22503 if (strcmp (kind, "simd") == 0)
22504 {
22505 tree c;
22506 c = c_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
22507 "#pragma omp declare simd");
22508 c = c_omp_declare_simd_clauses_to_numbers (parms, c);
22509 if (c != NULL_TREE)
22510 c = tree_cons (NULL_TREE, c, NULL_TREE);
22511 c = build_tree_list (get_identifier ("omp declare simd"), c);
22512 TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl);
22513 DECL_ATTRIBUTES (fndecl) = c;
22514 }
22515 else
22516 {
22517 gcc_assert (strcmp (kind, "variant") == 0);
22518 c_finish_omp_declare_variant (parser, fndecl, parms);
22519 }
22520 }
22521
22522 parser->tokens = &parser->tokens_buf[0];
22523 parser->tokens_avail = tokens_avail;
22524 if (clauses.exists ())
22525 clauses[0].type = CPP_PRAGMA;
22526 }
22527
22528
22529 /* OpenMP 4.0:
22530 # pragma omp declare target new-line
22531 declarations and definitions
22532 # pragma omp end declare target new-line
22533
22534 OpenMP 4.5:
22535 # pragma omp declare target ( extended-list ) new-line
22536
22537 # pragma omp declare target declare-target-clauses[seq] new-line */
22538
22539 #define OMP_DECLARE_TARGET_CLAUSE_MASK \
22540 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
22541 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ENTER) \
22542 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
22543 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
22544
22545 static void
22546 c_parser_omp_declare_target (c_parser *parser)
22547 {
22548 tree clauses = NULL_TREE;
22549 int device_type = 0;
22550 bool only_device_type = true;
22551 if (c_parser_next_token_is (parser, CPP_NAME))
22552 clauses = c_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
22553 "#pragma omp declare target");
22554 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
22555 {
22556 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
22557 clauses);
22558 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
22559 c_parser_skip_to_pragma_eol (parser);
22560 }
22561 else
22562 {
22563 c_parser_skip_to_pragma_eol (parser);
22564 c_omp_declare_target_attr attr = { -1 };
22565 vec_safe_push (current_omp_declare_target_attribute, attr);
22566 return;
22567 }
22568 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
22569 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
22570 device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
22571 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
22572 {
22573 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
22574 continue;
22575 tree t = OMP_CLAUSE_DECL (c), id;
22576 tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
22577 tree at2 = lookup_attribute ("omp declare target link",
22578 DECL_ATTRIBUTES (t));
22579 only_device_type = false;
22580 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
22581 {
22582 id = get_identifier ("omp declare target link");
22583 std::swap (at1, at2);
22584 }
22585 else
22586 id = get_identifier ("omp declare target");
22587 if (at2)
22588 {
22589 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ENTER)
22590 error_at (OMP_CLAUSE_LOCATION (c),
22591 "%qD specified both in declare target %<link%> and %qs"
22592 " clauses", t, OMP_CLAUSE_ENTER_TO (c) ? "to" : "enter");
22593 else
22594 error_at (OMP_CLAUSE_LOCATION (c),
22595 "%qD specified both in declare target %<link%> and "
22596 "%<to%> or %<enter%> clauses", t);
22597 continue;
22598 }
22599 if (!at1)
22600 {
22601 DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
22602 if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t))
22603 continue;
22604
22605 symtab_node *node = symtab_node::get (t);
22606 if (node != NULL)
22607 {
22608 node->offloadable = 1;
22609 if (ENABLE_OFFLOADING)
22610 {
22611 g->have_offload = true;
22612 if (is_a <varpool_node *> (node))
22613 vec_safe_push (offload_vars, t);
22614 }
22615 }
22616 }
22617 if (TREE_CODE (t) != FUNCTION_DECL)
22618 continue;
22619 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0)
22620 {
22621 tree at3 = lookup_attribute ("omp declare target host",
22622 DECL_ATTRIBUTES (t));
22623 if (at3 == NULL_TREE)
22624 {
22625 id = get_identifier ("omp declare target host");
22626 DECL_ATTRIBUTES (t)
22627 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
22628 }
22629 }
22630 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0)
22631 {
22632 tree at3 = lookup_attribute ("omp declare target nohost",
22633 DECL_ATTRIBUTES (t));
22634 if (at3 == NULL_TREE)
22635 {
22636 id = get_identifier ("omp declare target nohost");
22637 DECL_ATTRIBUTES (t)
22638 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
22639 }
22640 }
22641 }
22642 if (device_type && only_device_type)
22643 error_at (OMP_CLAUSE_LOCATION (clauses),
22644 "directive with only %<device_type%> clause");
22645 }
22646
22647 /* OpenMP 5.1
22648 #pragma omp begin assumes clauses[optseq] new-line
22649
22650 #pragma omp begin declare target clauses[optseq] new-line */
22651
22652 #define OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK \
22653 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE)
22654
22655 static void
22656 c_parser_omp_begin (c_parser *parser)
22657 {
22658 const char *p = "";
22659 c_parser_consume_pragma (parser);
22660 if (c_parser_next_token_is (parser, CPP_NAME))
22661 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22662 if (strcmp (p, "declare") == 0)
22663 {
22664 c_parser_consume_token (parser);
22665 p = "";
22666 if (c_parser_next_token_is (parser, CPP_NAME))
22667 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22668 if (strcmp (p, "target") == 0)
22669 {
22670 c_parser_consume_token (parser);
22671 tree clauses
22672 = c_parser_omp_all_clauses (parser,
22673 OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK,
22674 "#pragma omp begin declare target");
22675 int device_type = 0;
22676 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
22677 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
22678 device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
22679 c_omp_declare_target_attr attr = { device_type };
22680 vec_safe_push (current_omp_declare_target_attribute, attr);
22681 }
22682 else
22683 {
22684 c_parser_error (parser, "expected %<target%>");
22685 c_parser_skip_to_pragma_eol (parser);
22686 }
22687 }
22688 else if (strcmp (p, "assumes") == 0)
22689 {
22690 c_parser_consume_token (parser);
22691 c_parser_omp_assumption_clauses (parser, false);
22692 current_omp_begin_assumes++;
22693 }
22694 else
22695 {
22696 c_parser_error (parser, "expected %<declare target%> or %<assumes%>");
22697 c_parser_skip_to_pragma_eol (parser);
22698 }
22699 }
22700
22701 /* OpenMP 4.0
22702 #pragma omp end declare target
22703
22704 OpenMP 5.1
22705 #pragma omp end assumes */
22706
22707 static void
22708 c_parser_omp_end (c_parser *parser)
22709 {
22710 location_t loc = c_parser_peek_token (parser)->location;
22711 const char *p = "";
22712 c_parser_consume_pragma (parser);
22713 if (c_parser_next_token_is (parser, CPP_NAME))
22714 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22715 if (strcmp (p, "declare") == 0)
22716 {
22717 c_parser_consume_token (parser);
22718 if (c_parser_next_token_is (parser, CPP_NAME)
22719 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
22720 "target") == 0)
22721 c_parser_consume_token (parser);
22722 else
22723 {
22724 c_parser_error (parser, "expected %<target%>");
22725 c_parser_skip_to_pragma_eol (parser);
22726 return;
22727 }
22728 c_parser_skip_to_pragma_eol (parser);
22729 if (!vec_safe_length (current_omp_declare_target_attribute))
22730 error_at (loc, "%<#pragma omp end declare target%> without "
22731 "corresponding %<#pragma omp declare target%> or "
22732 "%<#pragma omp begin declare target%>");
22733 else
22734 current_omp_declare_target_attribute->pop ();
22735 }
22736 else if (strcmp (p, "assumes") == 0)
22737 {
22738 c_parser_consume_token (parser);
22739 c_parser_skip_to_pragma_eol (parser);
22740 if (!current_omp_begin_assumes)
22741 error_at (loc, "%qs without corresponding %qs",
22742 "#pragma omp end assumes", "#pragma omp begin assumes");
22743 else
22744 current_omp_begin_assumes--;
22745 }
22746 else
22747 {
22748 c_parser_error (parser, "expected %<declare%> or %<assumes%>");
22749 c_parser_skip_to_pragma_eol (parser);
22750 }
22751 }
22752
22753 /* OpenMP 4.0
22754 #pragma omp declare reduction (reduction-id : typename-list : expression) \
22755 initializer-clause[opt] new-line
22756
22757 initializer-clause:
22758 initializer (omp_priv = initializer)
22759 initializer (function-name (argument-list)) */
22760
22761 static void
22762 c_parser_omp_declare_reduction (c_parser *parser, enum pragma_context context)
22763 {
22764 unsigned int tokens_avail = 0, i;
22765 vec<tree> types = vNULL;
22766 vec<c_token> clauses = vNULL;
22767 enum tree_code reduc_code = ERROR_MARK;
22768 tree reduc_id = NULL_TREE;
22769 tree type;
22770 location_t rloc = c_parser_peek_token (parser)->location;
22771
22772 if (context == pragma_struct || context == pragma_param)
22773 {
22774 error ("%<#pragma omp declare reduction%> not at file or block scope");
22775 goto fail;
22776 }
22777
22778 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
22779 goto fail;
22780
22781 switch (c_parser_peek_token (parser)->type)
22782 {
22783 case CPP_PLUS:
22784 reduc_code = PLUS_EXPR;
22785 break;
22786 case CPP_MULT:
22787 reduc_code = MULT_EXPR;
22788 break;
22789 case CPP_MINUS:
22790 reduc_code = MINUS_EXPR;
22791 break;
22792 case CPP_AND:
22793 reduc_code = BIT_AND_EXPR;
22794 break;
22795 case CPP_XOR:
22796 reduc_code = BIT_XOR_EXPR;
22797 break;
22798 case CPP_OR:
22799 reduc_code = BIT_IOR_EXPR;
22800 break;
22801 case CPP_AND_AND:
22802 reduc_code = TRUTH_ANDIF_EXPR;
22803 break;
22804 case CPP_OR_OR:
22805 reduc_code = TRUTH_ORIF_EXPR;
22806 break;
22807 case CPP_NAME:
22808 const char *p;
22809 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22810 if (strcmp (p, "min") == 0)
22811 {
22812 reduc_code = MIN_EXPR;
22813 break;
22814 }
22815 if (strcmp (p, "max") == 0)
22816 {
22817 reduc_code = MAX_EXPR;
22818 break;
22819 }
22820 reduc_id = c_parser_peek_token (parser)->value;
22821 break;
22822 default:
22823 c_parser_error (parser,
22824 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
22825 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
22826 goto fail;
22827 }
22828
22829 tree orig_reduc_id, reduc_decl;
22830 orig_reduc_id = reduc_id;
22831 reduc_id = c_omp_reduction_id (reduc_code, reduc_id);
22832 reduc_decl = c_omp_reduction_decl (reduc_id);
22833 c_parser_consume_token (parser);
22834
22835 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
22836 goto fail;
22837
22838 while (true)
22839 {
22840 location_t loc = c_parser_peek_token (parser)->location;
22841 struct c_type_name *ctype = c_parser_type_name (parser);
22842 if (ctype != NULL)
22843 {
22844 type = groktypename (ctype, NULL, NULL);
22845 if (type == error_mark_node)
22846 ;
22847 else if ((INTEGRAL_TYPE_P (type)
22848 || TREE_CODE (type) == REAL_TYPE
22849 || TREE_CODE (type) == COMPLEX_TYPE)
22850 && orig_reduc_id == NULL_TREE)
22851 error_at (loc, "predeclared arithmetic type in "
22852 "%<#pragma omp declare reduction%>");
22853 else if (TREE_CODE (type) == FUNCTION_TYPE
22854 || TREE_CODE (type) == ARRAY_TYPE)
22855 error_at (loc, "function or array type in "
22856 "%<#pragma omp declare reduction%>");
22857 else if (TYPE_ATOMIC (type))
22858 error_at (loc, "%<_Atomic%> qualified type in "
22859 "%<#pragma omp declare reduction%>");
22860 else if (TYPE_QUALS_NO_ADDR_SPACE (type))
22861 error_at (loc, "const, volatile or restrict qualified type in "
22862 "%<#pragma omp declare reduction%>");
22863 else
22864 {
22865 tree t;
22866 for (t = DECL_INITIAL (reduc_decl); t; t = TREE_CHAIN (t))
22867 if (comptypes (TREE_PURPOSE (t), type))
22868 {
22869 error_at (loc, "redeclaration of %qs "
22870 "%<#pragma omp declare reduction%> for "
22871 "type %qT",
22872 IDENTIFIER_POINTER (reduc_id)
22873 + sizeof ("omp declare reduction ") - 1,
22874 type);
22875 location_t ploc
22876 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t),
22877 0));
22878 error_at (ploc, "previous %<#pragma omp declare "
22879 "reduction%>");
22880 break;
22881 }
22882 if (t == NULL_TREE)
22883 types.safe_push (type);
22884 }
22885 if (c_parser_next_token_is (parser, CPP_COMMA))
22886 c_parser_consume_token (parser);
22887 else
22888 break;
22889 }
22890 else
22891 break;
22892 }
22893
22894 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")
22895 || types.is_empty ())
22896 {
22897 fail:
22898 clauses.release ();
22899 types.release ();
22900 while (true)
22901 {
22902 c_token *token = c_parser_peek_token (parser);
22903 if (token->type == CPP_EOF || token->type == CPP_PRAGMA_EOL)
22904 break;
22905 c_parser_consume_token (parser);
22906 }
22907 c_parser_skip_to_pragma_eol (parser);
22908 return;
22909 }
22910
22911 if (types.length () > 1)
22912 {
22913 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
22914 {
22915 c_token *token = c_parser_peek_token (parser);
22916 if (token->type == CPP_EOF)
22917 goto fail;
22918 clauses.safe_push (*token);
22919 c_parser_consume_token (parser);
22920 }
22921 clauses.safe_push (*c_parser_peek_token (parser));
22922 c_parser_skip_to_pragma_eol (parser);
22923
22924 /* Make sure nothing tries to read past the end of the tokens. */
22925 c_token eof_token;
22926 memset (&eof_token, 0, sizeof (eof_token));
22927 eof_token.type = CPP_EOF;
22928 clauses.safe_push (eof_token);
22929 clauses.safe_push (eof_token);
22930 }
22931
22932 int errs = errorcount;
22933 FOR_EACH_VEC_ELT (types, i, type)
22934 {
22935 tokens_avail = parser->tokens_avail;
22936 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
22937 if (!clauses.is_empty ())
22938 {
22939 parser->tokens = clauses.address ();
22940 parser->tokens_avail = clauses.length ();
22941 parser->in_pragma = true;
22942 }
22943
22944 bool nested = current_function_decl != NULL_TREE;
22945 if (nested)
22946 c_push_function_context ();
22947 tree fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
22948 reduc_id, default_function_type);
22949 current_function_decl = fndecl;
22950 allocate_struct_function (fndecl, true);
22951 push_scope ();
22952 tree stmt = push_stmt_list ();
22953 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
22954 warn about these. */
22955 tree omp_out = build_decl (BUILTINS_LOCATION, VAR_DECL,
22956 get_identifier ("omp_out"), type);
22957 DECL_ARTIFICIAL (omp_out) = 1;
22958 DECL_CONTEXT (omp_out) = fndecl;
22959 pushdecl (omp_out);
22960 tree omp_in = build_decl (BUILTINS_LOCATION, VAR_DECL,
22961 get_identifier ("omp_in"), type);
22962 DECL_ARTIFICIAL (omp_in) = 1;
22963 DECL_CONTEXT (omp_in) = fndecl;
22964 pushdecl (omp_in);
22965 struct c_expr combiner = c_parser_expression (parser);
22966 struct c_expr initializer;
22967 tree omp_priv = NULL_TREE, omp_orig = NULL_TREE;
22968 bool bad = false;
22969 initializer.set_error ();
22970 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
22971 bad = true;
22972 else if (c_parser_next_token_is (parser, CPP_NAME)
22973 && strcmp (IDENTIFIER_POINTER
22974 (c_parser_peek_token (parser)->value),
22975 "initializer") == 0)
22976 {
22977 c_parser_consume_token (parser);
22978 pop_scope ();
22979 push_scope ();
22980 omp_priv = build_decl (BUILTINS_LOCATION, VAR_DECL,
22981 get_identifier ("omp_priv"), type);
22982 DECL_ARTIFICIAL (omp_priv) = 1;
22983 DECL_INITIAL (omp_priv) = error_mark_node;
22984 DECL_CONTEXT (omp_priv) = fndecl;
22985 pushdecl (omp_priv);
22986 omp_orig = build_decl (BUILTINS_LOCATION, VAR_DECL,
22987 get_identifier ("omp_orig"), type);
22988 DECL_ARTIFICIAL (omp_orig) = 1;
22989 DECL_CONTEXT (omp_orig) = fndecl;
22990 pushdecl (omp_orig);
22991 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
22992 bad = true;
22993 else if (!c_parser_next_token_is (parser, CPP_NAME))
22994 {
22995 c_parser_error (parser, "expected %<omp_priv%> or "
22996 "function-name");
22997 bad = true;
22998 }
22999 else if (strcmp (IDENTIFIER_POINTER
23000 (c_parser_peek_token (parser)->value),
23001 "omp_priv") != 0)
23002 {
23003 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
23004 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
23005 {
23006 c_parser_error (parser, "expected function-name %<(%>");
23007 bad = true;
23008 }
23009 else
23010 initializer = c_parser_postfix_expression (parser);
23011 if (initializer.value
23012 && TREE_CODE (initializer.value) == CALL_EXPR)
23013 {
23014 int j;
23015 tree c = initializer.value;
23016 for (j = 0; j < call_expr_nargs (c); j++)
23017 {
23018 tree a = CALL_EXPR_ARG (c, j);
23019 STRIP_NOPS (a);
23020 if (TREE_CODE (a) == ADDR_EXPR
23021 && TREE_OPERAND (a, 0) == omp_priv)
23022 break;
23023 }
23024 if (j == call_expr_nargs (c))
23025 error ("one of the initializer call arguments should be "
23026 "%<&omp_priv%>");
23027 }
23028 }
23029 else
23030 {
23031 c_parser_consume_token (parser);
23032 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
23033 bad = true;
23034 else
23035 {
23036 tree st = push_stmt_list ();
23037 location_t loc = c_parser_peek_token (parser)->location;
23038 rich_location richloc (line_table, loc);
23039 start_init (omp_priv, NULL_TREE, 0, &richloc);
23040 struct c_expr init = c_parser_initializer (parser, omp_priv);
23041 finish_init ();
23042 finish_decl (omp_priv, loc, init.value,
23043 init.original_type, NULL_TREE);
23044 pop_stmt_list (st);
23045 }
23046 }
23047 if (!bad
23048 && !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
23049 bad = true;
23050 }
23051
23052 if (!bad)
23053 {
23054 c_parser_skip_to_pragma_eol (parser);
23055
23056 tree t = tree_cons (type, make_tree_vec (omp_priv ? 6 : 3),
23057 DECL_INITIAL (reduc_decl));
23058 DECL_INITIAL (reduc_decl) = t;
23059 DECL_SOURCE_LOCATION (omp_out) = rloc;
23060 TREE_VEC_ELT (TREE_VALUE (t), 0) = omp_out;
23061 TREE_VEC_ELT (TREE_VALUE (t), 1) = omp_in;
23062 TREE_VEC_ELT (TREE_VALUE (t), 2) = combiner.value;
23063 walk_tree (&combiner.value, c_check_omp_declare_reduction_r,
23064 &TREE_VEC_ELT (TREE_VALUE (t), 0), NULL);
23065 if (omp_priv)
23066 {
23067 DECL_SOURCE_LOCATION (omp_priv) = rloc;
23068 TREE_VEC_ELT (TREE_VALUE (t), 3) = omp_priv;
23069 TREE_VEC_ELT (TREE_VALUE (t), 4) = omp_orig;
23070 TREE_VEC_ELT (TREE_VALUE (t), 5) = initializer.value;
23071 walk_tree (&initializer.value, c_check_omp_declare_reduction_r,
23072 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
23073 walk_tree (&DECL_INITIAL (omp_priv),
23074 c_check_omp_declare_reduction_r,
23075 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
23076 }
23077 }
23078
23079 pop_stmt_list (stmt);
23080 pop_scope ();
23081 if (cfun->language != NULL)
23082 {
23083 ggc_free (cfun->language);
23084 cfun->language = NULL;
23085 }
23086 set_cfun (NULL);
23087 current_function_decl = NULL_TREE;
23088 if (nested)
23089 c_pop_function_context ();
23090
23091 if (!clauses.is_empty ())
23092 {
23093 parser->tokens = &parser->tokens_buf[0];
23094 parser->tokens_avail = tokens_avail;
23095 }
23096 if (bad)
23097 goto fail;
23098 if (errs != errorcount)
23099 break;
23100 }
23101
23102 clauses.release ();
23103 types.release ();
23104 }
23105
23106
23107 /* OpenMP 4.0
23108 #pragma omp declare simd declare-simd-clauses[optseq] new-line
23109 #pragma omp declare reduction (reduction-id : typename-list : expression) \
23110 initializer-clause[opt] new-line
23111 #pragma omp declare target new-line
23112
23113 OpenMP 5.0
23114 #pragma omp declare variant (identifier) match (context-selector) */
23115
23116 static bool
23117 c_parser_omp_declare (c_parser *parser, enum pragma_context context)
23118 {
23119 c_parser_consume_pragma (parser);
23120 if (c_parser_next_token_is (parser, CPP_NAME))
23121 {
23122 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23123 if (strcmp (p, "simd") == 0)
23124 {
23125 /* c_parser_consume_token (parser); done in
23126 c_parser_omp_declare_simd. */
23127 c_parser_omp_declare_simd (parser, context);
23128 return true;
23129 }
23130 if (strcmp (p, "reduction") == 0)
23131 {
23132 c_parser_consume_token (parser);
23133 c_parser_omp_declare_reduction (parser, context);
23134 return false;
23135 }
23136 if (!flag_openmp) /* flag_openmp_simd */
23137 {
23138 c_parser_skip_to_pragma_eol (parser, false);
23139 return false;
23140 }
23141 if (strcmp (p, "target") == 0)
23142 {
23143 c_parser_consume_token (parser);
23144 c_parser_omp_declare_target (parser);
23145 return false;
23146 }
23147 if (strcmp (p, "variant") == 0)
23148 {
23149 /* c_parser_consume_token (parser); done in
23150 c_parser_omp_declare_simd. */
23151 c_parser_omp_declare_simd (parser, context);
23152 return true;
23153 }
23154 }
23155
23156 c_parser_error (parser, "expected %<simd%>, %<reduction%>, "
23157 "%<target%> or %<variant%>");
23158 c_parser_skip_to_pragma_eol (parser);
23159 return false;
23160 }
23161
23162 /* OpenMP 5.0
23163 #pragma omp requires clauses[optseq] new-line */
23164
23165 static void
23166 c_parser_omp_requires (c_parser *parser)
23167 {
23168 bool first = true;
23169 enum omp_requires new_req = (enum omp_requires) 0;
23170
23171 c_parser_consume_pragma (parser);
23172
23173 location_t loc = c_parser_peek_token (parser)->location;
23174 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
23175 {
23176 if (!first
23177 && c_parser_next_token_is (parser, CPP_COMMA)
23178 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
23179 c_parser_consume_token (parser);
23180
23181 first = false;
23182
23183 if (c_parser_next_token_is (parser, CPP_NAME))
23184 {
23185 const char *p
23186 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23187 location_t cloc = c_parser_peek_token (parser)->location;
23188 enum omp_requires this_req = (enum omp_requires) 0;
23189
23190 if (!strcmp (p, "unified_address"))
23191 this_req = OMP_REQUIRES_UNIFIED_ADDRESS;
23192 else if (!strcmp (p, "unified_shared_memory"))
23193 this_req = OMP_REQUIRES_UNIFIED_SHARED_MEMORY;
23194 else if (!strcmp (p, "dynamic_allocators"))
23195 this_req = OMP_REQUIRES_DYNAMIC_ALLOCATORS;
23196 else if (!strcmp (p, "reverse_offload"))
23197 this_req = OMP_REQUIRES_REVERSE_OFFLOAD;
23198 else if (!strcmp (p, "atomic_default_mem_order"))
23199 {
23200 c_parser_consume_token (parser);
23201
23202 matching_parens parens;
23203 if (parens.require_open (parser))
23204 {
23205 if (c_parser_next_token_is (parser, CPP_NAME))
23206 {
23207 tree v = c_parser_peek_token (parser)->value;
23208 p = IDENTIFIER_POINTER (v);
23209
23210 if (!strcmp (p, "seq_cst"))
23211 this_req
23212 = (enum omp_requires) OMP_MEMORY_ORDER_SEQ_CST;
23213 else if (!strcmp (p, "relaxed"))
23214 this_req
23215 = (enum omp_requires) OMP_MEMORY_ORDER_RELAXED;
23216 else if (!strcmp (p, "acq_rel"))
23217 this_req
23218 = (enum omp_requires) OMP_MEMORY_ORDER_ACQ_REL;
23219 }
23220 if (this_req == 0)
23221 {
23222 error_at (c_parser_peek_token (parser)->location,
23223 "expected %<seq_cst%>, %<relaxed%> or "
23224 "%<acq_rel%>");
23225 switch (c_parser_peek_token (parser)->type)
23226 {
23227 case CPP_EOF:
23228 case CPP_PRAGMA_EOL:
23229 case CPP_CLOSE_PAREN:
23230 break;
23231 default:
23232 if (c_parser_peek_2nd_token (parser)->type
23233 == CPP_CLOSE_PAREN)
23234 c_parser_consume_token (parser);
23235 break;
23236 }
23237 }
23238 else
23239 c_parser_consume_token (parser);
23240
23241 parens.skip_until_found_close (parser);
23242 if (this_req == 0)
23243 {
23244 c_parser_skip_to_pragma_eol (parser, false);
23245 return;
23246 }
23247 }
23248 p = NULL;
23249 }
23250 else
23251 {
23252 error_at (cloc, "expected %<unified_address%>, "
23253 "%<unified_shared_memory%>, "
23254 "%<dynamic_allocators%>, "
23255 "%<reverse_offload%> "
23256 "or %<atomic_default_mem_order%> clause");
23257 c_parser_skip_to_pragma_eol (parser, false);
23258 return;
23259 }
23260 if (p)
23261 c_parser_consume_token (parser);
23262 if (this_req)
23263 {
23264 if ((this_req & ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
23265 {
23266 if ((this_req & new_req) != 0)
23267 error_at (cloc, "too many %qs clauses", p);
23268 if (this_req != OMP_REQUIRES_DYNAMIC_ALLOCATORS
23269 && (omp_requires_mask & OMP_REQUIRES_TARGET_USED) != 0)
23270 error_at (cloc, "%qs clause used lexically after first "
23271 "target construct or offloading API", p);
23272 }
23273 else if ((new_req & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
23274 {
23275 error_at (cloc, "too many %qs clauses",
23276 "atomic_default_mem_order");
23277 this_req = (enum omp_requires) 0;
23278 }
23279 else if ((omp_requires_mask
23280 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
23281 {
23282 error_at (cloc, "more than one %<atomic_default_mem_order%>"
23283 " clause in a single compilation unit");
23284 this_req
23285 = (enum omp_requires)
23286 (omp_requires_mask
23287 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER);
23288 }
23289 else if ((omp_requires_mask
23290 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED) != 0)
23291 error_at (cloc, "%<atomic_default_mem_order%> clause used "
23292 "lexically after first %<atomic%> construct "
23293 "without memory order clause");
23294 new_req = (enum omp_requires) (new_req | this_req);
23295 omp_requires_mask
23296 = (enum omp_requires) (omp_requires_mask | this_req);
23297 continue;
23298 }
23299 }
23300 break;
23301 }
23302 c_parser_skip_to_pragma_eol (parser);
23303
23304 if (new_req == 0)
23305 error_at (loc, "%<pragma omp requires%> requires at least one clause");
23306 }
23307
23308 /* Helper function for c_parser_omp_taskloop.
23309 Disallow zero sized or potentially zero sized task reductions. */
23310
23311 static tree
23312 c_finish_taskloop_clauses (tree clauses)
23313 {
23314 tree *pc = &clauses;
23315 for (tree c = clauses; c; c = *pc)
23316 {
23317 bool remove = false;
23318 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
23319 {
23320 tree type = strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c)));
23321 if (integer_zerop (TYPE_SIZE_UNIT (type)))
23322 {
23323 error_at (OMP_CLAUSE_LOCATION (c),
23324 "zero sized type %qT in %<reduction%> clause", type);
23325 remove = true;
23326 }
23327 else if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
23328 {
23329 error_at (OMP_CLAUSE_LOCATION (c),
23330 "variable sized type %qT in %<reduction%> clause",
23331 type);
23332 remove = true;
23333 }
23334 }
23335 if (remove)
23336 *pc = OMP_CLAUSE_CHAIN (c);
23337 else
23338 pc = &OMP_CLAUSE_CHAIN (c);
23339 }
23340 return clauses;
23341 }
23342
23343 /* OpenMP 4.5:
23344 #pragma omp taskloop taskloop-clause[optseq] new-line
23345 for-loop
23346
23347 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
23348 for-loop */
23349
23350 #define OMP_TASKLOOP_CLAUSE_MASK \
23351 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
23352 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
23353 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
23354 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
23355 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
23356 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
23357 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
23358 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
23359 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
23360 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
23361 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
23362 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
23363 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
23364 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
23365 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
23366 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
23367 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
23368
23369 static tree
23370 c_parser_omp_taskloop (location_t loc, c_parser *parser,
23371 char *p_name, omp_clause_mask mask, tree *cclauses,
23372 bool *if_p)
23373 {
23374 tree clauses, block, ret;
23375
23376 strcat (p_name, " taskloop");
23377 mask |= OMP_TASKLOOP_CLAUSE_MASK;
23378 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
23379 clause. */
23380 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
23381 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION);
23382
23383 if (c_parser_next_token_is (parser, CPP_NAME))
23384 {
23385 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23386
23387 if (strcmp (p, "simd") == 0)
23388 {
23389 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
23390 if (cclauses == NULL)
23391 cclauses = cclauses_buf;
23392 c_parser_consume_token (parser);
23393 if (!flag_openmp) /* flag_openmp_simd */
23394 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
23395 if_p);
23396 block = c_begin_compound_stmt (true);
23397 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
23398 block = c_end_compound_stmt (loc, block, true);
23399 if (ret == NULL)
23400 return ret;
23401 ret = make_node (OMP_TASKLOOP);
23402 TREE_TYPE (ret) = void_type_node;
23403 OMP_FOR_BODY (ret) = block;
23404 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
23405 OMP_FOR_CLAUSES (ret)
23406 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret));
23407 SET_EXPR_LOCATION (ret, loc);
23408 add_stmt (ret);
23409 return ret;
23410 }
23411 }
23412 if (!flag_openmp) /* flag_openmp_simd */
23413 {
23414 c_parser_skip_to_pragma_eol (parser, false);
23415 return NULL_TREE;
23416 }
23417
23418 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
23419 if (cclauses)
23420 {
23421 omp_split_clauses (loc, OMP_TASKLOOP, mask, clauses, cclauses);
23422 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
23423 }
23424
23425 clauses = c_finish_taskloop_clauses (clauses);
23426 block = c_begin_compound_stmt (true);
23427 ret = c_parser_omp_for_loop (loc, parser, OMP_TASKLOOP, clauses, NULL, if_p);
23428 block = c_end_compound_stmt (loc, block, true);
23429 add_stmt (block);
23430
23431 return ret;
23432 }
23433
23434 /* OpenMP 5.1
23435 #pragma omp nothing new-line */
23436
23437 static void
23438 c_parser_omp_nothing (c_parser *parser)
23439 {
23440 c_parser_consume_pragma (parser);
23441 c_parser_skip_to_pragma_eol (parser);
23442 }
23443
23444 /* OpenMP 5.1
23445 #pragma omp error clauses[optseq] new-line */
23446
23447 static bool
23448 c_parser_omp_error (c_parser *parser, enum pragma_context context)
23449 {
23450 int at_compilation = -1;
23451 int severity_fatal = -1;
23452 tree message = NULL_TREE;
23453 bool first = true;
23454 bool bad = false;
23455 location_t loc = c_parser_peek_token (parser)->location;
23456
23457 c_parser_consume_pragma (parser);
23458
23459 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
23460 {
23461 if (!first
23462 && c_parser_next_token_is (parser, CPP_COMMA)
23463 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
23464 c_parser_consume_token (parser);
23465
23466 first = false;
23467
23468 if (!c_parser_next_token_is (parser, CPP_NAME))
23469 break;
23470
23471 const char *p
23472 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23473 location_t cloc = c_parser_peek_token (parser)->location;
23474 static const char *args[] = {
23475 "execution", "compilation", "warning", "fatal"
23476 };
23477 int *v = NULL;
23478 int idx = 0, n = -1;
23479 tree m = NULL_TREE;
23480
23481 if (!strcmp (p, "at"))
23482 v = &at_compilation;
23483 else if (!strcmp (p, "severity"))
23484 {
23485 v = &severity_fatal;
23486 idx += 2;
23487 }
23488 else if (strcmp (p, "message"))
23489 {
23490 error_at (cloc,
23491 "expected %<at%>, %<severity%> or %<message%> clause");
23492 c_parser_skip_to_pragma_eol (parser, false);
23493 return false;
23494 }
23495
23496 c_parser_consume_token (parser);
23497
23498 matching_parens parens;
23499 if (parens.require_open (parser))
23500 {
23501 if (v == NULL)
23502 {
23503 location_t expr_loc = c_parser_peek_token (parser)->location;
23504 c_expr expr = c_parser_expr_no_commas (parser, NULL);
23505 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
23506 m = convert (const_string_type_node, expr.value);
23507 m = c_fully_fold (m, false, NULL);
23508 }
23509 else
23510 {
23511 if (c_parser_next_token_is (parser, CPP_NAME))
23512 {
23513 tree val = c_parser_peek_token (parser)->value;
23514 const char *q = IDENTIFIER_POINTER (val);
23515
23516 if (!strcmp (q, args[idx]))
23517 n = 0;
23518 else if (!strcmp (q, args[idx + 1]))
23519 n = 1;
23520 }
23521 if (n == -1)
23522 {
23523 error_at (c_parser_peek_token (parser)->location,
23524 "expected %qs or %qs", args[idx], args[idx + 1]);
23525 bad = true;
23526 switch (c_parser_peek_token (parser)->type)
23527 {
23528 case CPP_EOF:
23529 case CPP_PRAGMA_EOL:
23530 case CPP_CLOSE_PAREN:
23531 break;
23532 default:
23533 if (c_parser_peek_2nd_token (parser)->type
23534 == CPP_CLOSE_PAREN)
23535 c_parser_consume_token (parser);
23536 break;
23537 }
23538 }
23539 else
23540 c_parser_consume_token (parser);
23541 }
23542
23543 parens.skip_until_found_close (parser);
23544
23545 if (v == NULL)
23546 {
23547 if (message)
23548 {
23549 error_at (cloc, "too many %qs clauses", p);
23550 bad = true;
23551 }
23552 else
23553 message = m;
23554 }
23555 else if (n != -1)
23556 {
23557 if (*v != -1)
23558 {
23559 error_at (cloc, "too many %qs clauses", p);
23560 bad = true;
23561 }
23562 else
23563 *v = n;
23564 }
23565 }
23566 else
23567 bad = true;
23568 }
23569 c_parser_skip_to_pragma_eol (parser);
23570 if (bad)
23571 return true;
23572
23573 if (at_compilation == -1)
23574 at_compilation = 1;
23575 if (severity_fatal == -1)
23576 severity_fatal = 1;
23577 if (!at_compilation)
23578 {
23579 if (context != pragma_compound)
23580 {
23581 error_at (loc, "%<#pragma omp error%> with %<at(execution)%> clause "
23582 "may only be used in compound statements");
23583 return true;
23584 }
23585 tree fndecl
23586 = builtin_decl_explicit (severity_fatal ? BUILT_IN_GOMP_ERROR
23587 : BUILT_IN_GOMP_WARNING);
23588 if (!message)
23589 message = build_zero_cst (const_string_type_node);
23590 tree stmt = build_call_expr_loc (loc, fndecl, 2, message,
23591 build_all_ones_cst (size_type_node));
23592 add_stmt (stmt);
23593 return true;
23594 }
23595 const char *msg = NULL;
23596 if (message)
23597 {
23598 msg = c_getstr (message);
23599 if (msg == NULL)
23600 msg = _("<message unknown at compile time>");
23601 }
23602 if (msg)
23603 emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
23604 "%<pragma omp error%> encountered: %s", msg);
23605 else
23606 emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
23607 "%<pragma omp error%> encountered");
23608 return false;
23609 }
23610
23611 /* Assumption clauses:
23612 OpenMP 5.1
23613 absent (directive-name-list)
23614 contains (directive-name-list)
23615 holds (expression)
23616 no_openmp
23617 no_openmp_routines
23618 no_parallelism */
23619
23620 static void
23621 c_parser_omp_assumption_clauses (c_parser *parser, bool is_assume)
23622 {
23623 bool first = true;
23624 bool no_openmp = false;
23625 bool no_openmp_routines = false;
23626 bool no_parallelism = false;
23627 bitmap_head absent_head, contains_head;
23628
23629 bitmap_obstack_initialize (NULL);
23630 bitmap_initialize (&absent_head, &bitmap_default_obstack);
23631 bitmap_initialize (&contains_head, &bitmap_default_obstack);
23632
23633 if (c_parser_next_token_is (parser, CPP_PRAGMA_EOL))
23634 error_at (c_parser_peek_token (parser)->location,
23635 "expected at least one assumption clause");
23636
23637 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
23638 {
23639 if (!first
23640 && c_parser_next_token_is (parser, CPP_COMMA)
23641 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
23642 c_parser_consume_token (parser);
23643
23644 first = false;
23645
23646 if (!c_parser_next_token_is (parser, CPP_NAME))
23647 break;
23648
23649 const char *p
23650 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
23651 location_t cloc = c_parser_peek_token (parser)->location;
23652
23653 if (!strcmp (p, "no_openmp"))
23654 {
23655 c_parser_consume_token (parser);
23656 if (no_openmp)
23657 error_at (cloc, "too many %qs clauses", "no_openmp");
23658 no_openmp = true;
23659 }
23660 else if (!strcmp (p, "no_openmp_routines"))
23661 {
23662 c_parser_consume_token (parser);
23663 if (no_openmp_routines)
23664 error_at (cloc, "too many %qs clauses", "no_openmp_routines");
23665 no_openmp_routines = true;
23666 }
23667 else if (!strcmp (p, "no_parallelism"))
23668 {
23669 c_parser_consume_token (parser);
23670 if (no_parallelism)
23671 error_at (cloc, "too many %qs clauses", "no_parallelism");
23672 no_parallelism = true;
23673 }
23674 else if (!strcmp (p, "holds"))
23675 {
23676 c_parser_consume_token (parser);
23677 matching_parens parens;
23678 if (parens.require_open (parser))
23679 {
23680 location_t eloc = c_parser_peek_token (parser)->location;
23681 c_expr expr = c_parser_expr_no_commas (parser, NULL);
23682 tree t = convert_lvalue_to_rvalue (eloc, expr, true, true).value;
23683 t = c_objc_common_truthvalue_conversion (eloc, t);
23684 t = c_fully_fold (t, false, NULL);
23685 if (is_assume && t != error_mark_node)
23686 {
23687 tree fn = build_call_expr_internal_loc (eloc, IFN_ASSUME,
23688 void_type_node, 1,
23689 t);
23690 add_stmt (fn);
23691 }
23692 parens.skip_until_found_close (parser);
23693 }
23694 }
23695 else if (!strcmp (p, "absent") || !strcmp (p, "contains"))
23696 {
23697 c_parser_consume_token (parser);
23698 matching_parens parens;
23699 if (parens.require_open (parser))
23700 {
23701 do
23702 {
23703 const char *directive[3] = {};
23704 int i;
23705 location_t dloc = c_parser_peek_token (parser)->location;
23706 for (i = 0; i < 3; i++)
23707 {
23708 tree id;
23709 if (c_parser_peek_nth_token (parser, i + 1)->type
23710 == CPP_NAME)
23711 id = c_parser_peek_nth_token (parser, i + 1)->value;
23712 else if (c_parser_peek_nth_token (parser, i + 1)->keyword
23713 != RID_MAX)
23714 {
23715 enum rid rid
23716 = c_parser_peek_nth_token (parser, i + 1)->keyword;
23717 id = ridpointers[rid];
23718 }
23719 else
23720 break;
23721 directive[i] = IDENTIFIER_POINTER (id);
23722 }
23723 if (i == 0)
23724 error_at (dloc, "expected directive name");
23725 else
23726 {
23727 const struct c_omp_directive *dir
23728 = c_omp_categorize_directive (directive[0],
23729 directive[1],
23730 directive[2]);
23731 if (dir == NULL
23732 || dir->kind == C_OMP_DIR_DECLARATIVE
23733 || dir->kind == C_OMP_DIR_INFORMATIONAL
23734 || dir->id == PRAGMA_OMP_END
23735 || (!dir->second && directive[1])
23736 || (!dir->third && directive[2]))
23737 error_at (dloc, "unknown OpenMP directive name in "
23738 "%qs clause argument", p);
23739 else
23740 {
23741 int id = dir - c_omp_directives;
23742 if (bitmap_bit_p (p[0] == 'a' ? &contains_head
23743 : &absent_head, id))
23744 error_at (dloc, "%<%s%s%s%s%s%> directive "
23745 "mentioned in both %<absent%> and "
23746 "%<contains%> clauses",
23747 directive[0],
23748 directive[1] ? " " : "",
23749 directive[1] ? directive[1] : "",
23750 directive[2] ? " " : "",
23751 directive[2] ? directive[2] : "");
23752 else if (!bitmap_set_bit (p[0] == 'a'
23753 ? &absent_head
23754 : &contains_head, id))
23755 error_at (dloc, "%<%s%s%s%s%s%> directive "
23756 "mentioned multiple times in %qs "
23757 "clauses",
23758 directive[0],
23759 directive[1] ? " " : "",
23760 directive[1] ? directive[1] : "",
23761 directive[2] ? " " : "",
23762 directive[2] ? directive[2] : "", p);
23763 }
23764 for (; i; --i)
23765 c_parser_consume_token (parser);
23766 }
23767 if (c_parser_next_token_is (parser, CPP_COMMA))
23768 c_parser_consume_token (parser);
23769 else
23770 break;
23771 }
23772 while (1);
23773 parens.skip_until_found_close (parser);
23774 }
23775 }
23776 else if (startswith (p, "ext_"))
23777 {
23778 warning_at (cloc, 0, "unknown assumption clause %qs", p);
23779 c_parser_consume_token (parser);
23780 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
23781 {
23782 matching_parens parens;
23783 parens.consume_open (parser);
23784 c_parser_balanced_token_sequence (parser);
23785 parens.require_close (parser);
23786 }
23787 }
23788 else
23789 {
23790 c_parser_consume_token (parser);
23791 error_at (cloc, "expected assumption clause");
23792 break;
23793 }
23794 }
23795 c_parser_skip_to_pragma_eol (parser);
23796 }
23797
23798 /* OpenMP 5.1
23799 #pragma omp assume clauses[optseq] new-line */
23800
23801 static void
23802 c_parser_omp_assume (c_parser *parser, bool *if_p)
23803 {
23804 c_parser_omp_assumption_clauses (parser, true);
23805 add_stmt (c_parser_omp_structured_block (parser, if_p));
23806 }
23807
23808 /* OpenMP 5.1
23809 #pragma omp assumes clauses[optseq] new-line */
23810
23811 static void
23812 c_parser_omp_assumes (c_parser *parser)
23813 {
23814 c_parser_consume_pragma (parser);
23815 c_parser_omp_assumption_clauses (parser, false);
23816 }
23817
23818 /* Main entry point to parsing most OpenMP pragmas. */
23819
23820 static void
23821 c_parser_omp_construct (c_parser *parser, bool *if_p)
23822 {
23823 enum pragma_kind p_kind;
23824 location_t loc;
23825 tree stmt;
23826 char p_name[sizeof "#pragma omp teams distribute parallel for simd"];
23827 omp_clause_mask mask (0);
23828
23829 loc = c_parser_peek_token (parser)->location;
23830 p_kind = c_parser_peek_token (parser)->pragma_kind;
23831 c_parser_consume_pragma (parser);
23832
23833 switch (p_kind)
23834 {
23835 case PRAGMA_OACC_ATOMIC:
23836 c_parser_omp_atomic (loc, parser, true);
23837 return;
23838 case PRAGMA_OACC_CACHE:
23839 strcpy (p_name, "#pragma acc");
23840 stmt = c_parser_oacc_cache (loc, parser);
23841 break;
23842 case PRAGMA_OACC_DATA:
23843 stmt = c_parser_oacc_data (loc, parser, if_p);
23844 break;
23845 case PRAGMA_OACC_HOST_DATA:
23846 stmt = c_parser_oacc_host_data (loc, parser, if_p);
23847 break;
23848 case PRAGMA_OACC_KERNELS:
23849 case PRAGMA_OACC_PARALLEL:
23850 case PRAGMA_OACC_SERIAL:
23851 strcpy (p_name, "#pragma acc");
23852 stmt = c_parser_oacc_compute (loc, parser, p_kind, p_name, if_p);
23853 break;
23854 case PRAGMA_OACC_LOOP:
23855 strcpy (p_name, "#pragma acc");
23856 stmt = c_parser_oacc_loop (loc, parser, p_name, mask, NULL, if_p);
23857 break;
23858 case PRAGMA_OACC_WAIT:
23859 strcpy (p_name, "#pragma wait");
23860 stmt = c_parser_oacc_wait (loc, parser, p_name);
23861 break;
23862 case PRAGMA_OMP_ALLOCATE:
23863 c_parser_omp_allocate (loc, parser);
23864 return;
23865 case PRAGMA_OMP_ATOMIC:
23866 c_parser_omp_atomic (loc, parser, false);
23867 return;
23868 case PRAGMA_OMP_CRITICAL:
23869 stmt = c_parser_omp_critical (loc, parser, if_p);
23870 break;
23871 case PRAGMA_OMP_DISTRIBUTE:
23872 strcpy (p_name, "#pragma omp");
23873 stmt = c_parser_omp_distribute (loc, parser, p_name, mask, NULL, if_p);
23874 break;
23875 case PRAGMA_OMP_FOR:
23876 strcpy (p_name, "#pragma omp");
23877 stmt = c_parser_omp_for (loc, parser, p_name, mask, NULL, if_p);
23878 break;
23879 case PRAGMA_OMP_LOOP:
23880 strcpy (p_name, "#pragma omp");
23881 stmt = c_parser_omp_loop (loc, parser, p_name, mask, NULL, if_p);
23882 break;
23883 case PRAGMA_OMP_MASKED:
23884 strcpy (p_name, "#pragma omp");
23885 stmt = c_parser_omp_masked (loc, parser, p_name, mask, NULL, if_p);
23886 break;
23887 case PRAGMA_OMP_MASTER:
23888 strcpy (p_name, "#pragma omp");
23889 stmt = c_parser_omp_master (loc, parser, p_name, mask, NULL, if_p);
23890 break;
23891 case PRAGMA_OMP_PARALLEL:
23892 strcpy (p_name, "#pragma omp");
23893 stmt = c_parser_omp_parallel (loc, parser, p_name, mask, NULL, if_p);
23894 break;
23895 case PRAGMA_OMP_SCOPE:
23896 stmt = c_parser_omp_scope (loc, parser, if_p);
23897 break;
23898 case PRAGMA_OMP_SECTIONS:
23899 strcpy (p_name, "#pragma omp");
23900 stmt = c_parser_omp_sections (loc, parser, p_name, mask, NULL);
23901 break;
23902 case PRAGMA_OMP_SIMD:
23903 strcpy (p_name, "#pragma omp");
23904 stmt = c_parser_omp_simd (loc, parser, p_name, mask, NULL, if_p);
23905 break;
23906 case PRAGMA_OMP_SINGLE:
23907 stmt = c_parser_omp_single (loc, parser, if_p);
23908 break;
23909 case PRAGMA_OMP_TASK:
23910 stmt = c_parser_omp_task (loc, parser, if_p);
23911 break;
23912 case PRAGMA_OMP_TASKGROUP:
23913 stmt = c_parser_omp_taskgroup (loc, parser, if_p);
23914 break;
23915 case PRAGMA_OMP_TASKLOOP:
23916 strcpy (p_name, "#pragma omp");
23917 stmt = c_parser_omp_taskloop (loc, parser, p_name, mask, NULL, if_p);
23918 break;
23919 case PRAGMA_OMP_TEAMS:
23920 strcpy (p_name, "#pragma omp");
23921 stmt = c_parser_omp_teams (loc, parser, p_name, mask, NULL, if_p);
23922 break;
23923 case PRAGMA_OMP_ASSUME:
23924 c_parser_omp_assume (parser, if_p);
23925 return;
23926 default:
23927 gcc_unreachable ();
23928 }
23929
23930 if (stmt && stmt != error_mark_node)
23931 gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION);
23932 }
23933
23934
23935 /* OpenMP 2.5:
23936 # pragma omp threadprivate (variable-list) */
23937
23938 static void
23939 c_parser_omp_threadprivate (c_parser *parser)
23940 {
23941 tree vars, t;
23942 location_t loc;
23943
23944 c_parser_consume_pragma (parser);
23945 loc = c_parser_peek_token (parser)->location;
23946 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
23947
23948 /* Mark every variable in VARS to be assigned thread local storage. */
23949 for (t = vars; t; t = TREE_CHAIN (t))
23950 {
23951 tree v = TREE_PURPOSE (t);
23952
23953 /* FIXME diagnostics: Ideally we should keep individual
23954 locations for all the variables in the var list to make the
23955 following errors more precise. Perhaps
23956 c_parser_omp_var_list_parens() should construct a list of
23957 locations to go along with the var list. */
23958
23959 /* If V had already been marked threadprivate, it doesn't matter
23960 whether it had been used prior to this point. */
23961 if (!VAR_P (v))
23962 error_at (loc, "%qD is not a variable", v);
23963 else if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v))
23964 error_at (loc, "%qE declared %<threadprivate%> after first use", v);
23965 else if (! is_global_var (v))
23966 error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v);
23967 else if (TREE_TYPE (v) == error_mark_node)
23968 ;
23969 else if (! COMPLETE_TYPE_P (TREE_TYPE (v)))
23970 error_at (loc, "%<threadprivate%> %qE has incomplete type", v);
23971 else
23972 {
23973 if (! DECL_THREAD_LOCAL_P (v))
23974 {
23975 set_decl_tls_model (v, decl_default_tls_model (v));
23976 /* If rtl has been already set for this var, call
23977 make_decl_rtl once again, so that encode_section_info
23978 has a chance to look at the new decl flags. */
23979 if (DECL_RTL_SET_P (v))
23980 make_decl_rtl (v);
23981 }
23982 C_DECL_THREADPRIVATE_P (v) = 1;
23983 }
23984 }
23985
23986 c_parser_skip_to_pragma_eol (parser);
23987 }
23988
23989 /* Parse a transaction attribute (GCC Extension).
23990
23991 transaction-attribute:
23992 gnu-attributes
23993 attribute-specifier
23994 */
23995
23996 static tree
23997 c_parser_transaction_attributes (c_parser *parser)
23998 {
23999 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
24000 return c_parser_gnu_attributes (parser);
24001
24002 if (!c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
24003 return NULL_TREE;
24004 return c_parser_std_attribute_specifier (parser, true);
24005 }
24006
24007 /* Parse a __transaction_atomic or __transaction_relaxed statement
24008 (GCC Extension).
24009
24010 transaction-statement:
24011 __transaction_atomic transaction-attribute[opt] compound-statement
24012 __transaction_relaxed compound-statement
24013
24014 Note that the only valid attribute is: "outer".
24015 */
24016
24017 static tree
24018 c_parser_transaction (c_parser *parser, enum rid keyword)
24019 {
24020 unsigned int old_in = parser->in_transaction;
24021 unsigned int this_in = 1, new_in;
24022 location_t loc = c_parser_peek_token (parser)->location;
24023 tree stmt, attrs;
24024
24025 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
24026 || keyword == RID_TRANSACTION_RELAXED)
24027 && c_parser_next_token_is_keyword (parser, keyword));
24028 c_parser_consume_token (parser);
24029
24030 if (keyword == RID_TRANSACTION_RELAXED)
24031 this_in |= TM_STMT_ATTR_RELAXED;
24032 else
24033 {
24034 attrs = c_parser_transaction_attributes (parser);
24035 if (attrs)
24036 this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
24037 }
24038
24039 /* Keep track if we're in the lexical scope of an outer transaction. */
24040 new_in = this_in | (old_in & TM_STMT_ATTR_OUTER);
24041
24042 parser->in_transaction = new_in;
24043 stmt = c_parser_compound_statement (parser);
24044 parser->in_transaction = old_in;
24045
24046 if (flag_tm)
24047 stmt = c_finish_transaction (loc, stmt, this_in);
24048 else
24049 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
24050 "%<__transaction_atomic%> without transactional memory support enabled"
24051 : "%<__transaction_relaxed %> "
24052 "without transactional memory support enabled"));
24053
24054 return stmt;
24055 }
24056
24057 /* Parse a __transaction_atomic or __transaction_relaxed expression
24058 (GCC Extension).
24059
24060 transaction-expression:
24061 __transaction_atomic ( expression )
24062 __transaction_relaxed ( expression )
24063 */
24064
24065 static struct c_expr
24066 c_parser_transaction_expression (c_parser *parser, enum rid keyword)
24067 {
24068 struct c_expr ret;
24069 unsigned int old_in = parser->in_transaction;
24070 unsigned int this_in = 1;
24071 location_t loc = c_parser_peek_token (parser)->location;
24072 tree attrs;
24073
24074 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
24075 || keyword == RID_TRANSACTION_RELAXED)
24076 && c_parser_next_token_is_keyword (parser, keyword));
24077 c_parser_consume_token (parser);
24078
24079 if (keyword == RID_TRANSACTION_RELAXED)
24080 this_in |= TM_STMT_ATTR_RELAXED;
24081 else
24082 {
24083 attrs = c_parser_transaction_attributes (parser);
24084 if (attrs)
24085 this_in |= parse_tm_stmt_attr (attrs, 0);
24086 }
24087
24088 parser->in_transaction = this_in;
24089 matching_parens parens;
24090 if (parens.require_open (parser))
24091 {
24092 tree expr = c_parser_expression (parser).value;
24093 ret.original_type = TREE_TYPE (expr);
24094 ret.value = build1 (TRANSACTION_EXPR, ret.original_type, expr);
24095 if (this_in & TM_STMT_ATTR_RELAXED)
24096 TRANSACTION_EXPR_RELAXED (ret.value) = 1;
24097 SET_EXPR_LOCATION (ret.value, loc);
24098 ret.original_code = TRANSACTION_EXPR;
24099 ret.m_decimal = 0;
24100 if (!parens.require_close (parser))
24101 {
24102 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
24103 goto error;
24104 }
24105 }
24106 else
24107 {
24108 error:
24109 ret.set_error ();
24110 ret.original_code = ERROR_MARK;
24111 ret.original_type = NULL;
24112 }
24113 parser->in_transaction = old_in;
24114
24115 if (!flag_tm)
24116 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
24117 "%<__transaction_atomic%> without transactional memory support enabled"
24118 : "%<__transaction_relaxed %> "
24119 "without transactional memory support enabled"));
24120
24121 set_c_expr_source_range (&ret, loc, loc);
24122
24123 return ret;
24124 }
24125
24126 /* Parse a __transaction_cancel statement (GCC Extension).
24127
24128 transaction-cancel-statement:
24129 __transaction_cancel transaction-attribute[opt] ;
24130
24131 Note that the only valid attribute is "outer".
24132 */
24133
24134 static tree
24135 c_parser_transaction_cancel (c_parser *parser)
24136 {
24137 location_t loc = c_parser_peek_token (parser)->location;
24138 tree attrs;
24139 bool is_outer = false;
24140
24141 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TRANSACTION_CANCEL));
24142 c_parser_consume_token (parser);
24143
24144 attrs = c_parser_transaction_attributes (parser);
24145 if (attrs)
24146 is_outer = (parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER) != 0);
24147
24148 if (!flag_tm)
24149 {
24150 error_at (loc, "%<__transaction_cancel%> without "
24151 "transactional memory support enabled");
24152 goto ret_error;
24153 }
24154 else if (parser->in_transaction & TM_STMT_ATTR_RELAXED)
24155 {
24156 error_at (loc, "%<__transaction_cancel%> within a "
24157 "%<__transaction_relaxed%>");
24158 goto ret_error;
24159 }
24160 else if (is_outer)
24161 {
24162 if ((parser->in_transaction & TM_STMT_ATTR_OUTER) == 0
24163 && !is_tm_may_cancel_outer (current_function_decl))
24164 {
24165 error_at (loc, "outer %<__transaction_cancel%> not "
24166 "within outer %<__transaction_atomic%> or "
24167 "a %<transaction_may_cancel_outer%> function");
24168 goto ret_error;
24169 }
24170 }
24171 else if (parser->in_transaction == 0)
24172 {
24173 error_at (loc, "%<__transaction_cancel%> not within "
24174 "%<__transaction_atomic%>");
24175 goto ret_error;
24176 }
24177
24178 return add_stmt (build_tm_abort_call (loc, is_outer));
24179
24180 ret_error:
24181 return build1 (NOP_EXPR, void_type_node, error_mark_node);
24182 }
24183 \f
24184 /* Parse a single source file. */
24185
24186 void
24187 c_parse_file (void)
24188 {
24189 /* Use local storage to begin. If the first token is a pragma, parse it.
24190 If it is #pragma GCC pch_preprocess, then this will load a PCH file
24191 which will cause garbage collection. */
24192 c_parser tparser;
24193
24194 memset (&tparser, 0, sizeof tparser);
24195 tparser.translate_strings_p = true;
24196 tparser.tokens = &tparser.tokens_buf[0];
24197 the_parser = &tparser;
24198
24199 if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS)
24200 c_parser_pragma_pch_preprocess (&tparser);
24201 else
24202 c_common_no_more_pch ();
24203
24204 the_parser = ggc_alloc<c_parser> ();
24205 *the_parser = tparser;
24206 if (tparser.tokens == &tparser.tokens_buf[0])
24207 the_parser->tokens = &the_parser->tokens_buf[0];
24208
24209 /* Initialize EH, if we've been told to do so. */
24210 if (flag_exceptions)
24211 using_eh_for_cleanups ();
24212
24213 c_parser_translation_unit (the_parser);
24214 the_parser = NULL;
24215 }
24216
24217 /* Parse the body of a function declaration marked with "__RTL".
24218
24219 The RTL parser works on the level of characters read from a
24220 FILE *, whereas c_parser works at the level of tokens.
24221 Square this circle by consuming all of the tokens up to and
24222 including the closing brace, recording the start/end of the RTL
24223 fragment, and reopening the file and re-reading the relevant
24224 lines within the RTL parser.
24225
24226 This requires the opening and closing braces of the C function
24227 to be on separate lines from the RTL they wrap.
24228
24229 Take ownership of START_WITH_PASS, if non-NULL. */
24230
24231 location_t
24232 c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass)
24233 {
24234 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
24235 {
24236 free (start_with_pass);
24237 return c_parser_peek_token (parser)->location;
24238 }
24239
24240 location_t start_loc = c_parser_peek_token (parser)->location;
24241
24242 /* Consume all tokens, up to the closing brace, handling
24243 matching pairs of braces in the rtl dump. */
24244 int num_open_braces = 1;
24245 while (1)
24246 {
24247 switch (c_parser_peek_token (parser)->type)
24248 {
24249 case CPP_OPEN_BRACE:
24250 num_open_braces++;
24251 break;
24252 case CPP_CLOSE_BRACE:
24253 if (--num_open_braces == 0)
24254 goto found_closing_brace;
24255 break;
24256 case CPP_EOF:
24257 error_at (start_loc, "no closing brace");
24258 free (start_with_pass);
24259 return c_parser_peek_token (parser)->location;
24260 default:
24261 break;
24262 }
24263 c_parser_consume_token (parser);
24264 }
24265
24266 found_closing_brace:
24267 /* At the closing brace; record its location. */
24268 location_t end_loc = c_parser_peek_token (parser)->location;
24269
24270 /* Consume the closing brace. */
24271 c_parser_consume_token (parser);
24272
24273 /* Invoke the RTL parser. */
24274 if (!read_rtl_function_body_from_file_range (start_loc, end_loc))
24275 {
24276 free (start_with_pass);
24277 return end_loc;
24278 }
24279
24280 /* Run the backend on the cfun created above, transferring ownership of
24281 START_WITH_PASS. */
24282 run_rtl_passes (start_with_pass);
24283 return end_loc;
24284 }
24285
24286 #include "gt-c-c-parser.h"