]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/c/c-parser.cc
c: Fix location for _Pragma tokens [PR97498]
[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
75 /* We need to walk over decls with incomplete struct/union/enum types
76 after parsing the whole translation unit.
77 In finish_decl(), if the decl is static, has incomplete
78 struct/union/enum type, it is appended to incomplete_record_decls.
79 In c_parser_translation_unit(), we iterate over incomplete_record_decls
80 and report error if any of the decls are still incomplete. */
81
82 vec<tree> incomplete_record_decls;
83
84 void
85 set_c_expr_source_range (c_expr *expr,
86 location_t start, location_t finish)
87 {
88 expr->src_range.m_start = start;
89 expr->src_range.m_finish = finish;
90 if (expr->value)
91 set_source_range (expr->value, start, finish);
92 }
93
94 void
95 set_c_expr_source_range (c_expr *expr,
96 source_range src_range)
97 {
98 expr->src_range = src_range;
99 if (expr->value)
100 set_source_range (expr->value, src_range);
101 }
102
103 \f
104 /* Initialization routine for this file. */
105
106 void
107 c_parse_init (void)
108 {
109 /* The only initialization required is of the reserved word
110 identifiers. */
111 unsigned int i;
112 tree id;
113 int mask = 0;
114
115 /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in
116 the c_token structure. */
117 gcc_assert (RID_MAX <= 255);
118
119 mask |= D_CXXONLY;
120 if (!flag_isoc99)
121 mask |= D_C99;
122 if (flag_no_asm)
123 {
124 mask |= D_ASM | D_EXT;
125 if (!flag_isoc99)
126 mask |= D_EXT89;
127 }
128 if (!c_dialect_objc ())
129 mask |= D_OBJC | D_CXX_OBJC;
130
131 ridpointers = ggc_cleared_vec_alloc<tree> ((int) RID_MAX);
132 for (i = 0; i < num_c_common_reswords; i++)
133 {
134 /* If a keyword is disabled, do not enter it into the table
135 and so create a canonical spelling that isn't a keyword. */
136 if (c_common_reswords[i].disable & mask)
137 {
138 if (warn_cxx_compat
139 && (c_common_reswords[i].disable & D_CXXWARN))
140 {
141 id = get_identifier (c_common_reswords[i].word);
142 C_SET_RID_CODE (id, RID_CXX_COMPAT_WARN);
143 C_IS_RESERVED_WORD (id) = 1;
144 }
145 continue;
146 }
147
148 id = get_identifier (c_common_reswords[i].word);
149 C_SET_RID_CODE (id, c_common_reswords[i].rid);
150 C_IS_RESERVED_WORD (id) = 1;
151 ridpointers [(int) c_common_reswords[i].rid] = id;
152 }
153
154 for (i = 0; i < NUM_INT_N_ENTS; i++)
155 {
156 /* We always create the symbols but they aren't always supported. */
157 char name[50];
158 sprintf (name, "__int%d", int_n_data[i].bitsize);
159 id = get_identifier (name);
160 C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
161 C_IS_RESERVED_WORD (id) = 1;
162
163 sprintf (name, "__int%d__", int_n_data[i].bitsize);
164 id = get_identifier (name);
165 C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
166 C_IS_RESERVED_WORD (id) = 1;
167 }
168 }
169 \f
170 /* A parser structure recording information about the state and
171 context of parsing. Includes lexer information with up to two
172 tokens of look-ahead; more are not needed for C. */
173 struct GTY(()) c_parser {
174 /* The look-ahead tokens. */
175 c_token * GTY((skip)) tokens;
176 /* Buffer for look-ahead tokens. */
177 c_token tokens_buf[4];
178 /* How many look-ahead tokens are available (0 - 4, or
179 more if parsing from pre-lexed tokens). */
180 unsigned int tokens_avail;
181 /* Raw look-ahead tokens, used only for checking in Objective-C
182 whether '[[' starts attributes. */
183 vec<c_token, va_gc> *raw_tokens;
184 /* The number of raw look-ahead tokens that have since been fully
185 lexed. */
186 unsigned int raw_tokens_used;
187 /* True if a syntax error is being recovered from; false otherwise.
188 c_parser_error sets this flag. It should clear this flag when
189 enough tokens have been consumed to recover from the error. */
190 BOOL_BITFIELD error : 1;
191 /* True if we're processing a pragma, and shouldn't automatically
192 consume CPP_PRAGMA_EOL. */
193 BOOL_BITFIELD in_pragma : 1;
194 /* True if we're parsing the outermost block of an if statement. */
195 BOOL_BITFIELD in_if_block : 1;
196 /* True if we want to lex a translated, joined string (for an
197 initial #pragma pch_preprocess). Otherwise the parser is
198 responsible for concatenating strings and translating to the
199 execution character set as needed. */
200 BOOL_BITFIELD lex_joined_string : 1;
201 /* True if, when the parser is concatenating string literals, it
202 should translate them to the execution character set (false
203 inside attributes). */
204 BOOL_BITFIELD translate_strings_p : 1;
205
206 /* Objective-C specific parser/lexer information. */
207
208 /* True if we are in a context where the Objective-C "PQ" keywords
209 are considered keywords. */
210 BOOL_BITFIELD objc_pq_context : 1;
211 /* True if we are parsing a (potential) Objective-C foreach
212 statement. This is set to true after we parsed 'for (' and while
213 we wait for 'in' or ';' to decide if it's a standard C for loop or an
214 Objective-C foreach loop. */
215 BOOL_BITFIELD objc_could_be_foreach_context : 1;
216 /* The following flag is needed to contextualize Objective-C lexical
217 analysis. In some cases (e.g., 'int NSObject;'), it is
218 undesirable to bind an identifier to an Objective-C class, even
219 if a class with that name exists. */
220 BOOL_BITFIELD objc_need_raw_identifier : 1;
221 /* Nonzero if we're processing a __transaction statement. The value
222 is 1 | TM_STMT_ATTR_*. */
223 unsigned int in_transaction : 4;
224 /* True if we are in a context where the Objective-C "Property attribute"
225 keywords are valid. */
226 BOOL_BITFIELD objc_property_attr_context : 1;
227
228 /* Whether we have just seen/constructed a string-literal. Set when
229 returning a string-literal from c_parser_string_literal. Reset
230 in consume_token. Useful when we get a parse error and see an
231 unknown token, which could have been a string-literal constant
232 macro. */
233 BOOL_BITFIELD seen_string_literal : 1;
234
235 /* Location of the last consumed token. */
236 location_t last_token_location;
237 };
238
239 /* Return a pointer to the Nth token in PARSERs tokens_buf. */
240
241 c_token *
242 c_parser_tokens_buf (c_parser *parser, unsigned n)
243 {
244 return &parser->tokens_buf[n];
245 }
246
247 /* Return the error state of PARSER. */
248
249 bool
250 c_parser_error (c_parser *parser)
251 {
252 return parser->error;
253 }
254
255 /* Set the error state of PARSER to ERR. */
256
257 void
258 c_parser_set_error (c_parser *parser, bool err)
259 {
260 parser->error = err;
261 }
262
263
264 /* The actual parser and external interface. ??? Does this need to be
265 garbage-collected? */
266
267 static GTY (()) c_parser *the_parser;
268
269 /* Read in and lex a single token, storing it in *TOKEN. If RAW,
270 context-sensitive postprocessing of the token is not done. */
271
272 static void
273 c_lex_one_token (c_parser *parser, c_token *token, bool raw = false)
274 {
275 timevar_push (TV_LEX);
276
277 if (raw || vec_safe_length (parser->raw_tokens) == 0)
278 {
279 token->type = c_lex_with_flags (&token->value, &token->location,
280 &token->flags,
281 (parser->lex_joined_string
282 ? 0 : C_LEX_STRING_NO_JOIN));
283 token->id_kind = C_ID_NONE;
284 token->keyword = RID_MAX;
285 token->pragma_kind = PRAGMA_NONE;
286 }
287 else
288 {
289 /* Use a token previously lexed as a raw look-ahead token, and
290 complete the processing on it. */
291 *token = (*parser->raw_tokens)[parser->raw_tokens_used];
292 ++parser->raw_tokens_used;
293 if (parser->raw_tokens_used == vec_safe_length (parser->raw_tokens))
294 {
295 vec_free (parser->raw_tokens);
296 parser->raw_tokens_used = 0;
297 }
298 }
299
300 if (raw)
301 goto out;
302
303 switch (token->type)
304 {
305 case CPP_NAME:
306 {
307 tree decl;
308
309 bool objc_force_identifier = parser->objc_need_raw_identifier;
310 if (c_dialect_objc ())
311 parser->objc_need_raw_identifier = false;
312
313 if (C_IS_RESERVED_WORD (token->value))
314 {
315 enum rid rid_code = C_RID_CODE (token->value);
316
317 if (rid_code == RID_CXX_COMPAT_WARN)
318 {
319 warning_at (token->location,
320 OPT_Wc___compat,
321 "identifier %qE conflicts with C++ keyword",
322 token->value);
323 }
324 else if (rid_code >= RID_FIRST_ADDR_SPACE
325 && rid_code <= RID_LAST_ADDR_SPACE)
326 {
327 addr_space_t as;
328 as = (addr_space_t) (rid_code - RID_FIRST_ADDR_SPACE);
329 targetm.addr_space.diagnose_usage (as, token->location);
330 token->id_kind = C_ID_ADDRSPACE;
331 token->keyword = rid_code;
332 break;
333 }
334 else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code))
335 {
336 /* We found an Objective-C "pq" keyword (in, out,
337 inout, bycopy, byref, oneway). They need special
338 care because the interpretation depends on the
339 context. */
340 if (parser->objc_pq_context)
341 {
342 token->type = CPP_KEYWORD;
343 token->keyword = rid_code;
344 break;
345 }
346 else if (parser->objc_could_be_foreach_context
347 && rid_code == RID_IN)
348 {
349 /* We are in Objective-C, inside a (potential)
350 foreach context (which means after having
351 parsed 'for (', but before having parsed ';'),
352 and we found 'in'. We consider it the keyword
353 which terminates the declaration at the
354 beginning of a foreach-statement. Note that
355 this means you can't use 'in' for anything else
356 in that context; in particular, in Objective-C
357 you can't use 'in' as the name of the running
358 variable in a C for loop. We could potentially
359 try to add code here to disambiguate, but it
360 seems a reasonable limitation. */
361 token->type = CPP_KEYWORD;
362 token->keyword = rid_code;
363 break;
364 }
365 /* Else, "pq" keywords outside of the "pq" context are
366 not keywords, and we fall through to the code for
367 normal tokens. */
368 }
369 else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code))
370 {
371 /* We found an Objective-C "property attribute"
372 keyword (getter, setter, readonly, etc). These are
373 only valid in the property context. */
374 if (parser->objc_property_attr_context)
375 {
376 token->type = CPP_KEYWORD;
377 token->keyword = rid_code;
378 break;
379 }
380 /* Else they are not special keywords.
381 */
382 }
383 else if (c_dialect_objc ()
384 && (OBJC_IS_AT_KEYWORD (rid_code)
385 || OBJC_IS_CXX_KEYWORD (rid_code)))
386 {
387 /* We found one of the Objective-C "@" keywords (defs,
388 selector, synchronized, etc) or one of the
389 Objective-C "cxx" keywords (class, private,
390 protected, public, try, catch, throw) without a
391 preceding '@' sign. Do nothing and fall through to
392 the code for normal tokens (in C++ we would still
393 consider the CXX ones keywords, but not in C). */
394 ;
395 }
396 else
397 {
398 token->type = CPP_KEYWORD;
399 token->keyword = rid_code;
400 break;
401 }
402 }
403
404 decl = lookup_name (token->value);
405 if (decl)
406 {
407 if (TREE_CODE (decl) == TYPE_DECL)
408 {
409 token->id_kind = C_ID_TYPENAME;
410 break;
411 }
412 }
413 else if (c_dialect_objc ())
414 {
415 tree objc_interface_decl = objc_is_class_name (token->value);
416 /* Objective-C class names are in the same namespace as
417 variables and typedefs, and hence are shadowed by local
418 declarations. */
419 if (objc_interface_decl
420 && (!objc_force_identifier || global_bindings_p ()))
421 {
422 token->value = objc_interface_decl;
423 token->id_kind = C_ID_CLASSNAME;
424 break;
425 }
426 }
427 token->id_kind = C_ID_ID;
428 }
429 break;
430 case CPP_AT_NAME:
431 /* This only happens in Objective-C; it must be a keyword. */
432 token->type = CPP_KEYWORD;
433 switch (C_RID_CODE (token->value))
434 {
435 /* Replace 'class' with '@class', 'private' with '@private',
436 etc. This prevents confusion with the C++ keyword
437 'class', and makes the tokens consistent with other
438 Objective-C 'AT' keywords. For example '@class' is
439 reported as RID_AT_CLASS which is consistent with
440 '@synchronized', which is reported as
441 RID_AT_SYNCHRONIZED.
442 */
443 case RID_CLASS: token->keyword = RID_AT_CLASS; break;
444 case RID_PRIVATE: token->keyword = RID_AT_PRIVATE; break;
445 case RID_PROTECTED: token->keyword = RID_AT_PROTECTED; break;
446 case RID_PUBLIC: token->keyword = RID_AT_PUBLIC; break;
447 case RID_THROW: token->keyword = RID_AT_THROW; break;
448 case RID_TRY: token->keyword = RID_AT_TRY; break;
449 case RID_CATCH: token->keyword = RID_AT_CATCH; break;
450 case RID_SYNCHRONIZED: token->keyword = RID_AT_SYNCHRONIZED; break;
451 default: token->keyword = C_RID_CODE (token->value);
452 }
453 break;
454 case CPP_COLON:
455 case CPP_COMMA:
456 case CPP_CLOSE_PAREN:
457 case CPP_SEMICOLON:
458 /* These tokens may affect the interpretation of any identifiers
459 following, if doing Objective-C. */
460 if (c_dialect_objc ())
461 parser->objc_need_raw_identifier = false;
462 break;
463 case CPP_PRAGMA:
464 /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */
465 token->pragma_kind = (enum pragma_kind) TREE_INT_CST_LOW (token->value);
466 token->value = NULL;
467 break;
468 default:
469 break;
470 }
471 out:
472 timevar_pop (TV_LEX);
473 }
474
475 /* Return a pointer to the next token from PARSER, reading it in if
476 necessary. */
477
478 c_token *
479 c_parser_peek_token (c_parser *parser)
480 {
481 if (parser->tokens_avail == 0)
482 {
483 c_lex_one_token (parser, &parser->tokens[0]);
484 parser->tokens_avail = 1;
485 }
486 return &parser->tokens[0];
487 }
488
489 /* Return a pointer to the next-but-one token from PARSER, reading it
490 in if necessary. The next token is already read in. */
491
492 c_token *
493 c_parser_peek_2nd_token (c_parser *parser)
494 {
495 if (parser->tokens_avail >= 2)
496 return &parser->tokens[1];
497 gcc_assert (parser->tokens_avail == 1);
498 gcc_assert (parser->tokens[0].type != CPP_EOF);
499 gcc_assert (parser->tokens[0].type != CPP_PRAGMA_EOL);
500 c_lex_one_token (parser, &parser->tokens[1]);
501 parser->tokens_avail = 2;
502 return &parser->tokens[1];
503 }
504
505 /* Return a pointer to the Nth token from PARSER, reading it
506 in if necessary. The N-1th token is already read in. */
507
508 c_token *
509 c_parser_peek_nth_token (c_parser *parser, unsigned int n)
510 {
511 /* N is 1-based, not zero-based. */
512 gcc_assert (n > 0);
513
514 if (parser->tokens_avail >= n)
515 return &parser->tokens[n - 1];
516 gcc_assert (parser->tokens_avail == n - 1);
517 c_lex_one_token (parser, &parser->tokens[n - 1]);
518 parser->tokens_avail = n;
519 return &parser->tokens[n - 1];
520 }
521
522 /* Return a pointer to the Nth token from PARSER, reading it in as a
523 raw look-ahead token if necessary. The N-1th token is already read
524 in. Raw look-ahead tokens remain available for when the non-raw
525 functions above are called. */
526
527 c_token *
528 c_parser_peek_nth_token_raw (c_parser *parser, unsigned int n)
529 {
530 /* N is 1-based, not zero-based. */
531 gcc_assert (n > 0);
532
533 if (parser->tokens_avail >= n)
534 return &parser->tokens[n - 1];
535 unsigned int raw_len = vec_safe_length (parser->raw_tokens);
536 unsigned int raw_avail
537 = parser->tokens_avail + raw_len - parser->raw_tokens_used;
538 gcc_assert (raw_avail >= n - 1);
539 if (raw_avail >= n)
540 return &(*parser->raw_tokens)[parser->raw_tokens_used
541 + n - 1 - parser->tokens_avail];
542 vec_safe_reserve (parser->raw_tokens, 1);
543 parser->raw_tokens->quick_grow (raw_len + 1);
544 c_lex_one_token (parser, &(*parser->raw_tokens)[raw_len], true);
545 return &(*parser->raw_tokens)[raw_len];
546 }
547
548 bool
549 c_keyword_starts_typename (enum rid keyword)
550 {
551 switch (keyword)
552 {
553 case RID_UNSIGNED:
554 case RID_LONG:
555 case RID_SHORT:
556 case RID_SIGNED:
557 case RID_COMPLEX:
558 case RID_INT:
559 case RID_CHAR:
560 case RID_FLOAT:
561 case RID_DOUBLE:
562 case RID_VOID:
563 case RID_DFLOAT32:
564 case RID_DFLOAT64:
565 case RID_DFLOAT128:
566 CASE_RID_FLOATN_NX:
567 case RID_BOOL:
568 case RID_ENUM:
569 case RID_STRUCT:
570 case RID_UNION:
571 case RID_TYPEOF:
572 case RID_CONST:
573 case RID_ATOMIC:
574 case RID_VOLATILE:
575 case RID_RESTRICT:
576 case RID_ATTRIBUTE:
577 case RID_FRACT:
578 case RID_ACCUM:
579 case RID_SAT:
580 case RID_AUTO_TYPE:
581 case RID_ALIGNAS:
582 return true;
583 default:
584 if (keyword >= RID_FIRST_INT_N
585 && keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
586 && int_n_enabled_p[keyword - RID_FIRST_INT_N])
587 return true;
588 return false;
589 }
590 }
591
592 /* Return true if TOKEN can start a type name,
593 false otherwise. */
594 bool
595 c_token_starts_typename (c_token *token)
596 {
597 switch (token->type)
598 {
599 case CPP_NAME:
600 switch (token->id_kind)
601 {
602 case C_ID_ID:
603 return false;
604 case C_ID_ADDRSPACE:
605 return true;
606 case C_ID_TYPENAME:
607 return true;
608 case C_ID_CLASSNAME:
609 gcc_assert (c_dialect_objc ());
610 return true;
611 default:
612 gcc_unreachable ();
613 }
614 case CPP_KEYWORD:
615 return c_keyword_starts_typename (token->keyword);
616 case CPP_LESS:
617 if (c_dialect_objc ())
618 return true;
619 return false;
620 default:
621 return false;
622 }
623 }
624
625 /* Return true if the next token from PARSER can start a type name,
626 false otherwise. LA specifies how to do lookahead in order to
627 detect unknown type names. If unsure, pick CLA_PREFER_ID. */
628
629 static inline bool
630 c_parser_next_tokens_start_typename (c_parser *parser, enum c_lookahead_kind la)
631 {
632 c_token *token = c_parser_peek_token (parser);
633 if (c_token_starts_typename (token))
634 return true;
635
636 /* Try a bit harder to detect an unknown typename. */
637 if (la != cla_prefer_id
638 && token->type == CPP_NAME
639 && token->id_kind == C_ID_ID
640
641 /* Do not try too hard when we could have "object in array". */
642 && !parser->objc_could_be_foreach_context
643
644 && (la == cla_prefer_type
645 || c_parser_peek_2nd_token (parser)->type == CPP_NAME
646 || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
647
648 /* Only unknown identifiers. */
649 && !lookup_name (token->value))
650 return true;
651
652 return false;
653 }
654
655 /* Return true if TOKEN is a type qualifier, false otherwise. */
656 static bool
657 c_token_is_qualifier (c_token *token)
658 {
659 switch (token->type)
660 {
661 case CPP_NAME:
662 switch (token->id_kind)
663 {
664 case C_ID_ADDRSPACE:
665 return true;
666 default:
667 return false;
668 }
669 case CPP_KEYWORD:
670 switch (token->keyword)
671 {
672 case RID_CONST:
673 case RID_VOLATILE:
674 case RID_RESTRICT:
675 case RID_ATTRIBUTE:
676 case RID_ATOMIC:
677 return true;
678 default:
679 return false;
680 }
681 case CPP_LESS:
682 return false;
683 default:
684 gcc_unreachable ();
685 }
686 }
687
688 /* Return true if the next token from PARSER is a type qualifier,
689 false otherwise. */
690 static inline bool
691 c_parser_next_token_is_qualifier (c_parser *parser)
692 {
693 c_token *token = c_parser_peek_token (parser);
694 return c_token_is_qualifier (token);
695 }
696
697 /* Return true if TOKEN can start declaration specifiers (not
698 including standard attributes), false otherwise. */
699 static bool
700 c_token_starts_declspecs (c_token *token)
701 {
702 switch (token->type)
703 {
704 case CPP_NAME:
705 switch (token->id_kind)
706 {
707 case C_ID_ID:
708 return false;
709 case C_ID_ADDRSPACE:
710 return true;
711 case C_ID_TYPENAME:
712 return true;
713 case C_ID_CLASSNAME:
714 gcc_assert (c_dialect_objc ());
715 return true;
716 default:
717 gcc_unreachable ();
718 }
719 case CPP_KEYWORD:
720 switch (token->keyword)
721 {
722 case RID_STATIC:
723 case RID_EXTERN:
724 case RID_REGISTER:
725 case RID_TYPEDEF:
726 case RID_INLINE:
727 case RID_NORETURN:
728 case RID_AUTO:
729 case RID_THREAD:
730 case RID_UNSIGNED:
731 case RID_LONG:
732 case RID_SHORT:
733 case RID_SIGNED:
734 case RID_COMPLEX:
735 case RID_INT:
736 case RID_CHAR:
737 case RID_FLOAT:
738 case RID_DOUBLE:
739 case RID_VOID:
740 case RID_DFLOAT32:
741 case RID_DFLOAT64:
742 case RID_DFLOAT128:
743 CASE_RID_FLOATN_NX:
744 case RID_BOOL:
745 case RID_ENUM:
746 case RID_STRUCT:
747 case RID_UNION:
748 case RID_TYPEOF:
749 case RID_CONST:
750 case RID_VOLATILE:
751 case RID_RESTRICT:
752 case RID_ATTRIBUTE:
753 case RID_FRACT:
754 case RID_ACCUM:
755 case RID_SAT:
756 case RID_ALIGNAS:
757 case RID_ATOMIC:
758 case RID_AUTO_TYPE:
759 return true;
760 default:
761 if (token->keyword >= RID_FIRST_INT_N
762 && token->keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
763 && int_n_enabled_p[token->keyword - RID_FIRST_INT_N])
764 return true;
765 return false;
766 }
767 case CPP_LESS:
768 if (c_dialect_objc ())
769 return true;
770 return false;
771 default:
772 return false;
773 }
774 }
775
776
777 /* Return true if TOKEN can start declaration specifiers (not
778 including standard attributes) or a static assertion, false
779 otherwise. */
780 static bool
781 c_token_starts_declaration (c_token *token)
782 {
783 if (c_token_starts_declspecs (token)
784 || token->keyword == RID_STATIC_ASSERT)
785 return true;
786 else
787 return false;
788 }
789
790 /* Return true if the next token from PARSER can start declaration
791 specifiers (not including standard attributes), false
792 otherwise. */
793 bool
794 c_parser_next_token_starts_declspecs (c_parser *parser)
795 {
796 c_token *token = c_parser_peek_token (parser);
797
798 /* In Objective-C, a classname normally starts a declspecs unless it
799 is immediately followed by a dot. In that case, it is the
800 Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
801 setter/getter on the class. c_token_starts_declspecs() can't
802 differentiate between the two cases because it only checks the
803 current token, so we have a special check here. */
804 if (c_dialect_objc ()
805 && token->type == CPP_NAME
806 && token->id_kind == C_ID_CLASSNAME
807 && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
808 return false;
809
810 return c_token_starts_declspecs (token);
811 }
812
813 /* Return true if the next tokens from PARSER can start declaration
814 specifiers (not including standard attributes) or a static
815 assertion, false otherwise. */
816 bool
817 c_parser_next_tokens_start_declaration (c_parser *parser)
818 {
819 c_token *token = c_parser_peek_token (parser);
820
821 /* Same as above. */
822 if (c_dialect_objc ()
823 && token->type == CPP_NAME
824 && token->id_kind == C_ID_CLASSNAME
825 && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
826 return false;
827
828 /* Labels do not start declarations. */
829 if (token->type == CPP_NAME
830 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
831 return false;
832
833 if (c_token_starts_declaration (token))
834 return true;
835
836 if (c_parser_next_tokens_start_typename (parser, cla_nonabstract_decl))
837 return true;
838
839 return false;
840 }
841
842 /* Consume the next token from PARSER. */
843
844 void
845 c_parser_consume_token (c_parser *parser)
846 {
847 gcc_assert (parser->tokens_avail >= 1);
848 gcc_assert (parser->tokens[0].type != CPP_EOF);
849 gcc_assert (!parser->in_pragma || parser->tokens[0].type != CPP_PRAGMA_EOL);
850 gcc_assert (parser->error || parser->tokens[0].type != CPP_PRAGMA);
851 parser->last_token_location = parser->tokens[0].location;
852 if (parser->tokens != &parser->tokens_buf[0])
853 parser->tokens++;
854 else if (parser->tokens_avail >= 2)
855 {
856 parser->tokens[0] = parser->tokens[1];
857 if (parser->tokens_avail >= 3)
858 {
859 parser->tokens[1] = parser->tokens[2];
860 if (parser->tokens_avail >= 4)
861 parser->tokens[2] = parser->tokens[3];
862 }
863 }
864 parser->tokens_avail--;
865 parser->seen_string_literal = false;
866 }
867
868 /* Expect the current token to be a #pragma. Consume it and remember
869 that we've begun parsing a pragma. */
870
871 static void
872 c_parser_consume_pragma (c_parser *parser)
873 {
874 gcc_assert (!parser->in_pragma);
875 gcc_assert (parser->tokens_avail >= 1);
876 gcc_assert (parser->tokens[0].type == CPP_PRAGMA);
877 if (parser->tokens != &parser->tokens_buf[0])
878 parser->tokens++;
879 else if (parser->tokens_avail >= 2)
880 {
881 parser->tokens[0] = parser->tokens[1];
882 if (parser->tokens_avail >= 3)
883 parser->tokens[1] = parser->tokens[2];
884 }
885 parser->tokens_avail--;
886 parser->in_pragma = true;
887 }
888
889 /* Update the global input_location from TOKEN. */
890 static inline void
891 c_parser_set_source_position_from_token (c_token *token)
892 {
893 if (token->type != CPP_EOF)
894 {
895 input_location = token->location;
896 }
897 }
898
899 /* Helper function for c_parser_error.
900 Having peeked a token of kind TOK1_KIND that might signify
901 a conflict marker, peek successor tokens to determine
902 if we actually do have a conflict marker.
903 Specifically, we consider a run of 7 '<', '=' or '>' characters
904 at the start of a line as a conflict marker.
905 These come through the lexer as three pairs and a single,
906 e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<').
907 If it returns true, *OUT_LOC is written to with the location/range
908 of the marker. */
909
910 static bool
911 c_parser_peek_conflict_marker (c_parser *parser, enum cpp_ttype tok1_kind,
912 location_t *out_loc)
913 {
914 c_token *token2 = c_parser_peek_2nd_token (parser);
915 if (token2->type != tok1_kind)
916 return false;
917 c_token *token3 = c_parser_peek_nth_token (parser, 3);
918 if (token3->type != tok1_kind)
919 return false;
920 c_token *token4 = c_parser_peek_nth_token (parser, 4);
921 if (token4->type != conflict_marker_get_final_tok_kind (tok1_kind))
922 return false;
923
924 /* It must be at the start of the line. */
925 location_t start_loc = c_parser_peek_token (parser)->location;
926 if (LOCATION_COLUMN (start_loc) != 1)
927 return false;
928
929 /* We have a conflict marker. Construct a location of the form:
930 <<<<<<<
931 ^~~~~~~
932 with start == caret, finishing at the end of the marker. */
933 location_t finish_loc = get_finish (token4->location);
934 *out_loc = make_location (start_loc, start_loc, finish_loc);
935
936 return true;
937 }
938
939 /* Issue a diagnostic of the form
940 FILE:LINE: MESSAGE before TOKEN
941 where TOKEN is the next token in the input stream of PARSER.
942 MESSAGE (specified by the caller) is usually of the form "expected
943 OTHER-TOKEN".
944
945 Use RICHLOC as the location of the diagnostic.
946
947 Do not issue a diagnostic if still recovering from an error.
948
949 Return true iff an error was actually emitted.
950
951 ??? This is taken from the C++ parser, but building up messages in
952 this way is not i18n-friendly and some other approach should be
953 used. */
954
955 static bool
956 c_parser_error_richloc (c_parser *parser, const char *gmsgid,
957 rich_location *richloc)
958 {
959 c_token *token = c_parser_peek_token (parser);
960 if (parser->error)
961 return false;
962 parser->error = true;
963 if (!gmsgid)
964 return false;
965
966 /* If this is actually a conflict marker, report it as such. */
967 if (token->type == CPP_LSHIFT
968 || token->type == CPP_RSHIFT
969 || token->type == CPP_EQ_EQ)
970 {
971 location_t loc;
972 if (c_parser_peek_conflict_marker (parser, token->type, &loc))
973 {
974 error_at (loc, "version control conflict marker in file");
975 return true;
976 }
977 }
978
979 /* If we were parsing a string-literal and there is an unknown name
980 token right after, then check to see if that could also have been
981 a literal string by checking the name against a list of known
982 standard string literal constants defined in header files. If
983 there is one, then add that as an hint to the error message. */
984 auto_diagnostic_group d;
985 name_hint h;
986 if (parser->seen_string_literal && token->type == CPP_NAME)
987 {
988 tree name = token->value;
989 const char *token_name = IDENTIFIER_POINTER (name);
990 const char *header_hint
991 = get_c_stdlib_header_for_string_macro_name (token_name);
992 if (header_hint != NULL)
993 h = name_hint (NULL, new suggest_missing_header (token->location,
994 token_name,
995 header_hint));
996 }
997
998 c_parse_error (gmsgid,
999 /* Because c_parse_error does not understand
1000 CPP_KEYWORD, keywords are treated like
1001 identifiers. */
1002 (token->type == CPP_KEYWORD ? CPP_NAME : token->type),
1003 /* ??? The C parser does not save the cpp flags of a
1004 token, we need to pass 0 here and we will not get
1005 the source spelling of some tokens but rather the
1006 canonical spelling. */
1007 token->value, /*flags=*/0, richloc);
1008 return true;
1009 }
1010
1011 /* As c_parser_error_richloc, but issue the message at the
1012 location of PARSER's next token, or at input_location
1013 if the next token is EOF. */
1014
1015 bool
1016 c_parser_error (c_parser *parser, const char *gmsgid)
1017 {
1018 c_token *token = c_parser_peek_token (parser);
1019 c_parser_set_source_position_from_token (token);
1020 rich_location richloc (line_table, input_location);
1021 return c_parser_error_richloc (parser, gmsgid, &richloc);
1022 }
1023
1024 /* Some tokens naturally come in pairs e.g.'(' and ')'.
1025 This class is for tracking such a matching pair of symbols.
1026 In particular, it tracks the location of the first token,
1027 so that if the second token is missing, we can highlight the
1028 location of the first token when notifying the user about the
1029 problem. */
1030
1031 template <typename traits_t>
1032 class token_pair
1033 {
1034 public:
1035 /* token_pair's ctor. */
1036 token_pair () : m_open_loc (UNKNOWN_LOCATION) {}
1037
1038 /* If the next token is the opening symbol for this pair, consume it and
1039 return true.
1040 Otherwise, issue an error and return false.
1041 In either case, record the location of the opening token. */
1042
1043 bool require_open (c_parser *parser)
1044 {
1045 c_token *token = c_parser_peek_token (parser);
1046 if (token)
1047 m_open_loc = token->location;
1048
1049 return c_parser_require (parser, traits_t::open_token_type,
1050 traits_t::open_gmsgid);
1051 }
1052
1053 /* Consume the next token from PARSER, recording its location as
1054 that of the opening token within the pair. */
1055
1056 void consume_open (c_parser *parser)
1057 {
1058 c_token *token = c_parser_peek_token (parser);
1059 gcc_assert (token->type == traits_t::open_token_type);
1060 m_open_loc = token->location;
1061 c_parser_consume_token (parser);
1062 }
1063
1064 /* If the next token is the closing symbol for this pair, consume it
1065 and return true.
1066 Otherwise, issue an error, highlighting the location of the
1067 corresponding opening token, and return false. */
1068
1069 bool require_close (c_parser *parser) const
1070 {
1071 return c_parser_require (parser, traits_t::close_token_type,
1072 traits_t::close_gmsgid, m_open_loc);
1073 }
1074
1075 /* Like token_pair::require_close, except that tokens will be skipped
1076 until the desired token is found. An error message is still produced
1077 if the next token is not as expected. */
1078
1079 void skip_until_found_close (c_parser *parser) const
1080 {
1081 c_parser_skip_until_found (parser, traits_t::close_token_type,
1082 traits_t::close_gmsgid, m_open_loc);
1083 }
1084
1085 private:
1086 location_t m_open_loc;
1087 };
1088
1089 /* Traits for token_pair<T> for tracking matching pairs of parentheses. */
1090
1091 struct matching_paren_traits
1092 {
1093 static const enum cpp_ttype open_token_type = CPP_OPEN_PAREN;
1094 static const char * const open_gmsgid;
1095 static const enum cpp_ttype close_token_type = CPP_CLOSE_PAREN;
1096 static const char * const close_gmsgid;
1097 };
1098
1099 const char * const matching_paren_traits::open_gmsgid = "expected %<(%>";
1100 const char * const matching_paren_traits::close_gmsgid = "expected %<)%>";
1101
1102 /* "matching_parens" is a token_pair<T> class for tracking matching
1103 pairs of parentheses. */
1104
1105 typedef token_pair<matching_paren_traits> matching_parens;
1106
1107 /* Traits for token_pair<T> for tracking matching pairs of braces. */
1108
1109 struct matching_brace_traits
1110 {
1111 static const enum cpp_ttype open_token_type = CPP_OPEN_BRACE;
1112 static const char * const open_gmsgid;
1113 static const enum cpp_ttype close_token_type = CPP_CLOSE_BRACE;
1114 static const char * const close_gmsgid;
1115 };
1116
1117 const char * const matching_brace_traits::open_gmsgid = "expected %<{%>";
1118 const char * const matching_brace_traits::close_gmsgid = "expected %<}%>";
1119
1120 /* "matching_braces" is a token_pair<T> class for tracking matching
1121 pairs of braces. */
1122
1123 typedef token_pair<matching_brace_traits> matching_braces;
1124
1125 /* Get a description of the matching symbol to TYPE e.g. "(" for
1126 CPP_CLOSE_PAREN. */
1127
1128 static const char *
1129 get_matching_symbol (enum cpp_ttype type)
1130 {
1131 switch (type)
1132 {
1133 default:
1134 gcc_unreachable ();
1135 case CPP_CLOSE_PAREN:
1136 return "(";
1137 case CPP_CLOSE_BRACE:
1138 return "{";
1139 }
1140 }
1141
1142 /* If the next token is of the indicated TYPE, consume it. Otherwise,
1143 issue the error MSGID. If MSGID is NULL then a message has already
1144 been produced and no message will be produced this time. Returns
1145 true if found, false otherwise.
1146
1147 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1148 within any error as the location of an "opening" token matching
1149 the close token TYPE (e.g. the location of the '(' when TYPE is
1150 CPP_CLOSE_PAREN).
1151
1152 If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly
1153 one type (e.g. "expected %<)%>") and thus it may be reasonable to
1154 attempt to generate a fix-it hint for the problem.
1155 Otherwise msgid describes multiple token types (e.g.
1156 "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to
1157 generate a fix-it hint. */
1158
1159 bool
1160 c_parser_require (c_parser *parser,
1161 enum cpp_ttype type,
1162 const char *msgid,
1163 location_t matching_location,
1164 bool type_is_unique)
1165 {
1166 if (c_parser_next_token_is (parser, type))
1167 {
1168 c_parser_consume_token (parser);
1169 return true;
1170 }
1171 else
1172 {
1173 location_t next_token_loc = c_parser_peek_token (parser)->location;
1174 gcc_rich_location richloc (next_token_loc);
1175
1176 /* Potentially supply a fix-it hint, suggesting to add the
1177 missing token immediately after the *previous* token.
1178 This may move the primary location within richloc. */
1179 if (!parser->error && type_is_unique)
1180 maybe_suggest_missing_token_insertion (&richloc, type,
1181 parser->last_token_location);
1182
1183 /* If matching_location != UNKNOWN_LOCATION, highlight it.
1184 Attempt to consolidate diagnostics by printing it as a
1185 secondary range within the main diagnostic. */
1186 bool added_matching_location = false;
1187 if (matching_location != UNKNOWN_LOCATION)
1188 added_matching_location
1189 = richloc.add_location_if_nearby (matching_location);
1190
1191 if (c_parser_error_richloc (parser, msgid, &richloc))
1192 /* If we weren't able to consolidate matching_location, then
1193 print it as a secondary diagnostic. */
1194 if (matching_location != UNKNOWN_LOCATION && !added_matching_location)
1195 inform (matching_location, "to match this %qs",
1196 get_matching_symbol (type));
1197
1198 return false;
1199 }
1200 }
1201
1202 /* If the next token is the indicated keyword, consume it. Otherwise,
1203 issue the error MSGID. Returns true if found, false otherwise. */
1204
1205 static bool
1206 c_parser_require_keyword (c_parser *parser,
1207 enum rid keyword,
1208 const char *msgid)
1209 {
1210 if (c_parser_next_token_is_keyword (parser, keyword))
1211 {
1212 c_parser_consume_token (parser);
1213 return true;
1214 }
1215 else
1216 {
1217 c_parser_error (parser, msgid);
1218 return false;
1219 }
1220 }
1221
1222 /* Like c_parser_require, except that tokens will be skipped until the
1223 desired token is found. An error message is still produced if the
1224 next token is not as expected. If MSGID is NULL then a message has
1225 already been produced and no message will be produced this
1226 time.
1227
1228 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1229 within any error as the location of an "opening" token matching
1230 the close token TYPE (e.g. the location of the '(' when TYPE is
1231 CPP_CLOSE_PAREN). */
1232
1233 void
1234 c_parser_skip_until_found (c_parser *parser,
1235 enum cpp_ttype type,
1236 const char *msgid,
1237 location_t matching_location)
1238 {
1239 unsigned nesting_depth = 0;
1240
1241 if (c_parser_require (parser, type, msgid, matching_location))
1242 return;
1243
1244 /* Skip tokens until the desired token is found. */
1245 while (true)
1246 {
1247 /* Peek at the next token. */
1248 c_token *token = c_parser_peek_token (parser);
1249 /* If we've reached the token we want, consume it and stop. */
1250 if (token->type == type && !nesting_depth)
1251 {
1252 c_parser_consume_token (parser);
1253 break;
1254 }
1255
1256 /* If we've run out of tokens, stop. */
1257 if (token->type == CPP_EOF)
1258 return;
1259 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1260 return;
1261 if (token->type == CPP_OPEN_BRACE
1262 || token->type == CPP_OPEN_PAREN
1263 || token->type == CPP_OPEN_SQUARE)
1264 ++nesting_depth;
1265 else if (token->type == CPP_CLOSE_BRACE
1266 || token->type == CPP_CLOSE_PAREN
1267 || token->type == CPP_CLOSE_SQUARE)
1268 {
1269 if (nesting_depth-- == 0)
1270 break;
1271 }
1272 /* Consume this token. */
1273 c_parser_consume_token (parser);
1274 }
1275 parser->error = false;
1276 }
1277
1278 /* Skip tokens until the end of a parameter is found, but do not
1279 consume the comma, semicolon or closing delimiter. */
1280
1281 static void
1282 c_parser_skip_to_end_of_parameter (c_parser *parser)
1283 {
1284 unsigned nesting_depth = 0;
1285
1286 while (true)
1287 {
1288 c_token *token = c_parser_peek_token (parser);
1289 if ((token->type == CPP_COMMA || token->type == CPP_SEMICOLON)
1290 && !nesting_depth)
1291 break;
1292 /* If we've run out of tokens, stop. */
1293 if (token->type == CPP_EOF)
1294 return;
1295 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1296 return;
1297 if (token->type == CPP_OPEN_BRACE
1298 || token->type == CPP_OPEN_PAREN
1299 || token->type == CPP_OPEN_SQUARE)
1300 ++nesting_depth;
1301 else if (token->type == CPP_CLOSE_BRACE
1302 || token->type == CPP_CLOSE_PAREN
1303 || token->type == CPP_CLOSE_SQUARE)
1304 {
1305 if (nesting_depth-- == 0)
1306 break;
1307 }
1308 /* Consume this token. */
1309 c_parser_consume_token (parser);
1310 }
1311 parser->error = false;
1312 }
1313
1314 /* Expect to be at the end of the pragma directive and consume an
1315 end of line marker. */
1316
1317 static void
1318 c_parser_skip_to_pragma_eol (c_parser *parser, bool error_if_not_eol = true)
1319 {
1320 gcc_assert (parser->in_pragma);
1321 parser->in_pragma = false;
1322
1323 if (error_if_not_eol && c_parser_peek_token (parser)->type != CPP_PRAGMA_EOL)
1324 c_parser_error (parser, "expected end of line");
1325
1326 cpp_ttype token_type;
1327 do
1328 {
1329 c_token *token = c_parser_peek_token (parser);
1330 token_type = token->type;
1331 if (token_type == CPP_EOF)
1332 break;
1333 c_parser_consume_token (parser);
1334 }
1335 while (token_type != CPP_PRAGMA_EOL);
1336
1337 parser->error = false;
1338 }
1339
1340 /* Skip tokens until we have consumed an entire block, or until we
1341 have consumed a non-nested ';'. */
1342
1343 static void
1344 c_parser_skip_to_end_of_block_or_statement (c_parser *parser)
1345 {
1346 unsigned nesting_depth = 0;
1347 bool save_error = parser->error;
1348
1349 while (true)
1350 {
1351 c_token *token;
1352
1353 /* Peek at the next token. */
1354 token = c_parser_peek_token (parser);
1355
1356 switch (token->type)
1357 {
1358 case CPP_EOF:
1359 return;
1360
1361 case CPP_PRAGMA_EOL:
1362 if (parser->in_pragma)
1363 return;
1364 break;
1365
1366 case CPP_SEMICOLON:
1367 /* If the next token is a ';', we have reached the
1368 end of the statement. */
1369 if (!nesting_depth)
1370 {
1371 /* Consume the ';'. */
1372 c_parser_consume_token (parser);
1373 goto finished;
1374 }
1375 break;
1376
1377 case CPP_CLOSE_BRACE:
1378 /* If the next token is a non-nested '}', then we have
1379 reached the end of the current block. */
1380 if (nesting_depth == 0 || --nesting_depth == 0)
1381 {
1382 c_parser_consume_token (parser);
1383 goto finished;
1384 }
1385 break;
1386
1387 case CPP_OPEN_BRACE:
1388 /* If it the next token is a '{', then we are entering a new
1389 block. Consume the entire block. */
1390 ++nesting_depth;
1391 break;
1392
1393 case CPP_PRAGMA:
1394 /* If we see a pragma, consume the whole thing at once. We
1395 have some safeguards against consuming pragmas willy-nilly.
1396 Normally, we'd expect to be here with parser->error set,
1397 which disables these safeguards. But it's possible to get
1398 here for secondary error recovery, after parser->error has
1399 been cleared. */
1400 c_parser_consume_pragma (parser);
1401 c_parser_skip_to_pragma_eol (parser);
1402 parser->error = save_error;
1403 continue;
1404
1405 default:
1406 break;
1407 }
1408
1409 c_parser_consume_token (parser);
1410 }
1411
1412 finished:
1413 parser->error = false;
1414 }
1415
1416 /* CPP's options (initialized by c-opts.cc). */
1417 extern cpp_options *cpp_opts;
1418
1419 /* Save the warning flags which are controlled by __extension__. */
1420
1421 static inline int
1422 disable_extension_diagnostics (void)
1423 {
1424 int ret = (pedantic
1425 | (warn_pointer_arith << 1)
1426 | (warn_traditional << 2)
1427 | (flag_iso << 3)
1428 | (warn_long_long << 4)
1429 | (warn_cxx_compat << 5)
1430 | (warn_overlength_strings << 6)
1431 /* warn_c90_c99_compat has three states: -1/0/1, so we must
1432 play tricks to properly restore it. */
1433 | ((warn_c90_c99_compat == 1) << 7)
1434 | ((warn_c90_c99_compat == -1) << 8)
1435 /* Similarly for warn_c99_c11_compat. */
1436 | ((warn_c99_c11_compat == 1) << 9)
1437 | ((warn_c99_c11_compat == -1) << 10)
1438 /* Similarly for warn_c11_c2x_compat. */
1439 | ((warn_c11_c2x_compat == 1) << 11)
1440 | ((warn_c11_c2x_compat == -1) << 12)
1441 );
1442 cpp_opts->cpp_pedantic = pedantic = 0;
1443 warn_pointer_arith = 0;
1444 cpp_opts->cpp_warn_traditional = warn_traditional = 0;
1445 flag_iso = 0;
1446 cpp_opts->cpp_warn_long_long = warn_long_long = 0;
1447 warn_cxx_compat = 0;
1448 warn_overlength_strings = 0;
1449 warn_c90_c99_compat = 0;
1450 warn_c99_c11_compat = 0;
1451 warn_c11_c2x_compat = 0;
1452 return ret;
1453 }
1454
1455 /* Restore the warning flags which are controlled by __extension__.
1456 FLAGS is the return value from disable_extension_diagnostics. */
1457
1458 static inline void
1459 restore_extension_diagnostics (int flags)
1460 {
1461 cpp_opts->cpp_pedantic = pedantic = flags & 1;
1462 warn_pointer_arith = (flags >> 1) & 1;
1463 cpp_opts->cpp_warn_traditional = warn_traditional = (flags >> 2) & 1;
1464 flag_iso = (flags >> 3) & 1;
1465 cpp_opts->cpp_warn_long_long = warn_long_long = (flags >> 4) & 1;
1466 warn_cxx_compat = (flags >> 5) & 1;
1467 warn_overlength_strings = (flags >> 6) & 1;
1468 /* See above for why is this needed. */
1469 warn_c90_c99_compat = (flags >> 7) & 1 ? 1 : ((flags >> 8) & 1 ? -1 : 0);
1470 warn_c99_c11_compat = (flags >> 9) & 1 ? 1 : ((flags >> 10) & 1 ? -1 : 0);
1471 warn_c11_c2x_compat = (flags >> 11) & 1 ? 1 : ((flags >> 12) & 1 ? -1 : 0);
1472 }
1473
1474 /* Helper data structure for parsing #pragma acc routine. */
1475 struct oacc_routine_data {
1476 bool error_seen; /* Set if error has been reported. */
1477 bool fndecl_seen; /* Set if one fn decl/definition has been seen already. */
1478 tree clauses;
1479 location_t loc;
1480 };
1481
1482 /* Used for parsing objc foreach statements. */
1483 static tree objc_foreach_break_label, objc_foreach_continue_label;
1484
1485 static bool c_parser_nth_token_starts_std_attributes (c_parser *,
1486 unsigned int);
1487 static tree c_parser_std_attribute_specifier_sequence (c_parser *);
1488 static void c_parser_external_declaration (c_parser *);
1489 static void c_parser_asm_definition (c_parser *);
1490 static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
1491 bool, bool, tree * = NULL,
1492 vec<c_token> * = NULL,
1493 bool have_attrs = false,
1494 tree attrs = NULL,
1495 struct oacc_routine_data * = NULL,
1496 bool * = NULL);
1497 static void c_parser_static_assert_declaration_no_semi (c_parser *);
1498 static void c_parser_static_assert_declaration (c_parser *);
1499 static struct c_typespec c_parser_enum_specifier (c_parser *);
1500 static struct c_typespec c_parser_struct_or_union_specifier (c_parser *);
1501 static tree c_parser_struct_declaration (c_parser *);
1502 static struct c_typespec c_parser_typeof_specifier (c_parser *);
1503 static tree c_parser_alignas_specifier (c_parser *);
1504 static struct c_declarator *c_parser_direct_declarator (c_parser *, bool,
1505 c_dtr_syn, bool *);
1506 static struct c_declarator *c_parser_direct_declarator_inner (c_parser *,
1507 bool,
1508 struct c_declarator *);
1509 static struct c_arg_info *c_parser_parms_declarator (c_parser *, bool, tree,
1510 bool);
1511 static struct c_arg_info *c_parser_parms_list_declarator (c_parser *, tree,
1512 tree, bool);
1513 static struct c_parm *c_parser_parameter_declaration (c_parser *, tree, bool);
1514 static tree c_parser_simple_asm_expr (c_parser *);
1515 static tree c_parser_gnu_attributes (c_parser *);
1516 static struct c_expr c_parser_initializer (c_parser *);
1517 static struct c_expr c_parser_braced_init (c_parser *, tree, bool,
1518 struct obstack *);
1519 static void c_parser_initelt (c_parser *, struct obstack *);
1520 static void c_parser_initval (c_parser *, struct c_expr *,
1521 struct obstack *);
1522 static tree c_parser_compound_statement (c_parser *, location_t * = NULL);
1523 static location_t c_parser_compound_statement_nostart (c_parser *);
1524 static void c_parser_label (c_parser *, tree);
1525 static void c_parser_statement (c_parser *, bool *, location_t * = NULL);
1526 static void c_parser_statement_after_labels (c_parser *, bool *,
1527 vec<tree> * = NULL);
1528 static tree c_parser_c99_block_statement (c_parser *, bool *,
1529 location_t * = NULL);
1530 static void c_parser_if_statement (c_parser *, bool *, vec<tree> *);
1531 static void c_parser_switch_statement (c_parser *, bool *);
1532 static void c_parser_while_statement (c_parser *, bool, unsigned short, bool *);
1533 static void c_parser_do_statement (c_parser *, bool, unsigned short);
1534 static void c_parser_for_statement (c_parser *, bool, unsigned short, bool *);
1535 static tree c_parser_asm_statement (c_parser *);
1536 static tree c_parser_asm_operands (c_parser *);
1537 static tree c_parser_asm_goto_operands (c_parser *);
1538 static tree c_parser_asm_clobbers (c_parser *);
1539 static struct c_expr c_parser_expr_no_commas (c_parser *, struct c_expr *,
1540 tree = NULL_TREE);
1541 static struct c_expr c_parser_conditional_expression (c_parser *,
1542 struct c_expr *, tree);
1543 static struct c_expr c_parser_binary_expression (c_parser *, struct c_expr *,
1544 tree);
1545 static struct c_expr c_parser_cast_expression (c_parser *, struct c_expr *);
1546 static struct c_expr c_parser_unary_expression (c_parser *);
1547 static struct c_expr c_parser_sizeof_expression (c_parser *);
1548 static struct c_expr c_parser_alignof_expression (c_parser *);
1549 static struct c_expr c_parser_postfix_expression (c_parser *);
1550 static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *,
1551 struct c_type_name *,
1552 location_t);
1553 static struct c_expr c_parser_postfix_expression_after_primary (c_parser *,
1554 location_t loc,
1555 struct c_expr);
1556 static tree c_parser_transaction (c_parser *, enum rid);
1557 static struct c_expr c_parser_transaction_expression (c_parser *, enum rid);
1558 static tree c_parser_transaction_cancel (c_parser *);
1559 static struct c_expr c_parser_expression (c_parser *);
1560 static struct c_expr c_parser_expression_conv (c_parser *);
1561 static vec<tree, va_gc> *c_parser_expr_list (c_parser *, bool, bool,
1562 vec<tree, va_gc> **, location_t *,
1563 tree *, vec<location_t> *,
1564 unsigned int * = NULL);
1565 static struct c_expr c_parser_has_attribute_expression (c_parser *);
1566
1567 static void c_parser_oacc_declare (c_parser *);
1568 static void c_parser_oacc_enter_exit_data (c_parser *, bool);
1569 static void c_parser_oacc_update (c_parser *);
1570 static void c_parser_omp_construct (c_parser *, bool *);
1571 static void c_parser_omp_threadprivate (c_parser *);
1572 static void c_parser_omp_barrier (c_parser *);
1573 static void c_parser_omp_depobj (c_parser *);
1574 static void c_parser_omp_flush (c_parser *);
1575 static tree c_parser_omp_for_loop (location_t, c_parser *, enum tree_code,
1576 tree, tree *, bool *);
1577 static void c_parser_omp_taskwait (c_parser *);
1578 static void c_parser_omp_taskyield (c_parser *);
1579 static void c_parser_omp_cancel (c_parser *);
1580 static void c_parser_omp_nothing (c_parser *);
1581
1582 enum pragma_context { pragma_external, pragma_struct, pragma_param,
1583 pragma_stmt, pragma_compound };
1584 static bool c_parser_pragma (c_parser *, enum pragma_context, bool *);
1585 static bool c_parser_omp_cancellation_point (c_parser *, enum pragma_context);
1586 static bool c_parser_omp_target (c_parser *, enum pragma_context, bool *);
1587 static void c_parser_omp_end_declare_target (c_parser *);
1588 static bool c_parser_omp_declare (c_parser *, enum pragma_context);
1589 static void c_parser_omp_requires (c_parser *);
1590 static bool c_parser_omp_error (c_parser *, enum pragma_context);
1591 static bool c_parser_omp_ordered (c_parser *, enum pragma_context, bool *);
1592 static void c_parser_oacc_routine (c_parser *, enum pragma_context);
1593
1594 /* These Objective-C parser functions are only ever called when
1595 compiling Objective-C. */
1596 static void c_parser_objc_class_definition (c_parser *, tree);
1597 static void c_parser_objc_class_instance_variables (c_parser *);
1598 static void c_parser_objc_class_declaration (c_parser *);
1599 static void c_parser_objc_alias_declaration (c_parser *);
1600 static void c_parser_objc_protocol_definition (c_parser *, tree);
1601 static bool c_parser_objc_method_type (c_parser *);
1602 static void c_parser_objc_method_definition (c_parser *);
1603 static void c_parser_objc_methodprotolist (c_parser *);
1604 static void c_parser_objc_methodproto (c_parser *);
1605 static tree c_parser_objc_method_decl (c_parser *, bool, tree *, tree *);
1606 static tree c_parser_objc_type_name (c_parser *);
1607 static tree c_parser_objc_protocol_refs (c_parser *);
1608 static void c_parser_objc_try_catch_finally_statement (c_parser *);
1609 static void c_parser_objc_synchronized_statement (c_parser *);
1610 static tree c_parser_objc_selector (c_parser *);
1611 static tree c_parser_objc_selector_arg (c_parser *);
1612 static tree c_parser_objc_receiver (c_parser *);
1613 static tree c_parser_objc_message_args (c_parser *);
1614 static tree c_parser_objc_keywordexpr (c_parser *);
1615 static void c_parser_objc_at_property_declaration (c_parser *);
1616 static void c_parser_objc_at_synthesize_declaration (c_parser *);
1617 static void c_parser_objc_at_dynamic_declaration (c_parser *);
1618 static bool c_parser_objc_diagnose_bad_element_prefix
1619 (c_parser *, struct c_declspecs *);
1620 static location_t c_parser_parse_rtl_body (c_parser *, char *);
1621
1622 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
1623
1624 translation-unit:
1625 external-declarations
1626
1627 external-declarations:
1628 external-declaration
1629 external-declarations external-declaration
1630
1631 GNU extensions:
1632
1633 translation-unit:
1634 empty
1635 */
1636
1637 static void
1638 c_parser_translation_unit (c_parser *parser)
1639 {
1640 if (c_parser_next_token_is (parser, CPP_EOF))
1641 {
1642 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1643 "ISO C forbids an empty translation unit");
1644 }
1645 else
1646 {
1647 void *obstack_position = obstack_alloc (&parser_obstack, 0);
1648 mark_valid_location_for_stdc_pragma (false);
1649 do
1650 {
1651 ggc_collect ();
1652 c_parser_external_declaration (parser);
1653 obstack_free (&parser_obstack, obstack_position);
1654 }
1655 while (c_parser_next_token_is_not (parser, CPP_EOF));
1656 }
1657
1658 unsigned int i;
1659 tree decl;
1660 FOR_EACH_VEC_ELT (incomplete_record_decls, i, decl)
1661 if (DECL_SIZE (decl) == NULL_TREE && TREE_TYPE (decl) != error_mark_node)
1662 error ("storage size of %q+D isn%'t known", decl);
1663
1664 if (current_omp_declare_target_attribute)
1665 {
1666 if (!errorcount)
1667 error ("%<#pragma omp declare target%> without corresponding "
1668 "%<#pragma omp end declare target%>");
1669 current_omp_declare_target_attribute = 0;
1670 }
1671 }
1672
1673 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
1674
1675 external-declaration:
1676 function-definition
1677 declaration
1678
1679 GNU extensions:
1680
1681 external-declaration:
1682 asm-definition
1683 ;
1684 __extension__ external-declaration
1685
1686 Objective-C:
1687
1688 external-declaration:
1689 objc-class-definition
1690 objc-class-declaration
1691 objc-alias-declaration
1692 objc-protocol-definition
1693 objc-method-definition
1694 @end
1695 */
1696
1697 static void
1698 c_parser_external_declaration (c_parser *parser)
1699 {
1700 int ext;
1701 switch (c_parser_peek_token (parser)->type)
1702 {
1703 case CPP_KEYWORD:
1704 switch (c_parser_peek_token (parser)->keyword)
1705 {
1706 case RID_EXTENSION:
1707 ext = disable_extension_diagnostics ();
1708 c_parser_consume_token (parser);
1709 c_parser_external_declaration (parser);
1710 restore_extension_diagnostics (ext);
1711 break;
1712 case RID_ASM:
1713 c_parser_asm_definition (parser);
1714 break;
1715 case RID_AT_INTERFACE:
1716 case RID_AT_IMPLEMENTATION:
1717 gcc_assert (c_dialect_objc ());
1718 c_parser_objc_class_definition (parser, NULL_TREE);
1719 break;
1720 case RID_AT_CLASS:
1721 gcc_assert (c_dialect_objc ());
1722 c_parser_objc_class_declaration (parser);
1723 break;
1724 case RID_AT_ALIAS:
1725 gcc_assert (c_dialect_objc ());
1726 c_parser_objc_alias_declaration (parser);
1727 break;
1728 case RID_AT_PROTOCOL:
1729 gcc_assert (c_dialect_objc ());
1730 c_parser_objc_protocol_definition (parser, NULL_TREE);
1731 break;
1732 case RID_AT_PROPERTY:
1733 gcc_assert (c_dialect_objc ());
1734 c_parser_objc_at_property_declaration (parser);
1735 break;
1736 case RID_AT_SYNTHESIZE:
1737 gcc_assert (c_dialect_objc ());
1738 c_parser_objc_at_synthesize_declaration (parser);
1739 break;
1740 case RID_AT_DYNAMIC:
1741 gcc_assert (c_dialect_objc ());
1742 c_parser_objc_at_dynamic_declaration (parser);
1743 break;
1744 case RID_AT_END:
1745 gcc_assert (c_dialect_objc ());
1746 c_parser_consume_token (parser);
1747 objc_finish_implementation ();
1748 break;
1749 default:
1750 goto decl_or_fndef;
1751 }
1752 break;
1753 case CPP_SEMICOLON:
1754 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1755 "ISO C does not allow extra %<;%> outside of a function");
1756 c_parser_consume_token (parser);
1757 break;
1758 case CPP_PRAGMA:
1759 mark_valid_location_for_stdc_pragma (true);
1760 c_parser_pragma (parser, pragma_external, NULL);
1761 mark_valid_location_for_stdc_pragma (false);
1762 break;
1763 case CPP_PLUS:
1764 case CPP_MINUS:
1765 if (c_dialect_objc ())
1766 {
1767 c_parser_objc_method_definition (parser);
1768 break;
1769 }
1770 /* Else fall through, and yield a syntax error trying to parse
1771 as a declaration or function definition. */
1772 /* FALLTHRU */
1773 default:
1774 decl_or_fndef:
1775 /* A declaration or a function definition (or, in Objective-C,
1776 an @interface or @protocol with prefix attributes). We can
1777 only tell which after parsing the declaration specifiers, if
1778 any, and the first declarator. */
1779 c_parser_declaration_or_fndef (parser, true, true, true, false, true);
1780 break;
1781 }
1782 }
1783
1784 static void c_finish_omp_declare_simd (c_parser *, tree, tree, vec<c_token> *);
1785 static void c_finish_oacc_routine (struct oacc_routine_data *, tree, bool);
1786
1787 /* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */
1788
1789 static void
1790 add_debug_begin_stmt (location_t loc)
1791 {
1792 /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721. */
1793 if (!MAY_HAVE_DEBUG_MARKER_STMTS || !building_stmt_list_p ())
1794 return;
1795
1796 tree stmt = build0 (DEBUG_BEGIN_STMT, void_type_node);
1797 SET_EXPR_LOCATION (stmt, loc);
1798 add_stmt (stmt);
1799 }
1800
1801 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
1802 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition
1803 is accepted; otherwise (old-style parameter declarations) only other
1804 declarations are accepted. If STATIC_ASSERT_OK is true, a static
1805 assertion is accepted; otherwise (old-style parameter declarations)
1806 it is not. If NESTED is true, we are inside a function or parsing
1807 old-style parameter declarations; any functions encountered are
1808 nested functions and declaration specifiers are required; otherwise
1809 we are at top level and functions are normal functions and
1810 declaration specifiers may be optional. If EMPTY_OK is true, empty
1811 declarations are OK (subject to all other constraints); otherwise
1812 (old-style parameter declarations) they are diagnosed. If
1813 START_ATTR_OK is true, the declaration specifiers may start with
1814 attributes (GNU or standard); otherwise they may not.
1815 OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
1816 declaration when parsing an Objective-C foreach statement.
1817 FALLTHRU_ATTR_P is used to signal whether this function parsed
1818 "__attribute__((fallthrough));". ATTRS are any standard attributes
1819 parsed in the caller (in contexts where such attributes had to be
1820 parsed to determine whether what follows is a declaration or a
1821 statement); HAVE_ATTRS says whether there were any such attributes
1822 (even empty).
1823
1824 declaration:
1825 declaration-specifiers init-declarator-list[opt] ;
1826 static_assert-declaration
1827
1828 function-definition:
1829 declaration-specifiers[opt] declarator declaration-list[opt]
1830 compound-statement
1831
1832 declaration-list:
1833 declaration
1834 declaration-list declaration
1835
1836 init-declarator-list:
1837 init-declarator
1838 init-declarator-list , init-declarator
1839
1840 init-declarator:
1841 declarator simple-asm-expr[opt] gnu-attributes[opt]
1842 declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
1843
1844 GNU extensions:
1845
1846 nested-function-definition:
1847 declaration-specifiers declarator declaration-list[opt]
1848 compound-statement
1849
1850 attribute ;
1851
1852 Objective-C:
1853 gnu-attributes objc-class-definition
1854 gnu-attributes objc-category-definition
1855 gnu-attributes objc-protocol-definition
1856
1857 The simple-asm-expr and gnu-attributes are GNU extensions.
1858
1859 This function does not handle __extension__; that is handled in its
1860 callers. ??? Following the old parser, __extension__ may start
1861 external declarations, declarations in functions and declarations
1862 at the start of "for" loops, but not old-style parameter
1863 declarations.
1864
1865 C99 requires declaration specifiers in a function definition; the
1866 absence is diagnosed through the diagnosis of implicit int. In GNU
1867 C we also allow but diagnose declarations without declaration
1868 specifiers, but only at top level (elsewhere they conflict with
1869 other syntax).
1870
1871 In Objective-C, declarations of the looping variable in a foreach
1872 statement are exceptionally terminated by 'in' (for example, 'for
1873 (NSObject *object in array) { ... }').
1874
1875 OpenMP:
1876
1877 declaration:
1878 threadprivate-directive
1879
1880 GIMPLE:
1881
1882 gimple-function-definition:
1883 declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
1884 declaration-list[opt] compound-statement
1885
1886 rtl-function-definition:
1887 declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
1888 declaration-list[opt] compound-statement */
1889
1890 static void
1891 c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
1892 bool static_assert_ok, bool empty_ok,
1893 bool nested, bool start_attr_ok,
1894 tree *objc_foreach_object_declaration
1895 /* = NULL */,
1896 vec<c_token> *omp_declare_simd_clauses
1897 /* = NULL */,
1898 bool have_attrs /* = false */,
1899 tree attrs /* = NULL_TREE */,
1900 struct oacc_routine_data *oacc_routine_data
1901 /* = NULL */,
1902 bool *fallthru_attr_p /* = NULL */)
1903 {
1904 struct c_declspecs *specs;
1905 tree prefix_attrs;
1906 tree all_prefix_attrs;
1907 bool diagnosed_no_specs = false;
1908 location_t here = c_parser_peek_token (parser)->location;
1909
1910 add_debug_begin_stmt (c_parser_peek_token (parser)->location);
1911
1912 if (static_assert_ok
1913 && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
1914 {
1915 c_parser_static_assert_declaration (parser);
1916 return;
1917 }
1918 specs = build_null_declspecs ();
1919
1920 /* Handle any standard attributes parsed in the caller. */
1921 if (have_attrs)
1922 {
1923 declspecs_add_attrs (here, specs, attrs);
1924 specs->non_std_attrs_seen_p = false;
1925 }
1926
1927 /* Try to detect an unknown type name when we have "A B" or "A *B". */
1928 if (c_parser_peek_token (parser)->type == CPP_NAME
1929 && c_parser_peek_token (parser)->id_kind == C_ID_ID
1930 && (c_parser_peek_2nd_token (parser)->type == CPP_NAME
1931 || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
1932 && (!nested || !lookup_name (c_parser_peek_token (parser)->value)))
1933 {
1934 tree name = c_parser_peek_token (parser)->value;
1935
1936 /* Issue a warning about NAME being an unknown type name, perhaps
1937 with some kind of hint.
1938 If the user forgot a "struct" etc, suggest inserting
1939 it. Otherwise, attempt to look for misspellings. */
1940 gcc_rich_location richloc (here);
1941 if (tag_exists_p (RECORD_TYPE, name))
1942 {
1943 /* This is not C++ with its implicit typedef. */
1944 richloc.add_fixit_insert_before ("struct ");
1945 error_at (&richloc,
1946 "unknown type name %qE;"
1947 " use %<struct%> keyword to refer to the type",
1948 name);
1949 }
1950 else if (tag_exists_p (UNION_TYPE, name))
1951 {
1952 richloc.add_fixit_insert_before ("union ");
1953 error_at (&richloc,
1954 "unknown type name %qE;"
1955 " use %<union%> keyword to refer to the type",
1956 name);
1957 }
1958 else if (tag_exists_p (ENUMERAL_TYPE, name))
1959 {
1960 richloc.add_fixit_insert_before ("enum ");
1961 error_at (&richloc,
1962 "unknown type name %qE;"
1963 " use %<enum%> keyword to refer to the type",
1964 name);
1965 }
1966 else
1967 {
1968 auto_diagnostic_group d;
1969 name_hint hint = lookup_name_fuzzy (name, FUZZY_LOOKUP_TYPENAME,
1970 here);
1971 if (const char *suggestion = hint.suggestion ())
1972 {
1973 richloc.add_fixit_replace (suggestion);
1974 error_at (&richloc,
1975 "unknown type name %qE; did you mean %qs?",
1976 name, suggestion);
1977 }
1978 else
1979 error_at (here, "unknown type name %qE", name);
1980 }
1981
1982 /* Parse declspecs normally to get a correct pointer type, but avoid
1983 a further "fails to be a type name" error. Refuse nested functions
1984 since it is not how the user likely wants us to recover. */
1985 c_parser_peek_token (parser)->type = CPP_KEYWORD;
1986 c_parser_peek_token (parser)->keyword = RID_VOID;
1987 c_parser_peek_token (parser)->value = error_mark_node;
1988 fndef_ok = !nested;
1989 }
1990
1991 /* When there are standard attributes at the start of the
1992 declaration (to apply to the entity being declared), an
1993 init-declarator-list or function definition must be present. */
1994 if (c_parser_nth_token_starts_std_attributes (parser, 1))
1995 have_attrs = true;
1996
1997 c_parser_declspecs (parser, specs, true, true, start_attr_ok,
1998 true, true, start_attr_ok, true, cla_nonabstract_decl);
1999 if (parser->error)
2000 {
2001 c_parser_skip_to_end_of_block_or_statement (parser);
2002 return;
2003 }
2004 if (nested && !specs->declspecs_seen_p)
2005 {
2006 c_parser_error (parser, "expected declaration specifiers");
2007 c_parser_skip_to_end_of_block_or_statement (parser);
2008 return;
2009 }
2010
2011 finish_declspecs (specs);
2012 bool auto_type_p = specs->typespec_word == cts_auto_type;
2013 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2014 {
2015 if (auto_type_p)
2016 error_at (here, "%<__auto_type%> in empty declaration");
2017 else if (specs->typespec_kind == ctsk_none
2018 && attribute_fallthrough_p (specs->attrs))
2019 {
2020 if (fallthru_attr_p != NULL)
2021 *fallthru_attr_p = true;
2022 if (nested)
2023 {
2024 tree fn = build_call_expr_internal_loc (here, IFN_FALLTHROUGH,
2025 void_type_node, 0);
2026 add_stmt (fn);
2027 }
2028 else
2029 pedwarn (here, OPT_Wattributes,
2030 "%<fallthrough%> attribute at top level");
2031 }
2032 else if (empty_ok && !(have_attrs
2033 && specs->non_std_attrs_seen_p))
2034 shadow_tag (specs);
2035 else
2036 {
2037 shadow_tag_warned (specs, 1);
2038 pedwarn (here, 0, "empty declaration");
2039 }
2040 c_parser_consume_token (parser);
2041 if (oacc_routine_data)
2042 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2043 return;
2044 }
2045
2046 /* Provide better error recovery. Note that a type name here is usually
2047 better diagnosed as a redeclaration. */
2048 if (empty_ok
2049 && specs->typespec_kind == ctsk_tagdef
2050 && c_parser_next_token_starts_declspecs (parser)
2051 && !c_parser_next_token_is (parser, CPP_NAME))
2052 {
2053 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
2054 parser->error = false;
2055 shadow_tag_warned (specs, 1);
2056 return;
2057 }
2058 else if (c_dialect_objc () && !auto_type_p)
2059 {
2060 /* Prefix attributes are an error on method decls. */
2061 switch (c_parser_peek_token (parser)->type)
2062 {
2063 case CPP_PLUS:
2064 case CPP_MINUS:
2065 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2066 return;
2067 if (specs->attrs)
2068 {
2069 warning_at (c_parser_peek_token (parser)->location,
2070 OPT_Wattributes,
2071 "prefix attributes are ignored for methods");
2072 specs->attrs = NULL_TREE;
2073 }
2074 if (fndef_ok)
2075 c_parser_objc_method_definition (parser);
2076 else
2077 c_parser_objc_methodproto (parser);
2078 return;
2079 break;
2080 default:
2081 break;
2082 }
2083 /* This is where we parse 'attributes @interface ...',
2084 'attributes @implementation ...', 'attributes @protocol ...'
2085 (where attributes could be, for example, __attribute__
2086 ((deprecated)).
2087 */
2088 switch (c_parser_peek_token (parser)->keyword)
2089 {
2090 case RID_AT_INTERFACE:
2091 {
2092 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2093 return;
2094 c_parser_objc_class_definition (parser, specs->attrs);
2095 return;
2096 }
2097 break;
2098 case RID_AT_IMPLEMENTATION:
2099 {
2100 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2101 return;
2102 if (specs->attrs)
2103 {
2104 warning_at (c_parser_peek_token (parser)->location,
2105 OPT_Wattributes,
2106 "prefix attributes are ignored for implementations");
2107 specs->attrs = NULL_TREE;
2108 }
2109 c_parser_objc_class_definition (parser, NULL_TREE);
2110 return;
2111 }
2112 break;
2113 case RID_AT_PROTOCOL:
2114 {
2115 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
2116 return;
2117 c_parser_objc_protocol_definition (parser, specs->attrs);
2118 return;
2119 }
2120 break;
2121 case RID_AT_ALIAS:
2122 case RID_AT_CLASS:
2123 case RID_AT_END:
2124 case RID_AT_PROPERTY:
2125 if (specs->attrs)
2126 {
2127 c_parser_error (parser, "unexpected attribute");
2128 specs->attrs = NULL;
2129 }
2130 break;
2131 default:
2132 break;
2133 }
2134 }
2135 else if (attribute_fallthrough_p (specs->attrs))
2136 warning_at (here, OPT_Wattributes,
2137 "%<fallthrough%> attribute not followed by %<;%>");
2138
2139 pending_xref_error ();
2140 prefix_attrs = specs->attrs;
2141 all_prefix_attrs = prefix_attrs;
2142 specs->attrs = NULL_TREE;
2143 while (true)
2144 {
2145 struct c_declarator *declarator;
2146 bool dummy = false;
2147 timevar_id_t tv;
2148 tree fnbody = NULL_TREE;
2149 /* Declaring either one or more declarators (in which case we
2150 should diagnose if there were no declaration specifiers) or a
2151 function definition (in which case the diagnostic for
2152 implicit int suffices). */
2153 declarator = c_parser_declarator (parser,
2154 specs->typespec_kind != ctsk_none,
2155 C_DTR_NORMAL, &dummy);
2156 if (declarator == NULL)
2157 {
2158 if (omp_declare_simd_clauses)
2159 c_finish_omp_declare_simd (parser, NULL_TREE, NULL_TREE,
2160 omp_declare_simd_clauses);
2161 if (oacc_routine_data)
2162 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2163 c_parser_skip_to_end_of_block_or_statement (parser);
2164 return;
2165 }
2166 if (auto_type_p && declarator->kind != cdk_id)
2167 {
2168 error_at (here,
2169 "%<__auto_type%> requires a plain identifier"
2170 " as declarator");
2171 c_parser_skip_to_end_of_block_or_statement (parser);
2172 return;
2173 }
2174 if (c_parser_next_token_is (parser, CPP_EQ)
2175 || c_parser_next_token_is (parser, CPP_COMMA)
2176 || c_parser_next_token_is (parser, CPP_SEMICOLON)
2177 || c_parser_next_token_is_keyword (parser, RID_ASM)
2178 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)
2179 || c_parser_next_token_is_keyword (parser, RID_IN))
2180 {
2181 tree asm_name = NULL_TREE;
2182 tree postfix_attrs = NULL_TREE;
2183 if (!diagnosed_no_specs && !specs->declspecs_seen_p)
2184 {
2185 diagnosed_no_specs = true;
2186 pedwarn (here, 0, "data definition has no type or storage class");
2187 }
2188 /* Having seen a data definition, there cannot now be a
2189 function definition. */
2190 fndef_ok = false;
2191 if (c_parser_next_token_is_keyword (parser, RID_ASM))
2192 asm_name = c_parser_simple_asm_expr (parser);
2193 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2194 {
2195 postfix_attrs = c_parser_gnu_attributes (parser);
2196 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
2197 {
2198 /* This means there is an attribute specifier after
2199 the declarator in a function definition. Provide
2200 some more information for the user. */
2201 error_at (here, "attributes should be specified before the "
2202 "declarator in a function definition");
2203 c_parser_skip_to_end_of_block_or_statement (parser);
2204 return;
2205 }
2206 }
2207 if (c_parser_next_token_is (parser, CPP_EQ))
2208 {
2209 tree d;
2210 struct c_expr init;
2211 location_t init_loc;
2212 c_parser_consume_token (parser);
2213 if (auto_type_p)
2214 {
2215 init_loc = c_parser_peek_token (parser)->location;
2216 rich_location richloc (line_table, init_loc);
2217 start_init (NULL_TREE, asm_name, global_bindings_p (), &richloc);
2218 /* A parameter is initialized, which is invalid. Don't
2219 attempt to instrument the initializer. */
2220 int flag_sanitize_save = flag_sanitize;
2221 if (nested && !empty_ok)
2222 flag_sanitize = 0;
2223 init = c_parser_expr_no_commas (parser, NULL);
2224 flag_sanitize = flag_sanitize_save;
2225 if (TREE_CODE (init.value) == COMPONENT_REF
2226 && DECL_C_BIT_FIELD (TREE_OPERAND (init.value, 1)))
2227 error_at (here,
2228 "%<__auto_type%> used with a bit-field"
2229 " initializer");
2230 init = convert_lvalue_to_rvalue (init_loc, init, true, true);
2231 tree init_type = TREE_TYPE (init.value);
2232 bool vm_type = variably_modified_type_p (init_type,
2233 NULL_TREE);
2234 if (vm_type)
2235 init.value = save_expr (init.value);
2236 finish_init ();
2237 specs->typespec_kind = ctsk_typeof;
2238 specs->locations[cdw_typedef] = init_loc;
2239 specs->typedef_p = true;
2240 specs->type = init_type;
2241 if (vm_type)
2242 {
2243 bool maybe_const = true;
2244 tree type_expr = c_fully_fold (init.value, false,
2245 &maybe_const);
2246 specs->expr_const_operands &= maybe_const;
2247 if (specs->expr)
2248 specs->expr = build2 (COMPOUND_EXPR,
2249 TREE_TYPE (type_expr),
2250 specs->expr, type_expr);
2251 else
2252 specs->expr = type_expr;
2253 }
2254 d = start_decl (declarator, specs, true,
2255 chainon (postfix_attrs, all_prefix_attrs));
2256 if (!d)
2257 d = error_mark_node;
2258 if (omp_declare_simd_clauses)
2259 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2260 omp_declare_simd_clauses);
2261 }
2262 else
2263 {
2264 /* The declaration of the variable is in effect while
2265 its initializer is parsed. */
2266 d = start_decl (declarator, specs, true,
2267 chainon (postfix_attrs, all_prefix_attrs));
2268 if (!d)
2269 d = error_mark_node;
2270 if (omp_declare_simd_clauses)
2271 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2272 omp_declare_simd_clauses);
2273 init_loc = c_parser_peek_token (parser)->location;
2274 rich_location richloc (line_table, init_loc);
2275 start_init (d, asm_name, global_bindings_p (), &richloc);
2276 /* A parameter is initialized, which is invalid. Don't
2277 attempt to instrument the initializer. */
2278 int flag_sanitize_save = flag_sanitize;
2279 if (TREE_CODE (d) == PARM_DECL)
2280 flag_sanitize = 0;
2281 init = c_parser_initializer (parser);
2282 flag_sanitize = flag_sanitize_save;
2283 finish_init ();
2284 }
2285 if (oacc_routine_data)
2286 c_finish_oacc_routine (oacc_routine_data, d, false);
2287 if (d != error_mark_node)
2288 {
2289 maybe_warn_string_init (init_loc, TREE_TYPE (d), init);
2290 finish_decl (d, init_loc, init.value,
2291 init.original_type, asm_name);
2292 }
2293 }
2294 else
2295 {
2296 if (auto_type_p)
2297 {
2298 error_at (here,
2299 "%<__auto_type%> requires an initialized "
2300 "data declaration");
2301 c_parser_skip_to_end_of_block_or_statement (parser);
2302 return;
2303 }
2304
2305 location_t lastloc = UNKNOWN_LOCATION;
2306 tree attrs = chainon (postfix_attrs, all_prefix_attrs);
2307 tree d = start_decl (declarator, specs, false, attrs, &lastloc);
2308 if (d && TREE_CODE (d) == FUNCTION_DECL)
2309 {
2310 /* Find the innermost declarator that is neither cdk_id
2311 nor cdk_attrs. */
2312 const struct c_declarator *decl = declarator;
2313 const struct c_declarator *last_non_id_attrs = NULL;
2314
2315 while (decl)
2316 switch (decl->kind)
2317 {
2318 case cdk_array:
2319 case cdk_function:
2320 case cdk_pointer:
2321 last_non_id_attrs = decl;
2322 decl = decl->declarator;
2323 break;
2324
2325 case cdk_attrs:
2326 decl = decl->declarator;
2327 break;
2328
2329 case cdk_id:
2330 decl = 0;
2331 break;
2332
2333 default:
2334 gcc_unreachable ();
2335 }
2336
2337 /* If it exists and is cdk_function declaration whose
2338 arguments have not been set yet, use its arguments. */
2339 if (last_non_id_attrs
2340 && last_non_id_attrs->kind == cdk_function)
2341 {
2342 tree parms = last_non_id_attrs->u.arg_info->parms;
2343 if (DECL_ARGUMENTS (d) == NULL_TREE
2344 && DECL_INITIAL (d) == NULL_TREE)
2345 DECL_ARGUMENTS (d) = parms;
2346
2347 warn_parm_array_mismatch (lastloc, d, parms);
2348 }
2349 }
2350 if (omp_declare_simd_clauses)
2351 {
2352 tree parms = NULL_TREE;
2353 if (d && TREE_CODE (d) == FUNCTION_DECL)
2354 {
2355 struct c_declarator *ce = declarator;
2356 while (ce != NULL)
2357 if (ce->kind == cdk_function)
2358 {
2359 parms = ce->u.arg_info->parms;
2360 break;
2361 }
2362 else
2363 ce = ce->declarator;
2364 }
2365 if (parms)
2366 temp_store_parm_decls (d, parms);
2367 c_finish_omp_declare_simd (parser, d, parms,
2368 omp_declare_simd_clauses);
2369 if (parms)
2370 temp_pop_parm_decls ();
2371 }
2372 if (oacc_routine_data)
2373 c_finish_oacc_routine (oacc_routine_data, d, false);
2374 if (d)
2375 finish_decl (d, UNKNOWN_LOCATION, NULL_TREE,
2376 NULL_TREE, asm_name);
2377
2378 if (c_parser_next_token_is_keyword (parser, RID_IN))
2379 {
2380 if (d)
2381 *objc_foreach_object_declaration = d;
2382 else
2383 *objc_foreach_object_declaration = error_mark_node;
2384 }
2385 }
2386 if (c_parser_next_token_is (parser, CPP_COMMA))
2387 {
2388 if (auto_type_p)
2389 {
2390 error_at (here,
2391 "%<__auto_type%> may only be used with"
2392 " a single declarator");
2393 c_parser_skip_to_end_of_block_or_statement (parser);
2394 return;
2395 }
2396 c_parser_consume_token (parser);
2397 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2398 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
2399 prefix_attrs);
2400 else
2401 all_prefix_attrs = prefix_attrs;
2402 continue;
2403 }
2404 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2405 {
2406 c_parser_consume_token (parser);
2407 return;
2408 }
2409 else if (c_parser_next_token_is_keyword (parser, RID_IN))
2410 {
2411 /* This can only happen in Objective-C: we found the
2412 'in' that terminates the declaration inside an
2413 Objective-C foreach statement. Do not consume the
2414 token, so that the caller can use it to determine
2415 that this indeed is a foreach context. */
2416 return;
2417 }
2418 else
2419 {
2420 c_parser_error (parser, "expected %<,%> or %<;%>");
2421 c_parser_skip_to_end_of_block_or_statement (parser);
2422 return;
2423 }
2424 }
2425 else if (auto_type_p)
2426 {
2427 error_at (here,
2428 "%<__auto_type%> requires an initialized data declaration");
2429 c_parser_skip_to_end_of_block_or_statement (parser);
2430 return;
2431 }
2432 else if (!fndef_ok)
2433 {
2434 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, "
2435 "%<asm%> or %<__attribute__%>");
2436 c_parser_skip_to_end_of_block_or_statement (parser);
2437 return;
2438 }
2439 /* Function definition (nested or otherwise). */
2440 if (nested)
2441 {
2442 pedwarn (here, OPT_Wpedantic, "ISO C forbids nested functions");
2443 c_push_function_context ();
2444 }
2445 if (!start_function (specs, declarator, all_prefix_attrs))
2446 {
2447 /* At this point we've consumed:
2448 declaration-specifiers declarator
2449 and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2450 RID_ASM, RID_ATTRIBUTE, or RID_IN,
2451 but the
2452 declaration-specifiers declarator
2453 aren't grokkable as a function definition, so we have
2454 an error. */
2455 gcc_assert (!c_parser_next_token_is (parser, CPP_SEMICOLON));
2456 if (c_parser_next_token_starts_declspecs (parser))
2457 {
2458 /* If we have
2459 declaration-specifiers declarator decl-specs
2460 then assume we have a missing semicolon, which would
2461 give us:
2462 declaration-specifiers declarator decl-specs
2463 ^
2464 ;
2465 <~~~~~~~~~ declaration ~~~~~~~~~~>
2466 Use c_parser_require to get an error with a fix-it hint. */
2467 c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>");
2468 parser->error = false;
2469 }
2470 else
2471 {
2472 /* This can appear in many cases looking nothing like a
2473 function definition, so we don't give a more specific
2474 error suggesting there was one. */
2475 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2476 "or %<__attribute__%>");
2477 }
2478 if (nested)
2479 c_pop_function_context ();
2480 break;
2481 }
2482
2483 if (DECL_DECLARED_INLINE_P (current_function_decl))
2484 tv = TV_PARSE_INLINE;
2485 else
2486 tv = TV_PARSE_FUNC;
2487 auto_timevar at (g_timer, tv);
2488
2489 /* Parse old-style parameter declarations. ??? Attributes are
2490 not allowed to start declaration specifiers here because of a
2491 syntax conflict between a function declaration with attribute
2492 suffix and a function definition with an attribute prefix on
2493 first old-style parameter declaration. Following the old
2494 parser, they are not accepted on subsequent old-style
2495 parameter declarations either. However, there is no
2496 ambiguity after the first declaration, nor indeed on the
2497 first as long as we don't allow postfix attributes after a
2498 declarator with a nonempty identifier list in a definition;
2499 and postfix attributes have never been accepted here in
2500 function definitions either. */
2501 while (c_parser_next_token_is_not (parser, CPP_EOF)
2502 && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE))
2503 c_parser_declaration_or_fndef (parser, false, false, false,
2504 true, false);
2505 store_parm_decls ();
2506 if (omp_declare_simd_clauses)
2507 c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE,
2508 omp_declare_simd_clauses);
2509 if (oacc_routine_data)
2510 c_finish_oacc_routine (oacc_routine_data, current_function_decl, true);
2511 location_t startloc = c_parser_peek_token (parser)->location;
2512 DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
2513 = startloc;
2514 location_t endloc = startloc;
2515
2516 /* If the definition was marked with __RTL, use the RTL parser now,
2517 consuming the function body. */
2518 if (specs->declspec_il == cdil_rtl)
2519 {
2520 endloc = c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass);
2521
2522 /* Normally, store_parm_decls sets next_is_function_body,
2523 anticipating a function body. We need a push_scope/pop_scope
2524 pair to flush out this state, or subsequent function parsing
2525 will go wrong. */
2526 push_scope ();
2527 pop_scope ();
2528
2529 finish_function (endloc);
2530 return;
2531 }
2532 /* If the definition was marked with __GIMPLE then parse the
2533 function body as GIMPLE. */
2534 else if (specs->declspec_il != cdil_none)
2535 {
2536 bool saved = in_late_binary_op;
2537 in_late_binary_op = true;
2538 c_parser_parse_gimple_body (parser, specs->gimple_or_rtl_pass,
2539 specs->declspec_il,
2540 specs->entry_bb_count);
2541 in_late_binary_op = saved;
2542 }
2543 else
2544 fnbody = c_parser_compound_statement (parser, &endloc);
2545 tree fndecl = current_function_decl;
2546 if (nested)
2547 {
2548 tree decl = current_function_decl;
2549 /* Mark nested functions as needing static-chain initially.
2550 lower_nested_functions will recompute it but the
2551 DECL_STATIC_CHAIN flag is also used before that happens,
2552 by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
2553 DECL_STATIC_CHAIN (decl) = 1;
2554 add_stmt (fnbody);
2555 finish_function (endloc);
2556 c_pop_function_context ();
2557 add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));
2558 }
2559 else
2560 {
2561 if (fnbody)
2562 add_stmt (fnbody);
2563 finish_function (endloc);
2564 }
2565 /* Get rid of the empty stmt list for GIMPLE/RTL. */
2566 if (specs->declspec_il != cdil_none)
2567 DECL_SAVED_TREE (fndecl) = NULL_TREE;
2568
2569 break;
2570 }
2571 }
2572
2573 /* Parse an asm-definition (asm() outside a function body). This is a
2574 GNU extension.
2575
2576 asm-definition:
2577 simple-asm-expr ;
2578 */
2579
2580 static void
2581 c_parser_asm_definition (c_parser *parser)
2582 {
2583 tree asm_str = c_parser_simple_asm_expr (parser);
2584 if (asm_str)
2585 symtab->finalize_toplevel_asm (asm_str);
2586 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
2587 }
2588
2589 /* Parse a static assertion (C11 6.7.10).
2590
2591 static_assert-declaration:
2592 static_assert-declaration-no-semi ;
2593 */
2594
2595 static void
2596 c_parser_static_assert_declaration (c_parser *parser)
2597 {
2598 c_parser_static_assert_declaration_no_semi (parser);
2599 if (parser->error
2600 || !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
2601 c_parser_skip_to_end_of_block_or_statement (parser);
2602 }
2603
2604 /* Parse a static assertion (C11 6.7.10), without the trailing
2605 semicolon.
2606
2607 static_assert-declaration-no-semi:
2608 _Static_assert ( constant-expression , string-literal )
2609
2610 C2X:
2611 static_assert-declaration-no-semi:
2612 _Static_assert ( constant-expression )
2613 */
2614
2615 static void
2616 c_parser_static_assert_declaration_no_semi (c_parser *parser)
2617 {
2618 location_t assert_loc, value_loc;
2619 tree value;
2620 tree string = NULL_TREE;
2621
2622 gcc_assert (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT));
2623 assert_loc = c_parser_peek_token (parser)->location;
2624 if (flag_isoc99)
2625 pedwarn_c99 (assert_loc, OPT_Wpedantic,
2626 "ISO C99 does not support %<_Static_assert%>");
2627 else
2628 pedwarn_c99 (assert_loc, OPT_Wpedantic,
2629 "ISO C90 does not support %<_Static_assert%>");
2630 c_parser_consume_token (parser);
2631 matching_parens parens;
2632 if (!parens.require_open (parser))
2633 return;
2634 location_t value_tok_loc = c_parser_peek_token (parser)->location;
2635 value = c_parser_expr_no_commas (parser, NULL).value;
2636 value_loc = EXPR_LOC_OR_LOC (value, value_tok_loc);
2637 if (c_parser_next_token_is (parser, CPP_COMMA))
2638 {
2639 c_parser_consume_token (parser);
2640 switch (c_parser_peek_token (parser)->type)
2641 {
2642 case CPP_STRING:
2643 case CPP_STRING16:
2644 case CPP_STRING32:
2645 case CPP_WSTRING:
2646 case CPP_UTF8STRING:
2647 string = c_parser_string_literal (parser, false, true).value;
2648 break;
2649 default:
2650 c_parser_error (parser, "expected string literal");
2651 return;
2652 }
2653 }
2654 else if (flag_isoc11)
2655 /* If pedantic for pre-C11, the use of _Static_assert itself will
2656 have been diagnosed, so do not also diagnose the use of this
2657 new C2X feature of _Static_assert. */
2658 pedwarn_c11 (assert_loc, OPT_Wpedantic,
2659 "ISO C11 does not support omitting the string in "
2660 "%<_Static_assert%>");
2661 parens.require_close (parser);
2662
2663 if (!INTEGRAL_TYPE_P (TREE_TYPE (value)))
2664 {
2665 error_at (value_loc, "expression in static assertion is not an integer");
2666 return;
2667 }
2668 if (TREE_CODE (value) != INTEGER_CST)
2669 {
2670 value = c_fully_fold (value, false, NULL);
2671 /* Strip no-op conversions. */
2672 STRIP_TYPE_NOPS (value);
2673 if (TREE_CODE (value) == INTEGER_CST)
2674 pedwarn (value_loc, OPT_Wpedantic, "expression in static assertion "
2675 "is not an integer constant expression");
2676 }
2677 if (TREE_CODE (value) != INTEGER_CST)
2678 {
2679 error_at (value_loc, "expression in static assertion is not constant");
2680 return;
2681 }
2682 constant_expression_warning (value);
2683 if (integer_zerop (value))
2684 {
2685 if (string)
2686 error_at (assert_loc, "static assertion failed: %E", string);
2687 else
2688 error_at (assert_loc, "static assertion failed");
2689 }
2690 }
2691
2692 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
2693 6.7, C11 6.7), adding them to SPECS (which may already include some).
2694 Storage class specifiers are accepted iff SCSPEC_OK; type
2695 specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
2696 accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start
2697 iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK. In
2698 addition to the syntax shown, standard attributes are accepted at
2699 the start iff START_STD_ATTR_OK and at the end iff END_STD_ATTR_OK;
2700 unlike gnu-attributes, they are not accepted in the middle of the
2701 list. (This combines various different syntax productions in the C
2702 standard, and in some cases gnu-attributes and standard attributes
2703 at the start may already have been parsed before this function is
2704 called.)
2705
2706 declaration-specifiers:
2707 storage-class-specifier declaration-specifiers[opt]
2708 type-specifier declaration-specifiers[opt]
2709 type-qualifier declaration-specifiers[opt]
2710 function-specifier declaration-specifiers[opt]
2711 alignment-specifier declaration-specifiers[opt]
2712
2713 Function specifiers (inline) are from C99, and are currently
2714 handled as storage class specifiers, as is __thread. Alignment
2715 specifiers are from C11.
2716
2717 C90 6.5.1, C99 6.7.1, C11 6.7.1:
2718 storage-class-specifier:
2719 typedef
2720 extern
2721 static
2722 auto
2723 register
2724 _Thread_local
2725
2726 (_Thread_local is new in C11.)
2727
2728 C99 6.7.4, C11 6.7.4:
2729 function-specifier:
2730 inline
2731 _Noreturn
2732
2733 (_Noreturn is new in C11.)
2734
2735 C90 6.5.2, C99 6.7.2, C11 6.7.2:
2736 type-specifier:
2737 void
2738 char
2739 short
2740 int
2741 long
2742 float
2743 double
2744 signed
2745 unsigned
2746 _Bool
2747 _Complex
2748 [_Imaginary removed in C99 TC2]
2749 struct-or-union-specifier
2750 enum-specifier
2751 typedef-name
2752 atomic-type-specifier
2753
2754 (_Bool and _Complex are new in C99.)
2755 (atomic-type-specifier is new in C11.)
2756
2757 C90 6.5.3, C99 6.7.3, C11 6.7.3:
2758
2759 type-qualifier:
2760 const
2761 restrict
2762 volatile
2763 address-space-qualifier
2764 _Atomic
2765
2766 (restrict is new in C99.)
2767 (_Atomic is new in C11.)
2768
2769 GNU extensions:
2770
2771 declaration-specifiers:
2772 gnu-attributes declaration-specifiers[opt]
2773
2774 type-qualifier:
2775 address-space
2776
2777 address-space:
2778 identifier recognized by the target
2779
2780 storage-class-specifier:
2781 __thread
2782
2783 type-specifier:
2784 typeof-specifier
2785 __auto_type
2786 __intN
2787 _Decimal32
2788 _Decimal64
2789 _Decimal128
2790 _Fract
2791 _Accum
2792 _Sat
2793
2794 (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
2795 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
2796
2797 atomic-type-specifier
2798 _Atomic ( type-name )
2799
2800 Objective-C:
2801
2802 type-specifier:
2803 class-name objc-protocol-refs[opt]
2804 typedef-name objc-protocol-refs
2805 objc-protocol-refs
2806 */
2807
2808 void
2809 c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
2810 bool scspec_ok, bool typespec_ok, bool start_attr_ok,
2811 bool alignspec_ok, bool auto_type_ok,
2812 bool start_std_attr_ok, bool end_std_attr_ok,
2813 enum c_lookahead_kind la)
2814 {
2815 bool attrs_ok = start_attr_ok;
2816 bool seen_type = specs->typespec_kind != ctsk_none;
2817
2818 if (!typespec_ok)
2819 gcc_assert (la == cla_prefer_id);
2820
2821 if (start_std_attr_ok
2822 && c_parser_nth_token_starts_std_attributes (parser, 1))
2823 {
2824 gcc_assert (!specs->non_std_attrs_seen_p);
2825 location_t loc = c_parser_peek_token (parser)->location;
2826 tree attrs = c_parser_std_attribute_specifier_sequence (parser);
2827 declspecs_add_attrs (loc, specs, attrs);
2828 specs->non_std_attrs_seen_p = false;
2829 }
2830
2831 while (c_parser_next_token_is (parser, CPP_NAME)
2832 || c_parser_next_token_is (parser, CPP_KEYWORD)
2833 || (c_dialect_objc () && c_parser_next_token_is (parser, CPP_LESS)))
2834 {
2835 struct c_typespec t;
2836 tree attrs;
2837 tree align;
2838 location_t loc = c_parser_peek_token (parser)->location;
2839
2840 /* If we cannot accept a type, exit if the next token must start
2841 one. Also, if we already have seen a tagged definition,
2842 a typename would be an error anyway and likely the user
2843 has simply forgotten a semicolon, so we exit. */
2844 if ((!typespec_ok || specs->typespec_kind == ctsk_tagdef)
2845 && c_parser_next_tokens_start_typename (parser, la)
2846 && !c_parser_next_token_is_qualifier (parser)
2847 && !c_parser_next_token_is_keyword (parser, RID_ALIGNAS))
2848 break;
2849
2850 if (c_parser_next_token_is (parser, CPP_NAME))
2851 {
2852 c_token *name_token = c_parser_peek_token (parser);
2853 tree value = name_token->value;
2854 c_id_kind kind = name_token->id_kind;
2855
2856 if (kind == C_ID_ADDRSPACE)
2857 {
2858 addr_space_t as
2859 = name_token->keyword - RID_FIRST_ADDR_SPACE;
2860 declspecs_add_addrspace (name_token->location, specs, as);
2861 c_parser_consume_token (parser);
2862 attrs_ok = true;
2863 continue;
2864 }
2865
2866 gcc_assert (!c_parser_next_token_is_qualifier (parser));
2867
2868 /* If we cannot accept a type, and the next token must start one,
2869 exit. Do the same if we already have seen a tagged definition,
2870 since it would be an error anyway and likely the user has simply
2871 forgotten a semicolon. */
2872 if (seen_type || !c_parser_next_tokens_start_typename (parser, la))
2873 break;
2874
2875 /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
2876 a C_ID_CLASSNAME. */
2877 c_parser_consume_token (parser);
2878 seen_type = true;
2879 attrs_ok = true;
2880 if (kind == C_ID_ID)
2881 {
2882 error_at (loc, "unknown type name %qE", value);
2883 t.kind = ctsk_typedef;
2884 t.spec = error_mark_node;
2885 }
2886 else if (kind == C_ID_TYPENAME
2887 && (!c_dialect_objc ()
2888 || c_parser_next_token_is_not (parser, CPP_LESS)))
2889 {
2890 t.kind = ctsk_typedef;
2891 /* For a typedef name, record the meaning, not the name.
2892 In case of 'foo foo, bar;'. */
2893 t.spec = lookup_name (value);
2894 }
2895 else
2896 {
2897 tree proto = NULL_TREE;
2898 gcc_assert (c_dialect_objc ());
2899 t.kind = ctsk_objc;
2900 if (c_parser_next_token_is (parser, CPP_LESS))
2901 proto = c_parser_objc_protocol_refs (parser);
2902 t.spec = objc_get_protocol_qualified_type (value, proto);
2903 }
2904 t.expr = NULL_TREE;
2905 t.expr_const_operands = true;
2906 declspecs_add_type (name_token->location, specs, t);
2907 continue;
2908 }
2909 if (c_parser_next_token_is (parser, CPP_LESS))
2910 {
2911 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
2912 nisse@lysator.liu.se. */
2913 tree proto;
2914 gcc_assert (c_dialect_objc ());
2915 if (!typespec_ok || seen_type)
2916 break;
2917 proto = c_parser_objc_protocol_refs (parser);
2918 t.kind = ctsk_objc;
2919 t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto);
2920 t.expr = NULL_TREE;
2921 t.expr_const_operands = true;
2922 declspecs_add_type (loc, specs, t);
2923 continue;
2924 }
2925 gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD));
2926 switch (c_parser_peek_token (parser)->keyword)
2927 {
2928 case RID_STATIC:
2929 case RID_EXTERN:
2930 case RID_REGISTER:
2931 case RID_TYPEDEF:
2932 case RID_INLINE:
2933 case RID_NORETURN:
2934 case RID_AUTO:
2935 case RID_THREAD:
2936 if (!scspec_ok)
2937 goto out;
2938 attrs_ok = true;
2939 /* TODO: Distinguish between function specifiers (inline, noreturn)
2940 and storage class specifiers, either here or in
2941 declspecs_add_scspec. */
2942 declspecs_add_scspec (loc, specs,
2943 c_parser_peek_token (parser)->value);
2944 c_parser_consume_token (parser);
2945 break;
2946 case RID_AUTO_TYPE:
2947 if (!auto_type_ok)
2948 goto out;
2949 /* Fall through. */
2950 case RID_UNSIGNED:
2951 case RID_LONG:
2952 case RID_SHORT:
2953 case RID_SIGNED:
2954 case RID_COMPLEX:
2955 case RID_INT:
2956 case RID_CHAR:
2957 case RID_FLOAT:
2958 case RID_DOUBLE:
2959 case RID_VOID:
2960 case RID_DFLOAT32:
2961 case RID_DFLOAT64:
2962 case RID_DFLOAT128:
2963 CASE_RID_FLOATN_NX:
2964 case RID_BOOL:
2965 case RID_FRACT:
2966 case RID_ACCUM:
2967 case RID_SAT:
2968 case RID_INT_N_0:
2969 case RID_INT_N_1:
2970 case RID_INT_N_2:
2971 case RID_INT_N_3:
2972 if (!typespec_ok)
2973 goto out;
2974 attrs_ok = true;
2975 seen_type = true;
2976 if (c_dialect_objc ())
2977 parser->objc_need_raw_identifier = true;
2978 t.kind = ctsk_resword;
2979 t.spec = c_parser_peek_token (parser)->value;
2980 t.expr = NULL_TREE;
2981 t.expr_const_operands = true;
2982 declspecs_add_type (loc, specs, t);
2983 c_parser_consume_token (parser);
2984 break;
2985 case RID_ENUM:
2986 if (!typespec_ok)
2987 goto out;
2988 attrs_ok = true;
2989 seen_type = true;
2990 t = c_parser_enum_specifier (parser);
2991 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
2992 declspecs_add_type (loc, specs, t);
2993 break;
2994 case RID_STRUCT:
2995 case RID_UNION:
2996 if (!typespec_ok)
2997 goto out;
2998 attrs_ok = true;
2999 seen_type = true;
3000 t = c_parser_struct_or_union_specifier (parser);
3001 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
3002 declspecs_add_type (loc, specs, t);
3003 break;
3004 case RID_TYPEOF:
3005 /* ??? The old parser rejected typeof after other type
3006 specifiers, but is a syntax error the best way of
3007 handling this? */
3008 if (!typespec_ok || seen_type)
3009 goto out;
3010 attrs_ok = true;
3011 seen_type = true;
3012 t = c_parser_typeof_specifier (parser);
3013 declspecs_add_type (loc, specs, t);
3014 break;
3015 case RID_ATOMIC:
3016 /* C parser handling of Objective-C constructs needs
3017 checking for correct lvalue-to-rvalue conversions, and
3018 the code in build_modify_expr handling various
3019 Objective-C cases, and that in build_unary_op handling
3020 Objective-C cases for increment / decrement, also needs
3021 updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
3022 and objc_types_are_equivalent may also need updates. */
3023 if (c_dialect_objc ())
3024 sorry ("%<_Atomic%> in Objective-C");
3025 if (flag_isoc99)
3026 pedwarn_c99 (loc, OPT_Wpedantic,
3027 "ISO C99 does not support the %<_Atomic%> qualifier");
3028 else
3029 pedwarn_c99 (loc, OPT_Wpedantic,
3030 "ISO C90 does not support the %<_Atomic%> qualifier");
3031 attrs_ok = true;
3032 tree value;
3033 value = c_parser_peek_token (parser)->value;
3034 c_parser_consume_token (parser);
3035 if (typespec_ok && c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3036 {
3037 /* _Atomic ( type-name ). */
3038 seen_type = true;
3039 c_parser_consume_token (parser);
3040 struct c_type_name *type = c_parser_type_name (parser);
3041 t.kind = ctsk_typeof;
3042 t.spec = error_mark_node;
3043 t.expr = NULL_TREE;
3044 t.expr_const_operands = true;
3045 if (type != NULL)
3046 t.spec = groktypename (type, &t.expr,
3047 &t.expr_const_operands);
3048 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3049 "expected %<)%>");
3050 if (t.spec != error_mark_node)
3051 {
3052 if (TREE_CODE (t.spec) == ARRAY_TYPE)
3053 error_at (loc, "%<_Atomic%>-qualified array type");
3054 else if (TREE_CODE (t.spec) == FUNCTION_TYPE)
3055 error_at (loc, "%<_Atomic%>-qualified function type");
3056 else if (TYPE_QUALS (t.spec) != TYPE_UNQUALIFIED)
3057 error_at (loc, "%<_Atomic%> applied to a qualified type");
3058 else
3059 t.spec = c_build_qualified_type (t.spec, TYPE_QUAL_ATOMIC);
3060 }
3061 declspecs_add_type (loc, specs, t);
3062 }
3063 else
3064 declspecs_add_qual (loc, specs, value);
3065 break;
3066 case RID_CONST:
3067 case RID_VOLATILE:
3068 case RID_RESTRICT:
3069 attrs_ok = true;
3070 declspecs_add_qual (loc, specs, c_parser_peek_token (parser)->value);
3071 c_parser_consume_token (parser);
3072 break;
3073 case RID_ATTRIBUTE:
3074 if (!attrs_ok)
3075 goto out;
3076 attrs = c_parser_gnu_attributes (parser);
3077 declspecs_add_attrs (loc, specs, attrs);
3078 break;
3079 case RID_ALIGNAS:
3080 if (!alignspec_ok)
3081 goto out;
3082 align = c_parser_alignas_specifier (parser);
3083 declspecs_add_alignas (loc, specs, align);
3084 break;
3085 case RID_GIMPLE:
3086 if (! flag_gimple)
3087 error_at (loc, "%<__GIMPLE%> only valid with %<-fgimple%>");
3088 c_parser_consume_token (parser);
3089 specs->declspec_il = cdil_gimple;
3090 specs->locations[cdw_gimple] = loc;
3091 c_parser_gimple_or_rtl_pass_list (parser, specs);
3092 break;
3093 case RID_RTL:
3094 c_parser_consume_token (parser);
3095 specs->declspec_il = cdil_rtl;
3096 specs->locations[cdw_rtl] = loc;
3097 c_parser_gimple_or_rtl_pass_list (parser, specs);
3098 break;
3099 default:
3100 goto out;
3101 }
3102 }
3103 out:
3104 if (end_std_attr_ok
3105 && c_parser_nth_token_starts_std_attributes (parser, 1))
3106 specs->postfix_attrs = c_parser_std_attribute_specifier_sequence (parser);
3107 }
3108
3109 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
3110
3111 enum-specifier:
3112 enum gnu-attributes[opt] identifier[opt] { enumerator-list }
3113 gnu-attributes[opt]
3114 enum gnu-attributes[opt] identifier[opt] { enumerator-list , }
3115 gnu-attributes[opt]
3116 enum gnu-attributes[opt] identifier
3117
3118 The form with trailing comma is new in C99. The forms with
3119 gnu-attributes are GNU extensions. In GNU C, we accept any expression
3120 without commas in the syntax (assignment expressions, not just
3121 conditional expressions); assignment expressions will be diagnosed
3122 as non-constant.
3123
3124 enumerator-list:
3125 enumerator
3126 enumerator-list , enumerator
3127
3128 enumerator:
3129 enumeration-constant attribute-specifier-sequence[opt]
3130 enumeration-constant attribute-specifier-sequence[opt]
3131 = constant-expression
3132
3133 GNU Extensions:
3134
3135 enumerator:
3136 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3137 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
3138 = constant-expression
3139
3140 */
3141
3142 static struct c_typespec
3143 c_parser_enum_specifier (c_parser *parser)
3144 {
3145 struct c_typespec ret;
3146 bool have_std_attrs;
3147 tree std_attrs = NULL_TREE;
3148 tree attrs;
3149 tree ident = NULL_TREE;
3150 location_t enum_loc;
3151 location_t ident_loc = UNKNOWN_LOCATION; /* Quiet warning. */
3152 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ENUM));
3153 c_parser_consume_token (parser);
3154 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3155 if (have_std_attrs)
3156 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3157 attrs = c_parser_gnu_attributes (parser);
3158 enum_loc = c_parser_peek_token (parser)->location;
3159 /* Set the location in case we create a decl now. */
3160 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3161 if (c_parser_next_token_is (parser, CPP_NAME))
3162 {
3163 ident = c_parser_peek_token (parser)->value;
3164 ident_loc = c_parser_peek_token (parser)->location;
3165 enum_loc = ident_loc;
3166 c_parser_consume_token (parser);
3167 }
3168 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3169 {
3170 /* Parse an enum definition. */
3171 struct c_enum_contents the_enum;
3172 tree type;
3173 tree postfix_attrs;
3174 /* We chain the enumerators in reverse order, then put them in
3175 forward order at the end. */
3176 tree values;
3177 timevar_push (TV_PARSE_ENUM);
3178 type = start_enum (enum_loc, &the_enum, ident);
3179 values = NULL_TREE;
3180 c_parser_consume_token (parser);
3181 while (true)
3182 {
3183 tree enum_id;
3184 tree enum_value;
3185 tree enum_decl;
3186 bool seen_comma;
3187 c_token *token;
3188 location_t comma_loc = UNKNOWN_LOCATION; /* Quiet warning. */
3189 location_t decl_loc, value_loc;
3190 if (c_parser_next_token_is_not (parser, CPP_NAME))
3191 {
3192 /* Give a nicer error for "enum {}". */
3193 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3194 && !parser->error)
3195 {
3196 error_at (c_parser_peek_token (parser)->location,
3197 "empty enum is invalid");
3198 parser->error = true;
3199 }
3200 else
3201 c_parser_error (parser, "expected identifier");
3202 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3203 values = error_mark_node;
3204 break;
3205 }
3206 token = c_parser_peek_token (parser);
3207 enum_id = token->value;
3208 /* Set the location in case we create a decl now. */
3209 c_parser_set_source_position_from_token (token);
3210 decl_loc = value_loc = token->location;
3211 c_parser_consume_token (parser);
3212 /* Parse any specified attributes. */
3213 tree std_attrs = NULL_TREE;
3214 if (c_parser_nth_token_starts_std_attributes (parser, 1))
3215 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3216 tree enum_attrs = chainon (std_attrs,
3217 c_parser_gnu_attributes (parser));
3218 if (c_parser_next_token_is (parser, CPP_EQ))
3219 {
3220 c_parser_consume_token (parser);
3221 value_loc = c_parser_peek_token (parser)->location;
3222 enum_value = c_parser_expr_no_commas (parser, NULL).value;
3223 }
3224 else
3225 enum_value = NULL_TREE;
3226 enum_decl = build_enumerator (decl_loc, value_loc,
3227 &the_enum, enum_id, enum_value);
3228 if (enum_attrs)
3229 decl_attributes (&TREE_PURPOSE (enum_decl), enum_attrs, 0);
3230 TREE_CHAIN (enum_decl) = values;
3231 values = enum_decl;
3232 seen_comma = false;
3233 if (c_parser_next_token_is (parser, CPP_COMMA))
3234 {
3235 comma_loc = c_parser_peek_token (parser)->location;
3236 seen_comma = true;
3237 c_parser_consume_token (parser);
3238 }
3239 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3240 {
3241 if (seen_comma)
3242 pedwarn_c90 (comma_loc, OPT_Wpedantic,
3243 "comma at end of enumerator list");
3244 c_parser_consume_token (parser);
3245 break;
3246 }
3247 if (!seen_comma)
3248 {
3249 c_parser_error (parser, "expected %<,%> or %<}%>");
3250 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3251 values = error_mark_node;
3252 break;
3253 }
3254 }
3255 postfix_attrs = c_parser_gnu_attributes (parser);
3256 ret.spec = finish_enum (type, nreverse (values),
3257 chainon (std_attrs,
3258 chainon (attrs, postfix_attrs)));
3259 ret.kind = ctsk_tagdef;
3260 ret.expr = NULL_TREE;
3261 ret.expr_const_operands = true;
3262 timevar_pop (TV_PARSE_ENUM);
3263 return ret;
3264 }
3265 else if (!ident)
3266 {
3267 c_parser_error (parser, "expected %<{%>");
3268 ret.spec = error_mark_node;
3269 ret.kind = ctsk_tagref;
3270 ret.expr = NULL_TREE;
3271 ret.expr_const_operands = true;
3272 return ret;
3273 }
3274 /* Attributes may only appear when the members are defined or in
3275 certain forward declarations (treat enum forward declarations in
3276 GNU C analogously to struct and union forward declarations in
3277 standard C). */
3278 if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3279 c_parser_error (parser, "expected %<;%>");
3280 ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident, have_std_attrs,
3281 std_attrs);
3282 /* In ISO C, enumerated types can be referred to only if already
3283 defined. */
3284 if (pedantic && !COMPLETE_TYPE_P (ret.spec))
3285 {
3286 gcc_assert (ident);
3287 pedwarn (enum_loc, OPT_Wpedantic,
3288 "ISO C forbids forward references to %<enum%> types");
3289 }
3290 return ret;
3291 }
3292
3293 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3294
3295 struct-or-union-specifier:
3296 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3297 identifier[opt] { struct-contents } gnu-attributes[opt]
3298 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
3299 identifier
3300
3301 struct-contents:
3302 struct-declaration-list
3303
3304 struct-declaration-list:
3305 struct-declaration ;
3306 struct-declaration-list struct-declaration ;
3307
3308 GNU extensions:
3309
3310 struct-contents:
3311 empty
3312 struct-declaration
3313 struct-declaration-list struct-declaration
3314
3315 struct-declaration-list:
3316 struct-declaration-list ;
3317 ;
3318
3319 (Note that in the syntax here, unlike that in ISO C, the semicolons
3320 are included here rather than in struct-declaration, in order to
3321 describe the syntax with extra semicolons and missing semicolon at
3322 end.)
3323
3324 Objective-C:
3325
3326 struct-declaration-list:
3327 @defs ( class-name )
3328
3329 (Note this does not include a trailing semicolon, but can be
3330 followed by further declarations, and gets a pedwarn-if-pedantic
3331 when followed by a semicolon.) */
3332
3333 static struct c_typespec
3334 c_parser_struct_or_union_specifier (c_parser *parser)
3335 {
3336 struct c_typespec ret;
3337 bool have_std_attrs;
3338 tree std_attrs = NULL_TREE;
3339 tree attrs;
3340 tree ident = NULL_TREE;
3341 location_t struct_loc;
3342 location_t ident_loc = UNKNOWN_LOCATION;
3343 enum tree_code code;
3344 switch (c_parser_peek_token (parser)->keyword)
3345 {
3346 case RID_STRUCT:
3347 code = RECORD_TYPE;
3348 break;
3349 case RID_UNION:
3350 code = UNION_TYPE;
3351 break;
3352 default:
3353 gcc_unreachable ();
3354 }
3355 struct_loc = c_parser_peek_token (parser)->location;
3356 c_parser_consume_token (parser);
3357 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
3358 if (have_std_attrs)
3359 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
3360 attrs = c_parser_gnu_attributes (parser);
3361
3362 /* Set the location in case we create a decl now. */
3363 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3364
3365 if (c_parser_next_token_is (parser, CPP_NAME))
3366 {
3367 ident = c_parser_peek_token (parser)->value;
3368 ident_loc = c_parser_peek_token (parser)->location;
3369 struct_loc = ident_loc;
3370 c_parser_consume_token (parser);
3371 }
3372 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3373 {
3374 /* Parse a struct or union definition. Start the scope of the
3375 tag before parsing components. */
3376 class c_struct_parse_info *struct_info;
3377 tree type = start_struct (struct_loc, code, ident, &struct_info);
3378 tree postfix_attrs;
3379 /* We chain the components in reverse order, then put them in
3380 forward order at the end. Each struct-declaration may
3381 declare multiple components (comma-separated), so we must use
3382 chainon to join them, although when parsing each
3383 struct-declaration we can use TREE_CHAIN directly.
3384
3385 The theory behind all this is that there will be more
3386 semicolon separated fields than comma separated fields, and
3387 so we'll be minimizing the number of node traversals required
3388 by chainon. */
3389 tree contents;
3390 timevar_push (TV_PARSE_STRUCT);
3391 contents = NULL_TREE;
3392 c_parser_consume_token (parser);
3393 /* Handle the Objective-C @defs construct,
3394 e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
3395 if (c_parser_next_token_is_keyword (parser, RID_AT_DEFS))
3396 {
3397 tree name;
3398 gcc_assert (c_dialect_objc ());
3399 c_parser_consume_token (parser);
3400 matching_parens parens;
3401 if (!parens.require_open (parser))
3402 goto end_at_defs;
3403 if (c_parser_next_token_is (parser, CPP_NAME)
3404 && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)
3405 {
3406 name = c_parser_peek_token (parser)->value;
3407 c_parser_consume_token (parser);
3408 }
3409 else
3410 {
3411 c_parser_error (parser, "expected class name");
3412 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
3413 goto end_at_defs;
3414 }
3415 parens.skip_until_found_close (parser);
3416 contents = nreverse (objc_get_class_ivars (name));
3417 }
3418 end_at_defs:
3419 /* Parse the struct-declarations and semicolons. Problems with
3420 semicolons are diagnosed here; empty structures are diagnosed
3421 elsewhere. */
3422 while (true)
3423 {
3424 tree decls;
3425 /* Parse any stray semicolon. */
3426 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3427 {
3428 location_t semicolon_loc
3429 = c_parser_peek_token (parser)->location;
3430 gcc_rich_location richloc (semicolon_loc);
3431 richloc.add_fixit_remove ();
3432 pedwarn (&richloc, OPT_Wpedantic,
3433 "extra semicolon in struct or union specified");
3434 c_parser_consume_token (parser);
3435 continue;
3436 }
3437 /* Stop if at the end of the struct or union contents. */
3438 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3439 {
3440 c_parser_consume_token (parser);
3441 break;
3442 }
3443 /* Accept #pragmas at struct scope. */
3444 if (c_parser_next_token_is (parser, CPP_PRAGMA))
3445 {
3446 c_parser_pragma (parser, pragma_struct, NULL);
3447 continue;
3448 }
3449 /* Parse some comma-separated declarations, but not the
3450 trailing semicolon if any. */
3451 decls = c_parser_struct_declaration (parser);
3452 contents = chainon (decls, contents);
3453 /* If no semicolon follows, either we have a parse error or
3454 are at the end of the struct or union and should
3455 pedwarn. */
3456 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3457 c_parser_consume_token (parser);
3458 else
3459 {
3460 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3461 pedwarn (c_parser_peek_token (parser)->location, 0,
3462 "no semicolon at end of struct or union");
3463 else if (parser->error
3464 || !c_parser_next_token_starts_declspecs (parser))
3465 {
3466 c_parser_error (parser, "expected %<;%>");
3467 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3468 break;
3469 }
3470
3471 /* If we come here, we have already emitted an error
3472 for an expected `;', identifier or `(', and we also
3473 recovered already. Go on with the next field. */
3474 }
3475 }
3476 postfix_attrs = c_parser_gnu_attributes (parser);
3477 ret.spec = finish_struct (struct_loc, type, nreverse (contents),
3478 chainon (std_attrs,
3479 chainon (attrs, postfix_attrs)),
3480 struct_info);
3481 ret.kind = ctsk_tagdef;
3482 ret.expr = NULL_TREE;
3483 ret.expr_const_operands = true;
3484 timevar_pop (TV_PARSE_STRUCT);
3485 return ret;
3486 }
3487 else if (!ident)
3488 {
3489 c_parser_error (parser, "expected %<{%>");
3490 ret.spec = error_mark_node;
3491 ret.kind = ctsk_tagref;
3492 ret.expr = NULL_TREE;
3493 ret.expr_const_operands = true;
3494 return ret;
3495 }
3496 /* Attributes may only appear when the members are defined or in
3497 certain forward declarations. */
3498 if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
3499 c_parser_error (parser, "expected %<;%>");
3500 /* ??? Existing practice is that GNU attributes are ignored after
3501 the struct or union keyword when not defining the members. */
3502 ret = parser_xref_tag (ident_loc, code, ident, have_std_attrs, std_attrs);
3503 return ret;
3504 }
3505
3506 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
3507 *without* the trailing semicolon.
3508
3509 struct-declaration:
3510 attribute-specifier-sequence[opt] specifier-qualifier-list
3511 attribute-specifier-sequence[opt] struct-declarator-list
3512 static_assert-declaration-no-semi
3513
3514 specifier-qualifier-list:
3515 type-specifier specifier-qualifier-list[opt]
3516 type-qualifier specifier-qualifier-list[opt]
3517 alignment-specifier specifier-qualifier-list[opt]
3518 gnu-attributes specifier-qualifier-list[opt]
3519
3520 struct-declarator-list:
3521 struct-declarator
3522 struct-declarator-list , gnu-attributes[opt] struct-declarator
3523
3524 struct-declarator:
3525 declarator gnu-attributes[opt]
3526 declarator[opt] : constant-expression gnu-attributes[opt]
3527
3528 GNU extensions:
3529
3530 struct-declaration:
3531 __extension__ struct-declaration
3532 specifier-qualifier-list
3533
3534 Unlike the ISO C syntax, semicolons are handled elsewhere. The use
3535 of gnu-attributes where shown is a GNU extension. In GNU C, we accept
3536 any expression without commas in the syntax (assignment
3537 expressions, not just conditional expressions); assignment
3538 expressions will be diagnosed as non-constant. */
3539
3540 static tree
3541 c_parser_struct_declaration (c_parser *parser)
3542 {
3543 struct c_declspecs *specs;
3544 tree prefix_attrs;
3545 tree all_prefix_attrs;
3546 tree decls;
3547 location_t decl_loc;
3548 if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
3549 {
3550 int ext;
3551 tree decl;
3552 ext = disable_extension_diagnostics ();
3553 c_parser_consume_token (parser);
3554 decl = c_parser_struct_declaration (parser);
3555 restore_extension_diagnostics (ext);
3556 return decl;
3557 }
3558 if (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
3559 {
3560 c_parser_static_assert_declaration_no_semi (parser);
3561 return NULL_TREE;
3562 }
3563 specs = build_null_declspecs ();
3564 decl_loc = c_parser_peek_token (parser)->location;
3565 /* Strictly by the standard, we shouldn't allow _Alignas here,
3566 but it appears to have been intended to allow it there, so
3567 we're keeping it as it is until WG14 reaches a conclusion
3568 of N1731.
3569 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */
3570 c_parser_declspecs (parser, specs, false, true, true,
3571 true, false, true, true, cla_nonabstract_decl);
3572 if (parser->error)
3573 return NULL_TREE;
3574 if (!specs->declspecs_seen_p)
3575 {
3576 c_parser_error (parser, "expected specifier-qualifier-list");
3577 return NULL_TREE;
3578 }
3579 finish_declspecs (specs);
3580 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3581 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3582 {
3583 tree ret;
3584 if (specs->typespec_kind == ctsk_none)
3585 {
3586 pedwarn (decl_loc, OPT_Wpedantic,
3587 "ISO C forbids member declarations with no members");
3588 shadow_tag_warned (specs, pedantic);
3589 ret = NULL_TREE;
3590 }
3591 else
3592 {
3593 /* Support for unnamed structs or unions as members of
3594 structs or unions (which is [a] useful and [b] supports
3595 MS P-SDK). */
3596 tree attrs = NULL;
3597
3598 ret = grokfield (c_parser_peek_token (parser)->location,
3599 build_id_declarator (NULL_TREE), specs,
3600 NULL_TREE, &attrs);
3601 if (ret)
3602 decl_attributes (&ret, attrs, 0);
3603 }
3604 return ret;
3605 }
3606
3607 /* Provide better error recovery. Note that a type name here is valid,
3608 and will be treated as a field name. */
3609 if (specs->typespec_kind == ctsk_tagdef
3610 && TREE_CODE (specs->type) != ENUMERAL_TYPE
3611 && c_parser_next_token_starts_declspecs (parser)
3612 && !c_parser_next_token_is (parser, CPP_NAME))
3613 {
3614 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
3615 parser->error = false;
3616 return NULL_TREE;
3617 }
3618
3619 pending_xref_error ();
3620 prefix_attrs = specs->attrs;
3621 all_prefix_attrs = prefix_attrs;
3622 specs->attrs = NULL_TREE;
3623 decls = NULL_TREE;
3624 while (true)
3625 {
3626 /* Declaring one or more declarators or un-named bit-fields. */
3627 struct c_declarator *declarator;
3628 bool dummy = false;
3629 if (c_parser_next_token_is (parser, CPP_COLON))
3630 declarator = build_id_declarator (NULL_TREE);
3631 else
3632 declarator = c_parser_declarator (parser,
3633 specs->typespec_kind != ctsk_none,
3634 C_DTR_NORMAL, &dummy);
3635 if (declarator == NULL)
3636 {
3637 c_parser_skip_to_end_of_block_or_statement (parser);
3638 break;
3639 }
3640 if (c_parser_next_token_is (parser, CPP_COLON)
3641 || c_parser_next_token_is (parser, CPP_COMMA)
3642 || c_parser_next_token_is (parser, CPP_SEMICOLON)
3643 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3644 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3645 {
3646 tree postfix_attrs = NULL_TREE;
3647 tree width = NULL_TREE;
3648 tree d;
3649 if (c_parser_next_token_is (parser, CPP_COLON))
3650 {
3651 c_parser_consume_token (parser);
3652 width = c_parser_expr_no_commas (parser, NULL).value;
3653 }
3654 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3655 postfix_attrs = c_parser_gnu_attributes (parser);
3656 d = grokfield (c_parser_peek_token (parser)->location,
3657 declarator, specs, width, &all_prefix_attrs);
3658 decl_attributes (&d, chainon (postfix_attrs,
3659 all_prefix_attrs), 0);
3660 DECL_CHAIN (d) = decls;
3661 decls = d;
3662 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3663 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
3664 prefix_attrs);
3665 else
3666 all_prefix_attrs = prefix_attrs;
3667 if (c_parser_next_token_is (parser, CPP_COMMA))
3668 c_parser_consume_token (parser);
3669 else if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3670 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3671 {
3672 /* Semicolon consumed in caller. */
3673 break;
3674 }
3675 else
3676 {
3677 c_parser_error (parser, "expected %<,%>, %<;%> or %<}%>");
3678 break;
3679 }
3680 }
3681 else
3682 {
3683 c_parser_error (parser,
3684 "expected %<:%>, %<,%>, %<;%>, %<}%> or "
3685 "%<__attribute__%>");
3686 break;
3687 }
3688 }
3689 return decls;
3690 }
3691
3692 /* Parse a typeof specifier (a GNU extension).
3693
3694 typeof-specifier:
3695 typeof ( expression )
3696 typeof ( type-name )
3697 */
3698
3699 static struct c_typespec
3700 c_parser_typeof_specifier (c_parser *parser)
3701 {
3702 struct c_typespec ret;
3703 ret.kind = ctsk_typeof;
3704 ret.spec = error_mark_node;
3705 ret.expr = NULL_TREE;
3706 ret.expr_const_operands = true;
3707 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF));
3708 c_parser_consume_token (parser);
3709 c_inhibit_evaluation_warnings++;
3710 in_typeof++;
3711 matching_parens parens;
3712 if (!parens.require_open (parser))
3713 {
3714 c_inhibit_evaluation_warnings--;
3715 in_typeof--;
3716 return ret;
3717 }
3718 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
3719 {
3720 struct c_type_name *type = c_parser_type_name (parser);
3721 c_inhibit_evaluation_warnings--;
3722 in_typeof--;
3723 if (type != NULL)
3724 {
3725 ret.spec = groktypename (type, &ret.expr, &ret.expr_const_operands);
3726 pop_maybe_used (variably_modified_type_p (ret.spec, NULL_TREE));
3727 }
3728 }
3729 else
3730 {
3731 bool was_vm;
3732 location_t here = c_parser_peek_token (parser)->location;
3733 struct c_expr expr = c_parser_expression (parser);
3734 c_inhibit_evaluation_warnings--;
3735 in_typeof--;
3736 if (TREE_CODE (expr.value) == COMPONENT_REF
3737 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
3738 error_at (here, "%<typeof%> applied to a bit-field");
3739 mark_exp_read (expr.value);
3740 ret.spec = TREE_TYPE (expr.value);
3741 was_vm = variably_modified_type_p (ret.spec, NULL_TREE);
3742 /* This is returned with the type so that when the type is
3743 evaluated, this can be evaluated. */
3744 if (was_vm)
3745 ret.expr = c_fully_fold (expr.value, false, &ret.expr_const_operands);
3746 pop_maybe_used (was_vm);
3747 }
3748 parens.skip_until_found_close (parser);
3749 return ret;
3750 }
3751
3752 /* Parse an alignment-specifier.
3753
3754 C11 6.7.5:
3755
3756 alignment-specifier:
3757 _Alignas ( type-name )
3758 _Alignas ( constant-expression )
3759 */
3760
3761 static tree
3762 c_parser_alignas_specifier (c_parser * parser)
3763 {
3764 tree ret = error_mark_node;
3765 location_t loc = c_parser_peek_token (parser)->location;
3766 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNAS));
3767 c_parser_consume_token (parser);
3768 if (flag_isoc99)
3769 pedwarn_c99 (loc, OPT_Wpedantic,
3770 "ISO C99 does not support %<_Alignas%>");
3771 else
3772 pedwarn_c99 (loc, OPT_Wpedantic,
3773 "ISO C90 does not support %<_Alignas%>");
3774 matching_parens parens;
3775 if (!parens.require_open (parser))
3776 return ret;
3777 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
3778 {
3779 struct c_type_name *type = c_parser_type_name (parser);
3780 if (type != NULL)
3781 ret = c_sizeof_or_alignof_type (loc, groktypename (type, NULL, NULL),
3782 false, true, 1);
3783 }
3784 else
3785 ret = c_parser_expr_no_commas (parser, NULL).value;
3786 parens.skip_until_found_close (parser);
3787 return ret;
3788 }
3789
3790 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
3791 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then
3792 a typedef name may be redeclared; otherwise it may not. KIND
3793 indicates which kind of declarator is wanted. Returns a valid
3794 declarator except in the case of a syntax error in which case NULL is
3795 returned. *SEEN_ID is set to true if an identifier being declared is
3796 seen; this is used to diagnose bad forms of abstract array declarators
3797 and to determine whether an identifier list is syntactically permitted.
3798
3799 declarator:
3800 pointer[opt] direct-declarator
3801
3802 direct-declarator:
3803 identifier
3804 ( gnu-attributes[opt] declarator )
3805 direct-declarator array-declarator
3806 direct-declarator ( parameter-type-list )
3807 direct-declarator ( identifier-list[opt] )
3808
3809 pointer:
3810 * type-qualifier-list[opt]
3811 * type-qualifier-list[opt] pointer
3812
3813 type-qualifier-list:
3814 type-qualifier
3815 gnu-attributes
3816 type-qualifier-list type-qualifier
3817 type-qualifier-list gnu-attributes
3818
3819 array-declarator:
3820 [ type-qualifier-list[opt] assignment-expression[opt] ]
3821 [ static type-qualifier-list[opt] assignment-expression ]
3822 [ type-qualifier-list static assignment-expression ]
3823 [ type-qualifier-list[opt] * ]
3824
3825 parameter-type-list:
3826 parameter-list
3827 parameter-list , ...
3828
3829 parameter-list:
3830 parameter-declaration
3831 parameter-list , parameter-declaration
3832
3833 parameter-declaration:
3834 declaration-specifiers declarator gnu-attributes[opt]
3835 declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
3836
3837 identifier-list:
3838 identifier
3839 identifier-list , identifier
3840
3841 abstract-declarator:
3842 pointer
3843 pointer[opt] direct-abstract-declarator
3844
3845 direct-abstract-declarator:
3846 ( gnu-attributes[opt] abstract-declarator )
3847 direct-abstract-declarator[opt] array-declarator
3848 direct-abstract-declarator[opt] ( parameter-type-list[opt] )
3849
3850 GNU extensions:
3851
3852 direct-declarator:
3853 direct-declarator ( parameter-forward-declarations
3854 parameter-type-list[opt] )
3855
3856 direct-abstract-declarator:
3857 direct-abstract-declarator[opt] ( parameter-forward-declarations
3858 parameter-type-list[opt] )
3859
3860 parameter-forward-declarations:
3861 parameter-list ;
3862 parameter-forward-declarations parameter-list ;
3863
3864 The uses of gnu-attributes shown above are GNU extensions.
3865
3866 Some forms of array declarator are not included in C99 in the
3867 syntax for abstract declarators; these are disallowed elsewhere.
3868 This may be a defect (DR#289).
3869
3870 This function also accepts an omitted abstract declarator as being
3871 an abstract declarator, although not part of the formal syntax. */
3872
3873 struct c_declarator *
3874 c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
3875 bool *seen_id)
3876 {
3877 /* Parse any initial pointer part. */
3878 if (c_parser_next_token_is (parser, CPP_MULT))
3879 {
3880 struct c_declspecs *quals_attrs = build_null_declspecs ();
3881 struct c_declarator *inner;
3882 c_parser_consume_token (parser);
3883 c_parser_declspecs (parser, quals_attrs, false, false, true,
3884 false, false, true, false, cla_prefer_id);
3885 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
3886 if (inner == NULL)
3887 return NULL;
3888 else
3889 return make_pointer_declarator (quals_attrs, inner);
3890 }
3891 /* Now we have a direct declarator, direct abstract declarator or
3892 nothing (which counts as a direct abstract declarator here). */
3893 return c_parser_direct_declarator (parser, type_seen_p, kind, seen_id);
3894 }
3895
3896 /* Parse a direct declarator or direct abstract declarator; arguments
3897 as c_parser_declarator. */
3898
3899 static struct c_declarator *
3900 c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
3901 bool *seen_id)
3902 {
3903 /* The direct declarator must start with an identifier (possibly
3904 omitted) or a parenthesized declarator (possibly abstract). In
3905 an ordinary declarator, initial parentheses must start a
3906 parenthesized declarator. In an abstract declarator or parameter
3907 declarator, they could start a parenthesized declarator or a
3908 parameter list. To tell which, the open parenthesis and any
3909 following gnu-attributes must be read. If a declaration
3910 specifier or standard attributes follow, then it is a parameter
3911 list; if the specifier is a typedef name, there might be an
3912 ambiguity about redeclaring it, which is resolved in the
3913 direction of treating it as a typedef name. If a close
3914 parenthesis follows, it is also an empty parameter list, as the
3915 syntax does not permit empty abstract declarators. Otherwise, it
3916 is a parenthesized declarator (in which case the analysis may be
3917 repeated inside it, recursively).
3918
3919 ??? There is an ambiguity in a parameter declaration "int
3920 (__attribute__((foo)) x)", where x is not a typedef name: it
3921 could be an abstract declarator for a function, or declare x with
3922 parentheses. The proper resolution of this ambiguity needs
3923 documenting. At present we follow an accident of the old
3924 parser's implementation, whereby the first parameter must have
3925 some declaration specifiers other than just gnu-attributes. Thus as
3926 a parameter declaration it is treated as a parenthesized
3927 parameter named x, and as an abstract declarator it is
3928 rejected.
3929
3930 ??? Also following the old parser, gnu-attributes inside an empty
3931 parameter list are ignored, making it a list not yielding a
3932 prototype, rather than giving an error or making it have one
3933 parameter with implicit type int.
3934
3935 ??? Also following the old parser, typedef names may be
3936 redeclared in declarators, but not Objective-C class names. */
3937
3938 if (kind != C_DTR_ABSTRACT
3939 && c_parser_next_token_is (parser, CPP_NAME)
3940 && ((type_seen_p
3941 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
3942 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
3943 || c_parser_peek_token (parser)->id_kind == C_ID_ID))
3944 {
3945 struct c_declarator *inner
3946 = build_id_declarator (c_parser_peek_token (parser)->value);
3947 *seen_id = true;
3948 inner->id_loc = c_parser_peek_token (parser)->location;
3949 c_parser_consume_token (parser);
3950 if (c_parser_nth_token_starts_std_attributes (parser, 1))
3951 inner->u.id.attrs = c_parser_std_attribute_specifier_sequence (parser);
3952 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3953 }
3954
3955 if (kind != C_DTR_NORMAL
3956 && c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
3957 && !c_parser_nth_token_starts_std_attributes (parser, 1))
3958 {
3959 struct c_declarator *inner = build_id_declarator (NULL_TREE);
3960 inner->id_loc = c_parser_peek_token (parser)->location;
3961 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3962 }
3963
3964 /* Either we are at the end of an abstract declarator, or we have
3965 parentheses. */
3966
3967 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3968 {
3969 tree attrs;
3970 struct c_declarator *inner;
3971 c_parser_consume_token (parser);
3972 bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
3973 RID_ATTRIBUTE);
3974 attrs = c_parser_gnu_attributes (parser);
3975 if (kind != C_DTR_NORMAL
3976 && (c_parser_next_token_starts_declspecs (parser)
3977 || (!have_gnu_attrs
3978 && c_parser_nth_token_starts_std_attributes (parser, 1))
3979 || c_parser_next_token_is (parser, CPP_CLOSE_PAREN)))
3980 {
3981 struct c_arg_info *args
3982 = c_parser_parms_declarator (parser, kind == C_DTR_NORMAL,
3983 attrs, have_gnu_attrs);
3984 if (args == NULL)
3985 return NULL;
3986 else
3987 {
3988 inner = build_id_declarator (NULL_TREE);
3989 if (!(args->types
3990 && args->types != error_mark_node
3991 && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
3992 && c_parser_nth_token_starts_std_attributes (parser, 1))
3993 {
3994 tree std_attrs
3995 = c_parser_std_attribute_specifier_sequence (parser);
3996 if (std_attrs)
3997 inner = build_attrs_declarator (std_attrs, inner);
3998 }
3999 inner = build_function_declarator (args, inner);
4000 return c_parser_direct_declarator_inner (parser, *seen_id,
4001 inner);
4002 }
4003 }
4004 /* A parenthesized declarator. */
4005 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
4006 if (inner != NULL && attrs != NULL)
4007 inner = build_attrs_declarator (attrs, inner);
4008 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4009 {
4010 c_parser_consume_token (parser);
4011 if (inner == NULL)
4012 return NULL;
4013 else
4014 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
4015 }
4016 else
4017 {
4018 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4019 "expected %<)%>");
4020 return NULL;
4021 }
4022 }
4023 else
4024 {
4025 if (kind == C_DTR_NORMAL)
4026 {
4027 c_parser_error (parser, "expected identifier or %<(%>");
4028 return NULL;
4029 }
4030 else
4031 return build_id_declarator (NULL_TREE);
4032 }
4033 }
4034
4035 /* Parse part of a direct declarator or direct abstract declarator,
4036 given that some (in INNER) has already been parsed; ID_PRESENT is
4037 true if an identifier is present, false for an abstract
4038 declarator. */
4039
4040 static struct c_declarator *
4041 c_parser_direct_declarator_inner (c_parser *parser, bool id_present,
4042 struct c_declarator *inner)
4043 {
4044 /* Parse a sequence of array declarators and parameter lists. */
4045 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
4046 && !c_parser_nth_token_starts_std_attributes (parser, 1))
4047 {
4048 location_t brace_loc = c_parser_peek_token (parser)->location;
4049 struct c_declarator *declarator;
4050 struct c_declspecs *quals_attrs = build_null_declspecs ();
4051 bool static_seen;
4052 bool star_seen;
4053 struct c_expr dimen;
4054 dimen.value = NULL_TREE;
4055 dimen.original_code = ERROR_MARK;
4056 dimen.original_type = NULL_TREE;
4057 c_parser_consume_token (parser);
4058 c_parser_declspecs (parser, quals_attrs, false, false, true,
4059 false, false, false, false, cla_prefer_id);
4060 static_seen = c_parser_next_token_is_keyword (parser, RID_STATIC);
4061 if (static_seen)
4062 c_parser_consume_token (parser);
4063 if (static_seen && !quals_attrs->declspecs_seen_p)
4064 c_parser_declspecs (parser, quals_attrs, false, false, true,
4065 false, false, false, false, cla_prefer_id);
4066 if (!quals_attrs->declspecs_seen_p)
4067 quals_attrs = NULL;
4068 /* If "static" is present, there must be an array dimension.
4069 Otherwise, there may be a dimension, "*", or no
4070 dimension. */
4071 if (static_seen)
4072 {
4073 star_seen = false;
4074 dimen = c_parser_expr_no_commas (parser, NULL);
4075 }
4076 else
4077 {
4078 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4079 {
4080 dimen.value = NULL_TREE;
4081 star_seen = false;
4082 }
4083 else if (c_parser_next_token_is (parser, CPP_MULT))
4084 {
4085 if (c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_SQUARE)
4086 {
4087 dimen.value = NULL_TREE;
4088 star_seen = true;
4089 c_parser_consume_token (parser);
4090 }
4091 else
4092 {
4093 star_seen = false;
4094 dimen = c_parser_expr_no_commas (parser, NULL);
4095 }
4096 }
4097 else
4098 {
4099 star_seen = false;
4100 dimen = c_parser_expr_no_commas (parser, NULL);
4101 }
4102 }
4103 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4104 c_parser_consume_token (parser);
4105 else
4106 {
4107 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
4108 "expected %<]%>");
4109 return NULL;
4110 }
4111 if (dimen.value)
4112 dimen = convert_lvalue_to_rvalue (brace_loc, dimen, true, true);
4113 declarator = build_array_declarator (brace_loc, dimen.value, quals_attrs,
4114 static_seen, star_seen);
4115 if (declarator == NULL)
4116 return NULL;
4117 if (c_parser_nth_token_starts_std_attributes (parser, 1))
4118 {
4119 tree std_attrs
4120 = c_parser_std_attribute_specifier_sequence (parser);
4121 if (std_attrs)
4122 inner = build_attrs_declarator (std_attrs, inner);
4123 }
4124 inner = set_array_declarator_inner (declarator, inner);
4125 return c_parser_direct_declarator_inner (parser, id_present, inner);
4126 }
4127 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
4128 {
4129 tree attrs;
4130 struct c_arg_info *args;
4131 c_parser_consume_token (parser);
4132 bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
4133 RID_ATTRIBUTE);
4134 attrs = c_parser_gnu_attributes (parser);
4135 args = c_parser_parms_declarator (parser, id_present, attrs,
4136 have_gnu_attrs);
4137 if (args == NULL)
4138 return NULL;
4139 else
4140 {
4141 if (!(args->types
4142 && args->types != error_mark_node
4143 && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
4144 && c_parser_nth_token_starts_std_attributes (parser, 1))
4145 {
4146 tree std_attrs
4147 = c_parser_std_attribute_specifier_sequence (parser);
4148 if (std_attrs)
4149 inner = build_attrs_declarator (std_attrs, inner);
4150 }
4151 inner = build_function_declarator (args, inner);
4152 return c_parser_direct_declarator_inner (parser, id_present, inner);
4153 }
4154 }
4155 return inner;
4156 }
4157
4158 /* Parse a parameter list or identifier list, including the closing
4159 parenthesis but not the opening one. ATTRS are the gnu-attributes
4160 at the start of the list. ID_LIST_OK is true if an identifier list
4161 is acceptable; such a list must not have attributes at the start.
4162 HAVE_GNU_ATTRS says whether any gnu-attributes (including empty
4163 attributes) were present (in which case standard attributes cannot
4164 occur). */
4165
4166 static struct c_arg_info *
4167 c_parser_parms_declarator (c_parser *parser, bool id_list_ok, tree attrs,
4168 bool have_gnu_attrs)
4169 {
4170 push_scope ();
4171 declare_parm_level ();
4172 /* If the list starts with an identifier, it is an identifier list.
4173 Otherwise, it is either a prototype list or an empty list. */
4174 if (id_list_ok
4175 && !attrs
4176 && c_parser_next_token_is (parser, CPP_NAME)
4177 && c_parser_peek_token (parser)->id_kind == C_ID_ID
4178
4179 /* Look ahead to detect typos in type names. */
4180 && c_parser_peek_2nd_token (parser)->type != CPP_NAME
4181 && c_parser_peek_2nd_token (parser)->type != CPP_MULT
4182 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
4183 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_SQUARE
4184 && c_parser_peek_2nd_token (parser)->type != CPP_KEYWORD)
4185 {
4186 tree list = NULL_TREE, *nextp = &list;
4187 while (c_parser_next_token_is (parser, CPP_NAME)
4188 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
4189 {
4190 *nextp = build_tree_list (NULL_TREE,
4191 c_parser_peek_token (parser)->value);
4192 nextp = & TREE_CHAIN (*nextp);
4193 c_parser_consume_token (parser);
4194 if (c_parser_next_token_is_not (parser, CPP_COMMA))
4195 break;
4196 c_parser_consume_token (parser);
4197 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4198 {
4199 c_parser_error (parser, "expected identifier");
4200 break;
4201 }
4202 }
4203 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4204 {
4205 struct c_arg_info *ret = build_arg_info ();
4206 ret->types = list;
4207 c_parser_consume_token (parser);
4208 pop_scope ();
4209 return ret;
4210 }
4211 else
4212 {
4213 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4214 "expected %<)%>");
4215 pop_scope ();
4216 return NULL;
4217 }
4218 }
4219 else
4220 {
4221 struct c_arg_info *ret
4222 = c_parser_parms_list_declarator (parser, attrs, NULL, have_gnu_attrs);
4223 pop_scope ();
4224 return ret;
4225 }
4226 }
4227
4228 /* Parse a parameter list (possibly empty), including the closing
4229 parenthesis but not the opening one. ATTRS are the gnu-attributes
4230 at the start of the list; if HAVE_GNU_ATTRS, there were some such
4231 attributes (possibly empty, in which case ATTRS is NULL_TREE),
4232 which means standard attributes cannot start the list. EXPR is
4233 NULL or an expression that needs to be evaluated for the side
4234 effects of array size expressions in the parameters. */
4235
4236 static struct c_arg_info *
4237 c_parser_parms_list_declarator (c_parser *parser, tree attrs, tree expr,
4238 bool have_gnu_attrs)
4239 {
4240 bool bad_parm = false;
4241
4242 /* ??? Following the old parser, forward parameter declarations may
4243 use abstract declarators, and if no real parameter declarations
4244 follow the forward declarations then this is not diagnosed. Also
4245 note as above that gnu-attributes are ignored as the only contents of
4246 the parentheses, or as the only contents after forward
4247 declarations. */
4248 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4249 {
4250 struct c_arg_info *ret = build_arg_info ();
4251 c_parser_consume_token (parser);
4252 return ret;
4253 }
4254 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4255 {
4256 struct c_arg_info *ret = build_arg_info ();
4257
4258 if (flag_allow_parameterless_variadic_functions)
4259 {
4260 /* F (...) is allowed. */
4261 ret->types = NULL_TREE;
4262 }
4263 else
4264 {
4265 /* Suppress -Wold-style-definition for this case. */
4266 ret->types = error_mark_node;
4267 error_at (c_parser_peek_token (parser)->location,
4268 "ISO C requires a named argument before %<...%>");
4269 }
4270 c_parser_consume_token (parser);
4271 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4272 {
4273 c_parser_consume_token (parser);
4274 return ret;
4275 }
4276 else
4277 {
4278 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4279 "expected %<)%>");
4280 return NULL;
4281 }
4282 }
4283 /* Nonempty list of parameters, either terminated with semicolon
4284 (forward declarations; recurse) or with close parenthesis (normal
4285 function) or with ", ... )" (variadic function). */
4286 while (true)
4287 {
4288 /* Parse a parameter. */
4289 struct c_parm *parm = c_parser_parameter_declaration (parser, attrs,
4290 have_gnu_attrs);
4291 attrs = NULL_TREE;
4292 have_gnu_attrs = false;
4293 if (parm == NULL)
4294 bad_parm = true;
4295 else
4296 push_parm_decl (parm, &expr);
4297 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4298 {
4299 tree new_attrs;
4300 c_parser_consume_token (parser);
4301 mark_forward_parm_decls ();
4302 bool new_have_gnu_attrs
4303 = c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE);
4304 new_attrs = c_parser_gnu_attributes (parser);
4305 return c_parser_parms_list_declarator (parser, new_attrs, expr,
4306 new_have_gnu_attrs);
4307 }
4308 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4309 {
4310 c_parser_consume_token (parser);
4311 if (bad_parm)
4312 return NULL;
4313 else
4314 return get_parm_info (false, expr);
4315 }
4316 if (!c_parser_require (parser, CPP_COMMA,
4317 "expected %<;%>, %<,%> or %<)%>",
4318 UNKNOWN_LOCATION, false))
4319 {
4320 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4321 return NULL;
4322 }
4323 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4324 {
4325 c_parser_consume_token (parser);
4326 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4327 {
4328 c_parser_consume_token (parser);
4329 if (bad_parm)
4330 return NULL;
4331 else
4332 return get_parm_info (true, expr);
4333 }
4334 else
4335 {
4336 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4337 "expected %<)%>");
4338 return NULL;
4339 }
4340 }
4341 }
4342 }
4343
4344 /* Parse a parameter declaration. ATTRS are the gnu-attributes at the
4345 start of the declaration if it is the first parameter;
4346 HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even
4347 empty) there. */
4348
4349 static struct c_parm *
4350 c_parser_parameter_declaration (c_parser *parser, tree attrs,
4351 bool have_gnu_attrs)
4352 {
4353 struct c_declspecs *specs;
4354 struct c_declarator *declarator;
4355 tree prefix_attrs;
4356 tree postfix_attrs = NULL_TREE;
4357 bool dummy = false;
4358
4359 /* Accept #pragmas between parameter declarations. */
4360 while (c_parser_next_token_is (parser, CPP_PRAGMA))
4361 c_parser_pragma (parser, pragma_param, NULL);
4362
4363 if (!c_parser_next_token_starts_declspecs (parser)
4364 && !c_parser_nth_token_starts_std_attributes (parser, 1))
4365 {
4366 c_token *token = c_parser_peek_token (parser);
4367 if (parser->error)
4368 return NULL;
4369 c_parser_set_source_position_from_token (token);
4370 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
4371 {
4372 auto_diagnostic_group d;
4373 name_hint hint = lookup_name_fuzzy (token->value,
4374 FUZZY_LOOKUP_TYPENAME,
4375 token->location);
4376 if (const char *suggestion = hint.suggestion ())
4377 {
4378 gcc_rich_location richloc (token->location);
4379 richloc.add_fixit_replace (suggestion);
4380 error_at (&richloc,
4381 "unknown type name %qE; did you mean %qs?",
4382 token->value, suggestion);
4383 }
4384 else
4385 error_at (token->location, "unknown type name %qE", token->value);
4386 parser->error = true;
4387 }
4388 /* ??? In some Objective-C cases '...' isn't applicable so there
4389 should be a different message. */
4390 else
4391 c_parser_error (parser,
4392 "expected declaration specifiers or %<...%>");
4393 c_parser_skip_to_end_of_parameter (parser);
4394 return NULL;
4395 }
4396
4397 location_t start_loc = c_parser_peek_token (parser)->location;
4398
4399 specs = build_null_declspecs ();
4400 if (attrs)
4401 {
4402 declspecs_add_attrs (input_location, specs, attrs);
4403 attrs = NULL_TREE;
4404 }
4405 c_parser_declspecs (parser, specs, true, true, true, true, false,
4406 !have_gnu_attrs, true, cla_nonabstract_decl);
4407 finish_declspecs (specs);
4408 pending_xref_error ();
4409 prefix_attrs = specs->attrs;
4410 specs->attrs = NULL_TREE;
4411 declarator = c_parser_declarator (parser,
4412 specs->typespec_kind != ctsk_none,
4413 C_DTR_PARM, &dummy);
4414 if (declarator == NULL)
4415 {
4416 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
4417 return NULL;
4418 }
4419 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4420 postfix_attrs = c_parser_gnu_attributes (parser);
4421
4422 /* Generate a location for the parameter, ranging from the start of the
4423 initial token to the end of the final token.
4424
4425 If we have a identifier, then use it for the caret location, e.g.
4426
4427 extern int callee (int one, int (*two)(int, int), float three);
4428 ~~~~~~^~~~~~~~~~~~~~
4429
4430 otherwise, reuse the start location for the caret location e.g.:
4431
4432 extern int callee (int one, int (*)(int, int), float three);
4433 ^~~~~~~~~~~~~~~~~
4434 */
4435 location_t end_loc = parser->last_token_location;
4436
4437 /* Find any cdk_id declarator; determine if we have an identifier. */
4438 c_declarator *id_declarator = declarator;
4439 while (id_declarator && id_declarator->kind != cdk_id)
4440 id_declarator = id_declarator->declarator;
4441 location_t caret_loc = (id_declarator->u.id.id
4442 ? id_declarator->id_loc
4443 : start_loc);
4444 location_t param_loc = make_location (caret_loc, start_loc, end_loc);
4445
4446 return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
4447 declarator, param_loc);
4448 }
4449
4450 /* Parse a string literal in an asm expression. It should not be
4451 translated, and wide string literals are an error although
4452 permitted by the syntax. This is a GNU extension.
4453
4454 asm-string-literal:
4455 string-literal
4456 */
4457
4458 static tree
4459 c_parser_asm_string_literal (c_parser *parser)
4460 {
4461 tree str;
4462 int save_flag = warn_overlength_strings;
4463 warn_overlength_strings = 0;
4464 str = c_parser_string_literal (parser, false, false).value;
4465 warn_overlength_strings = save_flag;
4466 return str;
4467 }
4468
4469 /* Parse a simple asm expression. This is used in restricted
4470 contexts, where a full expression with inputs and outputs does not
4471 make sense. This is a GNU extension.
4472
4473 simple-asm-expr:
4474 asm ( asm-string-literal )
4475 */
4476
4477 static tree
4478 c_parser_simple_asm_expr (c_parser *parser)
4479 {
4480 tree str;
4481 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
4482 c_parser_consume_token (parser);
4483 matching_parens parens;
4484 if (!parens.require_open (parser))
4485 return NULL_TREE;
4486 str = c_parser_asm_string_literal (parser);
4487 if (!parens.require_close (parser))
4488 {
4489 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4490 return NULL_TREE;
4491 }
4492 return str;
4493 }
4494
4495 static tree
4496 c_parser_gnu_attribute_any_word (c_parser *parser)
4497 {
4498 tree attr_name = NULL_TREE;
4499
4500 if (c_parser_next_token_is (parser, CPP_KEYWORD))
4501 {
4502 /* ??? See comment above about what keywords are accepted here. */
4503 bool ok;
4504 switch (c_parser_peek_token (parser)->keyword)
4505 {
4506 case RID_STATIC:
4507 case RID_UNSIGNED:
4508 case RID_LONG:
4509 case RID_CONST:
4510 case RID_EXTERN:
4511 case RID_REGISTER:
4512 case RID_TYPEDEF:
4513 case RID_SHORT:
4514 case RID_INLINE:
4515 case RID_NORETURN:
4516 case RID_VOLATILE:
4517 case RID_SIGNED:
4518 case RID_AUTO:
4519 case RID_RESTRICT:
4520 case RID_COMPLEX:
4521 case RID_THREAD:
4522 case RID_INT:
4523 case RID_CHAR:
4524 case RID_FLOAT:
4525 case RID_DOUBLE:
4526 case RID_VOID:
4527 case RID_DFLOAT32:
4528 case RID_DFLOAT64:
4529 case RID_DFLOAT128:
4530 CASE_RID_FLOATN_NX:
4531 case RID_BOOL:
4532 case RID_FRACT:
4533 case RID_ACCUM:
4534 case RID_SAT:
4535 case RID_TRANSACTION_ATOMIC:
4536 case RID_TRANSACTION_CANCEL:
4537 case RID_ATOMIC:
4538 case RID_AUTO_TYPE:
4539 case RID_INT_N_0:
4540 case RID_INT_N_1:
4541 case RID_INT_N_2:
4542 case RID_INT_N_3:
4543 ok = true;
4544 break;
4545 default:
4546 ok = false;
4547 break;
4548 }
4549 if (!ok)
4550 return NULL_TREE;
4551
4552 /* Accept __attribute__((__const)) as __attribute__((const)) etc. */
4553 attr_name = ridpointers[(int) c_parser_peek_token (parser)->keyword];
4554 }
4555 else if (c_parser_next_token_is (parser, CPP_NAME))
4556 attr_name = c_parser_peek_token (parser)->value;
4557
4558 return attr_name;
4559 }
4560
4561 /* Parse attribute arguments. This is a common form of syntax
4562 covering all currently valid GNU and standard attributes.
4563
4564 gnu-attribute-arguments:
4565 identifier
4566 identifier , nonempty-expr-list
4567 expr-list
4568
4569 where the "identifier" must not be declared as a type. ??? Why not
4570 allow identifiers declared as types to start the arguments? */
4571
4572 static tree
4573 c_parser_attribute_arguments (c_parser *parser, bool takes_identifier,
4574 bool require_string, bool allow_empty_args)
4575 {
4576 vec<tree, va_gc> *expr_list;
4577 tree attr_args;
4578 /* Parse the attribute contents. If they start with an
4579 identifier which is followed by a comma or close
4580 parenthesis, then the arguments start with that
4581 identifier; otherwise they are an expression list.
4582 In objective-c the identifier may be a classname. */
4583 if (c_parser_next_token_is (parser, CPP_NAME)
4584 && (c_parser_peek_token (parser)->id_kind == C_ID_ID
4585 || (c_dialect_objc ()
4586 && c_parser_peek_token (parser)->id_kind
4587 == C_ID_CLASSNAME))
4588 && ((c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
4589 || (c_parser_peek_2nd_token (parser)->type
4590 == CPP_CLOSE_PAREN))
4591 && (takes_identifier
4592 || (c_dialect_objc ()
4593 && c_parser_peek_token (parser)->id_kind
4594 == C_ID_CLASSNAME)))
4595 {
4596 tree arg1 = c_parser_peek_token (parser)->value;
4597 c_parser_consume_token (parser);
4598 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4599 attr_args = build_tree_list (NULL_TREE, arg1);
4600 else
4601 {
4602 tree tree_list;
4603 c_parser_consume_token (parser);
4604 expr_list = c_parser_expr_list (parser, false, true,
4605 NULL, NULL, NULL, NULL);
4606 tree_list = build_tree_list_vec (expr_list);
4607 attr_args = tree_cons (NULL_TREE, arg1, tree_list);
4608 release_tree_vector (expr_list);
4609 }
4610 }
4611 else
4612 {
4613 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4614 {
4615 if (!allow_empty_args)
4616 error_at (c_parser_peek_token (parser)->location,
4617 "parentheses must be omitted if "
4618 "attribute argument list is empty");
4619 attr_args = NULL_TREE;
4620 }
4621 else if (require_string)
4622 {
4623 /* The only valid argument for this attribute is a string
4624 literal. Handle this specially here to avoid accepting
4625 string literals with excess parentheses. */
4626 tree string = c_parser_string_literal (parser, false, true).value;
4627 attr_args = build_tree_list (NULL_TREE, string);
4628 }
4629 else
4630 {
4631 expr_list = c_parser_expr_list (parser, false, true,
4632 NULL, NULL, NULL, NULL);
4633 attr_args = build_tree_list_vec (expr_list);
4634 release_tree_vector (expr_list);
4635 }
4636 }
4637 return attr_args;
4638 }
4639
4640 /* Parse (possibly empty) gnu-attributes. This is a GNU extension.
4641
4642 gnu-attributes:
4643 empty
4644 gnu-attributes gnu-attribute
4645
4646 gnu-attribute:
4647 __attribute__ ( ( gnu-attribute-list ) )
4648
4649 gnu-attribute-list:
4650 gnu-attrib
4651 gnu-attribute_list , gnu-attrib
4652
4653 gnu-attrib:
4654 empty
4655 any-word
4656 any-word ( gnu-attribute-arguments )
4657
4658 where "any-word" may be any identifier (including one declared as a
4659 type), a reserved word storage class specifier, type specifier or
4660 type qualifier. ??? This still leaves out most reserved keywords
4661 (following the old parser), shouldn't we include them?
4662 When EXPECT_COMMA is true, expect the attribute to be preceded
4663 by a comma and fail if it isn't.
4664 When EMPTY_OK is true, allow and consume any number of consecutive
4665 commas with no attributes in between. */
4666
4667 static tree
4668 c_parser_gnu_attribute (c_parser *parser, tree attrs,
4669 bool expect_comma = false, bool empty_ok = true)
4670 {
4671 bool comma_first = c_parser_next_token_is (parser, CPP_COMMA);
4672 if (!comma_first
4673 && !c_parser_next_token_is (parser, CPP_NAME)
4674 && !c_parser_next_token_is (parser, CPP_KEYWORD))
4675 return NULL_TREE;
4676
4677 while (c_parser_next_token_is (parser, CPP_COMMA))
4678 {
4679 c_parser_consume_token (parser);
4680 if (!empty_ok)
4681 return attrs;
4682 }
4683
4684 tree attr_name = c_parser_gnu_attribute_any_word (parser);
4685 if (attr_name == NULL_TREE)
4686 return NULL_TREE;
4687
4688 attr_name = canonicalize_attr_name (attr_name);
4689 c_parser_consume_token (parser);
4690
4691 tree attr;
4692 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
4693 {
4694 if (expect_comma && !comma_first)
4695 {
4696 /* A comma is missing between the last attribute on the chain
4697 and this one. */
4698 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4699 "expected %<)%>");
4700 return error_mark_node;
4701 }
4702 attr = build_tree_list (attr_name, NULL_TREE);
4703 /* Add this attribute to the list. */
4704 attrs = chainon (attrs, attr);
4705 return attrs;
4706 }
4707 c_parser_consume_token (parser);
4708
4709 tree attr_args
4710 = c_parser_attribute_arguments (parser,
4711 attribute_takes_identifier_p (attr_name),
4712 false, true);
4713
4714 attr = build_tree_list (attr_name, attr_args);
4715 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4716 c_parser_consume_token (parser);
4717 else
4718 {
4719 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4720 "expected %<)%>");
4721 return error_mark_node;
4722 }
4723
4724 if (expect_comma && !comma_first)
4725 {
4726 /* A comma is missing between the last attribute on the chain
4727 and this one. */
4728 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4729 "expected %<)%>");
4730 return error_mark_node;
4731 }
4732
4733 /* Add this attribute to the list. */
4734 attrs = chainon (attrs, attr);
4735 return attrs;
4736 }
4737
4738 static tree
4739 c_parser_gnu_attributes (c_parser *parser)
4740 {
4741 tree attrs = NULL_TREE;
4742 while (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4743 {
4744 bool save_translate_strings_p = parser->translate_strings_p;
4745 parser->translate_strings_p = false;
4746 /* Consume the `__attribute__' keyword. */
4747 c_parser_consume_token (parser);
4748 /* Look for the two `(' tokens. */
4749 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4750 {
4751 parser->translate_strings_p = save_translate_strings_p;
4752 return attrs;
4753 }
4754 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4755 {
4756 parser->translate_strings_p = save_translate_strings_p;
4757 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4758 return attrs;
4759 }
4760 /* Parse the attribute list. Require a comma between successive
4761 (possibly empty) attributes. */
4762 for (bool expect_comma = false; ; expect_comma = true)
4763 {
4764 /* Parse a single attribute. */
4765 tree attr = c_parser_gnu_attribute (parser, attrs, expect_comma);
4766 if (attr == error_mark_node)
4767 return attrs;
4768 if (!attr)
4769 break;
4770 attrs = attr;
4771 }
4772
4773 /* Look for the two `)' tokens. */
4774 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4775 c_parser_consume_token (parser);
4776 else
4777 {
4778 parser->translate_strings_p = save_translate_strings_p;
4779 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4780 "expected %<)%>");
4781 return attrs;
4782 }
4783 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4784 c_parser_consume_token (parser);
4785 else
4786 {
4787 parser->translate_strings_p = save_translate_strings_p;
4788 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4789 "expected %<)%>");
4790 return attrs;
4791 }
4792 parser->translate_strings_p = save_translate_strings_p;
4793 }
4794
4795 return attrs;
4796 }
4797
4798 /* Parse an optional balanced token sequence.
4799
4800 balanced-token-sequence:
4801 balanced-token
4802 balanced-token-sequence balanced-token
4803
4804 balanced-token:
4805 ( balanced-token-sequence[opt] )
4806 [ balanced-token-sequence[opt] ]
4807 { balanced-token-sequence[opt] }
4808 any token other than ()[]{}
4809 */
4810
4811 static void
4812 c_parser_balanced_token_sequence (c_parser *parser)
4813 {
4814 while (true)
4815 {
4816 c_token *token = c_parser_peek_token (parser);
4817 switch (token->type)
4818 {
4819 case CPP_OPEN_BRACE:
4820 {
4821 matching_braces braces;
4822 braces.consume_open (parser);
4823 c_parser_balanced_token_sequence (parser);
4824 braces.require_close (parser);
4825 break;
4826 }
4827
4828 case CPP_OPEN_PAREN:
4829 {
4830 matching_parens parens;
4831 parens.consume_open (parser);
4832 c_parser_balanced_token_sequence (parser);
4833 parens.require_close (parser);
4834 break;
4835 }
4836
4837 case CPP_OPEN_SQUARE:
4838 c_parser_consume_token (parser);
4839 c_parser_balanced_token_sequence (parser);
4840 c_parser_require (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
4841 break;
4842
4843 case CPP_CLOSE_BRACE:
4844 case CPP_CLOSE_PAREN:
4845 case CPP_CLOSE_SQUARE:
4846 case CPP_EOF:
4847 return;
4848
4849 case CPP_PRAGMA:
4850 c_parser_consume_pragma (parser);
4851 c_parser_skip_to_pragma_eol (parser, false);
4852 break;
4853
4854 default:
4855 c_parser_consume_token (parser);
4856 break;
4857 }
4858 }
4859 }
4860
4861 /* Parse standard (C2X) attributes (including GNU attributes in the
4862 gnu:: namespace).
4863
4864 attribute-specifier-sequence:
4865 attribute-specifier-sequence[opt] attribute-specifier
4866
4867 attribute-specifier:
4868 [ [ attribute-list ] ]
4869
4870 attribute-list:
4871 attribute[opt]
4872 attribute-list, attribute[opt]
4873
4874 attribute:
4875 attribute-token attribute-argument-clause[opt]
4876
4877 attribute-token:
4878 standard-attribute
4879 attribute-prefixed-token
4880
4881 standard-attribute:
4882 identifier
4883
4884 attribute-prefixed-token:
4885 attribute-prefix :: identifier
4886
4887 attribute-prefix:
4888 identifier
4889
4890 attribute-argument-clause:
4891 ( balanced-token-sequence[opt] )
4892
4893 Keywords are accepted as identifiers for this purpose.
4894 */
4895
4896 static tree
4897 c_parser_std_attribute (c_parser *parser, bool for_tm)
4898 {
4899 c_token *token = c_parser_peek_token (parser);
4900 tree ns, name, attribute;
4901
4902 /* Parse the attribute-token. */
4903 if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
4904 {
4905 c_parser_error (parser, "expected identifier");
4906 return error_mark_node;
4907 }
4908 name = canonicalize_attr_name (token->value);
4909 c_parser_consume_token (parser);
4910 if (c_parser_next_token_is (parser, CPP_SCOPE))
4911 {
4912 ns = name;
4913 c_parser_consume_token (parser);
4914 token = c_parser_peek_token (parser);
4915 if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
4916 {
4917 c_parser_error (parser, "expected identifier");
4918 return error_mark_node;
4919 }
4920 name = canonicalize_attr_name (token->value);
4921 c_parser_consume_token (parser);
4922 }
4923 else
4924 ns = NULL_TREE;
4925 attribute = build_tree_list (build_tree_list (ns, name), NULL_TREE);
4926
4927 /* Parse the arguments, if any. */
4928 const attribute_spec *as = lookup_attribute_spec (TREE_PURPOSE (attribute));
4929 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
4930 goto out;
4931 {
4932 location_t open_loc = c_parser_peek_token (parser)->location;
4933 matching_parens parens;
4934 parens.consume_open (parser);
4935 if ((as && as->max_length == 0)
4936 /* Special-case the transactional-memory attribute "outer",
4937 which is specially handled but not registered as an
4938 attribute, to avoid allowing arbitrary balanced token
4939 sequences as arguments. */
4940 || is_attribute_p ("outer", name))
4941 {
4942 error_at (open_loc, "%qE attribute does not take any arguments", name);
4943 parens.skip_until_found_close (parser);
4944 return error_mark_node;
4945 }
4946 /* If this is a fake attribute created to handle -Wno-attributes,
4947 we must skip parsing the arguments. */
4948 if (as && !attribute_ignored_p (as))
4949 {
4950 bool takes_identifier
4951 = (ns != NULL_TREE
4952 && strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0
4953 && attribute_takes_identifier_p (name));
4954 bool require_string
4955 = (ns == NULL_TREE
4956 && (strcmp (IDENTIFIER_POINTER (name), "deprecated") == 0
4957 || strcmp (IDENTIFIER_POINTER (name), "nodiscard") == 0));
4958 TREE_VALUE (attribute)
4959 = c_parser_attribute_arguments (parser, takes_identifier,
4960 require_string, false);
4961 }
4962 else
4963 c_parser_balanced_token_sequence (parser);
4964 parens.require_close (parser);
4965 }
4966 out:
4967 if (ns == NULL_TREE && !for_tm && !as)
4968 {
4969 /* An attribute with standard syntax and no namespace specified
4970 is a constraint violation if it is not one of the known
4971 standard attributes. Diagnose it here with a pedwarn and
4972 then discard it to prevent a duplicate warning later. */
4973 pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored",
4974 name);
4975 return error_mark_node;
4976 }
4977 return attribute;
4978 }
4979
4980 static tree
4981 c_parser_std_attribute_specifier (c_parser *parser, bool for_tm)
4982 {
4983 location_t loc = c_parser_peek_token (parser)->location;
4984 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
4985 return NULL_TREE;
4986 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
4987 {
4988 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
4989 return NULL_TREE;
4990 }
4991 if (!for_tm)
4992 pedwarn_c11 (loc, OPT_Wpedantic,
4993 "ISO C does not support %<[[]]%> attributes before C2X");
4994 tree attributes = NULL_TREE;
4995 while (true)
4996 {
4997 c_token *token = c_parser_peek_token (parser);
4998 if (token->type == CPP_CLOSE_SQUARE)
4999 break;
5000 if (token->type == CPP_COMMA)
5001 {
5002 c_parser_consume_token (parser);
5003 continue;
5004 }
5005 tree attribute = c_parser_std_attribute (parser, for_tm);
5006 if (attribute != error_mark_node)
5007 {
5008 TREE_CHAIN (attribute) = attributes;
5009 attributes = attribute;
5010 }
5011 if (c_parser_next_token_is_not (parser, CPP_COMMA))
5012 break;
5013 }
5014 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5015 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
5016 return nreverse (attributes);
5017 }
5018
5019 /* Look past an optional balanced token sequence of raw look-ahead
5020 tokens starting with the *Nth token. *N is updated to point to the
5021 following token. Return true if such a sequence was found, false
5022 if the tokens parsed were not balanced. */
5023
5024 static bool
5025 c_parser_check_balanced_raw_token_sequence (c_parser *parser, unsigned int *n)
5026 {
5027 while (true)
5028 {
5029 c_token *token = c_parser_peek_nth_token_raw (parser, *n);
5030 switch (token->type)
5031 {
5032 case CPP_OPEN_BRACE:
5033 {
5034 ++*n;
5035 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5036 {
5037 token = c_parser_peek_nth_token_raw (parser, *n);
5038 if (token->type == CPP_CLOSE_BRACE)
5039 ++*n;
5040 else
5041 return false;
5042 }
5043 else
5044 return false;
5045 break;
5046 }
5047
5048 case CPP_OPEN_PAREN:
5049 {
5050 ++*n;
5051 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5052 {
5053 token = c_parser_peek_nth_token_raw (parser, *n);
5054 if (token->type == CPP_CLOSE_PAREN)
5055 ++*n;
5056 else
5057 return false;
5058 }
5059 else
5060 return false;
5061 break;
5062 }
5063
5064 case CPP_OPEN_SQUARE:
5065 {
5066 ++*n;
5067 if (c_parser_check_balanced_raw_token_sequence (parser, n))
5068 {
5069 token = c_parser_peek_nth_token_raw (parser, *n);
5070 if (token->type == CPP_CLOSE_SQUARE)
5071 ++*n;
5072 else
5073 return false;
5074 }
5075 else
5076 return false;
5077 break;
5078 }
5079
5080 case CPP_CLOSE_BRACE:
5081 case CPP_CLOSE_PAREN:
5082 case CPP_CLOSE_SQUARE:
5083 case CPP_EOF:
5084 return true;
5085
5086 default:
5087 ++*n;
5088 break;
5089 }
5090 }
5091 }
5092
5093 /* Return whether standard attributes start with the Nth token. */
5094
5095 static bool
5096 c_parser_nth_token_starts_std_attributes (c_parser *parser, unsigned int n)
5097 {
5098 if (!(c_parser_peek_nth_token (parser, n)->type == CPP_OPEN_SQUARE
5099 && c_parser_peek_nth_token (parser, n + 1)->type == CPP_OPEN_SQUARE))
5100 return false;
5101 /* In C, '[[' must start attributes. In Objective-C, we need to
5102 check whether '[[' is matched by ']]'. */
5103 if (!c_dialect_objc ())
5104 return true;
5105 n += 2;
5106 if (!c_parser_check_balanced_raw_token_sequence (parser, &n))
5107 return false;
5108 c_token *token = c_parser_peek_nth_token_raw (parser, n);
5109 if (token->type != CPP_CLOSE_SQUARE)
5110 return false;
5111 token = c_parser_peek_nth_token_raw (parser, n + 1);
5112 return token->type == CPP_CLOSE_SQUARE;
5113 }
5114
5115 static tree
5116 c_parser_std_attribute_specifier_sequence (c_parser *parser)
5117 {
5118 tree attributes = NULL_TREE;
5119 do
5120 {
5121 tree attrs = c_parser_std_attribute_specifier (parser, false);
5122 attributes = chainon (attributes, attrs);
5123 }
5124 while (c_parser_nth_token_starts_std_attributes (parser, 1));
5125 return attributes;
5126 }
5127
5128 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK
5129 says whether alignment specifiers are OK (only in cases that might
5130 be the type name of a compound literal).
5131
5132 type-name:
5133 specifier-qualifier-list abstract-declarator[opt]
5134 */
5135
5136 struct c_type_name *
5137 c_parser_type_name (c_parser *parser, bool alignas_ok)
5138 {
5139 struct c_declspecs *specs = build_null_declspecs ();
5140 struct c_declarator *declarator;
5141 struct c_type_name *ret;
5142 bool dummy = false;
5143 c_parser_declspecs (parser, specs, false, true, true, alignas_ok, false,
5144 false, true, cla_prefer_type);
5145 if (!specs->declspecs_seen_p)
5146 {
5147 c_parser_error (parser, "expected specifier-qualifier-list");
5148 return NULL;
5149 }
5150 if (specs->type != error_mark_node)
5151 {
5152 pending_xref_error ();
5153 finish_declspecs (specs);
5154 }
5155 declarator = c_parser_declarator (parser,
5156 specs->typespec_kind != ctsk_none,
5157 C_DTR_ABSTRACT, &dummy);
5158 if (declarator == NULL)
5159 return NULL;
5160 ret = XOBNEW (&parser_obstack, struct c_type_name);
5161 ret->specs = specs;
5162 ret->declarator = declarator;
5163 return ret;
5164 }
5165
5166 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
5167
5168 initializer:
5169 assignment-expression
5170 { initializer-list }
5171 { initializer-list , }
5172
5173 initializer-list:
5174 designation[opt] initializer
5175 initializer-list , designation[opt] initializer
5176
5177 designation:
5178 designator-list =
5179
5180 designator-list:
5181 designator
5182 designator-list designator
5183
5184 designator:
5185 array-designator
5186 . identifier
5187
5188 array-designator:
5189 [ constant-expression ]
5190
5191 GNU extensions:
5192
5193 initializer:
5194 { }
5195
5196 designation:
5197 array-designator
5198 identifier :
5199
5200 array-designator:
5201 [ constant-expression ... constant-expression ]
5202
5203 Any expression without commas is accepted in the syntax for the
5204 constant-expressions, with non-constant expressions rejected later.
5205
5206 This function is only used for top-level initializers; for nested
5207 ones, see c_parser_initval. */
5208
5209 static struct c_expr
5210 c_parser_initializer (c_parser *parser)
5211 {
5212 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
5213 return c_parser_braced_init (parser, NULL_TREE, false, NULL);
5214 else
5215 {
5216 struct c_expr ret;
5217 location_t loc = c_parser_peek_token (parser)->location;
5218 ret = c_parser_expr_no_commas (parser, NULL);
5219 if (TREE_CODE (ret.value) != STRING_CST
5220 && TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR)
5221 ret = convert_lvalue_to_rvalue (loc, ret, true, true);
5222 return ret;
5223 }
5224 }
5225
5226 /* The location of the last comma within the current initializer list,
5227 or UNKNOWN_LOCATION if not within one. */
5228
5229 location_t last_init_list_comma;
5230
5231 /* Parse a braced initializer list. TYPE is the type specified for a
5232 compound literal, and NULL_TREE for other initializers and for
5233 nested braced lists. NESTED_P is true for nested braced lists,
5234 false for the list of a compound literal or the list that is the
5235 top-level initializer in a declaration. */
5236
5237 static struct c_expr
5238 c_parser_braced_init (c_parser *parser, tree type, bool nested_p,
5239 struct obstack *outer_obstack)
5240 {
5241 struct c_expr ret;
5242 struct obstack braced_init_obstack;
5243 location_t brace_loc = c_parser_peek_token (parser)->location;
5244 gcc_obstack_init (&braced_init_obstack);
5245 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
5246 matching_braces braces;
5247 braces.consume_open (parser);
5248 if (nested_p)
5249 {
5250 finish_implicit_inits (brace_loc, outer_obstack);
5251 push_init_level (brace_loc, 0, &braced_init_obstack);
5252 }
5253 else
5254 really_start_incremental_init (type);
5255 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5256 {
5257 pedwarn (brace_loc, OPT_Wpedantic, "ISO C forbids empty initializer braces");
5258 }
5259 else
5260 {
5261 /* Parse a non-empty initializer list, possibly with a trailing
5262 comma. */
5263 while (true)
5264 {
5265 c_parser_initelt (parser, &braced_init_obstack);
5266 if (parser->error)
5267 break;
5268 if (c_parser_next_token_is (parser, CPP_COMMA))
5269 {
5270 last_init_list_comma = c_parser_peek_token (parser)->location;
5271 c_parser_consume_token (parser);
5272 }
5273 else
5274 break;
5275 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5276 break;
5277 }
5278 }
5279 c_token *next_tok = c_parser_peek_token (parser);
5280 if (next_tok->type != CPP_CLOSE_BRACE)
5281 {
5282 ret.set_error ();
5283 ret.original_code = ERROR_MARK;
5284 ret.original_type = NULL;
5285 braces.skip_until_found_close (parser);
5286 pop_init_level (brace_loc, 0, &braced_init_obstack, last_init_list_comma);
5287 obstack_free (&braced_init_obstack, NULL);
5288 return ret;
5289 }
5290 location_t close_loc = next_tok->location;
5291 c_parser_consume_token (parser);
5292 ret = pop_init_level (brace_loc, 0, &braced_init_obstack, close_loc);
5293 obstack_free (&braced_init_obstack, NULL);
5294 set_c_expr_source_range (&ret, brace_loc, close_loc);
5295 return ret;
5296 }
5297
5298 /* Parse a nested initializer, including designators. */
5299
5300 static void
5301 c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
5302 {
5303 /* Parse any designator or designator list. A single array
5304 designator may have the subsequent "=" omitted in GNU C, but a
5305 longer list or a structure member designator may not. */
5306 if (c_parser_next_token_is (parser, CPP_NAME)
5307 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
5308 {
5309 /* Old-style structure member designator. */
5310 set_init_label (c_parser_peek_token (parser)->location,
5311 c_parser_peek_token (parser)->value,
5312 c_parser_peek_token (parser)->location,
5313 braced_init_obstack);
5314 /* Use the colon as the error location. */
5315 pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_Wpedantic,
5316 "obsolete use of designated initializer with %<:%>");
5317 c_parser_consume_token (parser);
5318 c_parser_consume_token (parser);
5319 }
5320 else
5321 {
5322 /* des_seen is 0 if there have been no designators, 1 if there
5323 has been a single array designator and 2 otherwise. */
5324 int des_seen = 0;
5325 /* Location of a designator. */
5326 location_t des_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5327 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
5328 || c_parser_next_token_is (parser, CPP_DOT))
5329 {
5330 int des_prev = des_seen;
5331 if (!des_seen)
5332 des_loc = c_parser_peek_token (parser)->location;
5333 if (des_seen < 2)
5334 des_seen++;
5335 if (c_parser_next_token_is (parser, CPP_DOT))
5336 {
5337 des_seen = 2;
5338 c_parser_consume_token (parser);
5339 if (c_parser_next_token_is (parser, CPP_NAME))
5340 {
5341 set_init_label (des_loc, c_parser_peek_token (parser)->value,
5342 c_parser_peek_token (parser)->location,
5343 braced_init_obstack);
5344 c_parser_consume_token (parser);
5345 }
5346 else
5347 {
5348 struct c_expr init;
5349 init.set_error ();
5350 init.original_code = ERROR_MARK;
5351 init.original_type = NULL;
5352 c_parser_error (parser, "expected identifier");
5353 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
5354 process_init_element (input_location, init, false,
5355 braced_init_obstack);
5356 return;
5357 }
5358 }
5359 else
5360 {
5361 tree first, second;
5362 location_t ellipsis_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5363 location_t array_index_loc = UNKNOWN_LOCATION;
5364 /* ??? Following the old parser, [ objc-receiver
5365 objc-message-args ] is accepted as an initializer,
5366 being distinguished from a designator by what follows
5367 the first assignment expression inside the square
5368 brackets, but after a first array designator a
5369 subsequent square bracket is for Objective-C taken to
5370 start an expression, using the obsolete form of
5371 designated initializer without '=', rather than
5372 possibly being a second level of designation: in LALR
5373 terms, the '[' is shifted rather than reducing
5374 designator to designator-list. */
5375 if (des_prev == 1 && c_dialect_objc ())
5376 {
5377 des_seen = des_prev;
5378 break;
5379 }
5380 if (des_prev == 0 && c_dialect_objc ())
5381 {
5382 /* This might be an array designator or an
5383 Objective-C message expression. If the former,
5384 continue parsing here; if the latter, parse the
5385 remainder of the initializer given the starting
5386 primary-expression. ??? It might make sense to
5387 distinguish when des_prev == 1 as well; see
5388 previous comment. */
5389 tree rec, args;
5390 struct c_expr mexpr;
5391 c_parser_consume_token (parser);
5392 if (c_parser_peek_token (parser)->type == CPP_NAME
5393 && ((c_parser_peek_token (parser)->id_kind
5394 == C_ID_TYPENAME)
5395 || (c_parser_peek_token (parser)->id_kind
5396 == C_ID_CLASSNAME)))
5397 {
5398 /* Type name receiver. */
5399 tree id = c_parser_peek_token (parser)->value;
5400 c_parser_consume_token (parser);
5401 rec = objc_get_class_reference (id);
5402 goto parse_message_args;
5403 }
5404 first = c_parser_expr_no_commas (parser, NULL).value;
5405 mark_exp_read (first);
5406 if (c_parser_next_token_is (parser, CPP_ELLIPSIS)
5407 || c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
5408 goto array_desig_after_first;
5409 /* Expression receiver. So far only one part
5410 without commas has been parsed; there might be
5411 more of the expression. */
5412 rec = first;
5413 while (c_parser_next_token_is (parser, CPP_COMMA))
5414 {
5415 struct c_expr next;
5416 location_t comma_loc, exp_loc;
5417 comma_loc = c_parser_peek_token (parser)->location;
5418 c_parser_consume_token (parser);
5419 exp_loc = c_parser_peek_token (parser)->location;
5420 next = c_parser_expr_no_commas (parser, NULL);
5421 next = convert_lvalue_to_rvalue (exp_loc, next,
5422 true, true);
5423 rec = build_compound_expr (comma_loc, rec, next.value);
5424 }
5425 parse_message_args:
5426 /* Now parse the objc-message-args. */
5427 args = c_parser_objc_message_args (parser);
5428 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5429 "expected %<]%>");
5430 mexpr.value
5431 = objc_build_message_expr (rec, args);
5432 mexpr.original_code = ERROR_MARK;
5433 mexpr.original_type = NULL;
5434 /* Now parse and process the remainder of the
5435 initializer, starting with this message
5436 expression as a primary-expression. */
5437 c_parser_initval (parser, &mexpr, braced_init_obstack);
5438 return;
5439 }
5440 c_parser_consume_token (parser);
5441 array_index_loc = c_parser_peek_token (parser)->location;
5442 first = c_parser_expr_no_commas (parser, NULL).value;
5443 mark_exp_read (first);
5444 array_desig_after_first:
5445 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
5446 {
5447 ellipsis_loc = c_parser_peek_token (parser)->location;
5448 c_parser_consume_token (parser);
5449 second = c_parser_expr_no_commas (parser, NULL).value;
5450 mark_exp_read (second);
5451 }
5452 else
5453 second = NULL_TREE;
5454 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
5455 {
5456 c_parser_consume_token (parser);
5457 set_init_index (array_index_loc, first, second,
5458 braced_init_obstack);
5459 if (second)
5460 pedwarn (ellipsis_loc, OPT_Wpedantic,
5461 "ISO C forbids specifying range of elements to initialize");
5462 }
5463 else
5464 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
5465 "expected %<]%>");
5466 }
5467 }
5468 if (des_seen >= 1)
5469 {
5470 if (c_parser_next_token_is (parser, CPP_EQ))
5471 {
5472 pedwarn_c90 (des_loc, OPT_Wpedantic,
5473 "ISO C90 forbids specifying subobject "
5474 "to initialize");
5475 c_parser_consume_token (parser);
5476 }
5477 else
5478 {
5479 if (des_seen == 1)
5480 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
5481 "obsolete use of designated initializer without %<=%>");
5482 else
5483 {
5484 struct c_expr init;
5485 init.set_error ();
5486 init.original_code = ERROR_MARK;
5487 init.original_type = NULL;
5488 c_parser_error (parser, "expected %<=%>");
5489 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
5490 process_init_element (input_location, init, false,
5491 braced_init_obstack);
5492 return;
5493 }
5494 }
5495 }
5496 }
5497 c_parser_initval (parser, NULL, braced_init_obstack);
5498 }
5499
5500 /* Parse a nested initializer; as c_parser_initializer but parses
5501 initializers within braced lists, after any designators have been
5502 applied. If AFTER is not NULL then it is an Objective-C message
5503 expression which is the primary-expression starting the
5504 initializer. */
5505
5506 static void
5507 c_parser_initval (c_parser *parser, struct c_expr *after,
5508 struct obstack * braced_init_obstack)
5509 {
5510 struct c_expr init;
5511 gcc_assert (!after || c_dialect_objc ());
5512 location_t loc = c_parser_peek_token (parser)->location;
5513
5514 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after)
5515 init = c_parser_braced_init (parser, NULL_TREE, true,
5516 braced_init_obstack);
5517 else
5518 {
5519 init = c_parser_expr_no_commas (parser, after);
5520 if (init.value != NULL_TREE
5521 && TREE_CODE (init.value) != STRING_CST
5522 && TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR)
5523 init = convert_lvalue_to_rvalue (loc, init, true, true);
5524 }
5525 process_init_element (loc, init, false, braced_init_obstack);
5526 }
5527
5528 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
5529 C99 6.8.2, C11 6.8.2, C2X 6.8.2).
5530
5531 compound-statement:
5532 { block-item-list[opt] }
5533 { label-declarations block-item-list }
5534
5535 block-item-list:
5536 block-item
5537 block-item-list block-item
5538
5539 block-item:
5540 label
5541 nested-declaration
5542 statement
5543
5544 nested-declaration:
5545 declaration
5546
5547 GNU extensions:
5548
5549 compound-statement:
5550 { label-declarations block-item-list }
5551
5552 nested-declaration:
5553 __extension__ nested-declaration
5554 nested-function-definition
5555
5556 label-declarations:
5557 label-declaration
5558 label-declarations label-declaration
5559
5560 label-declaration:
5561 __label__ identifier-list ;
5562
5563 Allowing the mixing of declarations and code is new in C99. The
5564 GNU syntax also permits (not shown above) labels at the end of
5565 compound statements, which yield an error. We don't allow labels
5566 on declarations; this might seem like a natural extension, but
5567 there would be a conflict between gnu-attributes on the label and
5568 prefix gnu-attributes on the declaration. ??? The syntax follows the
5569 old parser in requiring something after label declarations.
5570 Although they are erroneous if the labels declared aren't defined,
5571 is it useful for the syntax to be this way?
5572
5573 OpenACC:
5574
5575 block-item:
5576 openacc-directive
5577
5578 openacc-directive:
5579 update-directive
5580
5581 OpenMP:
5582
5583 block-item:
5584 openmp-directive
5585
5586 openmp-directive:
5587 barrier-directive
5588 flush-directive
5589 taskwait-directive
5590 taskyield-directive
5591 cancel-directive
5592 cancellation-point-directive */
5593
5594 static tree
5595 c_parser_compound_statement (c_parser *parser, location_t *endlocp)
5596 {
5597 tree stmt;
5598 location_t brace_loc;
5599 brace_loc = c_parser_peek_token (parser)->location;
5600 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
5601 {
5602 /* Ensure a scope is entered and left anyway to avoid confusion
5603 if we have just prepared to enter a function body. */
5604 stmt = c_begin_compound_stmt (true);
5605 c_end_compound_stmt (brace_loc, stmt, true);
5606 return error_mark_node;
5607 }
5608 stmt = c_begin_compound_stmt (true);
5609 location_t end_loc = c_parser_compound_statement_nostart (parser);
5610 if (endlocp)
5611 *endlocp = end_loc;
5612
5613 return c_end_compound_stmt (brace_loc, stmt, true);
5614 }
5615
5616 /* Parse a compound statement except for the opening brace. This is
5617 used for parsing both compound statements and statement expressions
5618 (which follow different paths to handling the opening). */
5619
5620 static location_t
5621 c_parser_compound_statement_nostart (c_parser *parser)
5622 {
5623 bool last_stmt = false;
5624 bool last_label = false;
5625 bool save_valid_for_pragma = valid_location_for_stdc_pragma_p ();
5626 location_t label_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5627 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5628 {
5629 location_t endloc = c_parser_peek_token (parser)->location;
5630 add_debug_begin_stmt (endloc);
5631 c_parser_consume_token (parser);
5632 return endloc;
5633 }
5634 mark_valid_location_for_stdc_pragma (true);
5635 if (c_parser_next_token_is_keyword (parser, RID_LABEL))
5636 {
5637 /* Read zero or more forward-declarations for labels that nested
5638 functions can jump to. */
5639 mark_valid_location_for_stdc_pragma (false);
5640 while (c_parser_next_token_is_keyword (parser, RID_LABEL))
5641 {
5642 label_loc = c_parser_peek_token (parser)->location;
5643 c_parser_consume_token (parser);
5644 /* Any identifiers, including those declared as type names,
5645 are OK here. */
5646 while (true)
5647 {
5648 tree label;
5649 if (c_parser_next_token_is_not (parser, CPP_NAME))
5650 {
5651 c_parser_error (parser, "expected identifier");
5652 break;
5653 }
5654 label
5655 = declare_label (c_parser_peek_token (parser)->value);
5656 C_DECLARED_LABEL_FLAG (label) = 1;
5657 add_stmt (build_stmt (label_loc, DECL_EXPR, label));
5658 c_parser_consume_token (parser);
5659 if (c_parser_next_token_is (parser, CPP_COMMA))
5660 c_parser_consume_token (parser);
5661 else
5662 break;
5663 }
5664 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
5665 }
5666 pedwarn (label_loc, OPT_Wpedantic, "ISO C forbids label declarations");
5667 }
5668 /* We must now have at least one statement, label or declaration. */
5669 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5670 {
5671 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5672 c_parser_error (parser, "expected declaration or statement");
5673 location_t endloc = c_parser_peek_token (parser)->location;
5674 c_parser_consume_token (parser);
5675 return endloc;
5676 }
5677 while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
5678 {
5679 location_t loc = c_parser_peek_token (parser)->location;
5680 loc = expansion_point_location_if_in_system_header (loc);
5681 /* Standard attributes may start a label, statement or declaration. */
5682 bool have_std_attrs
5683 = c_parser_nth_token_starts_std_attributes (parser, 1);
5684 tree std_attrs = NULL_TREE;
5685 if (have_std_attrs)
5686 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5687 if (c_parser_next_token_is_keyword (parser, RID_CASE)
5688 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
5689 || (c_parser_next_token_is (parser, CPP_NAME)
5690 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5691 {
5692 if (c_parser_next_token_is_keyword (parser, RID_CASE))
5693 label_loc = c_parser_peek_2nd_token (parser)->location;
5694 else
5695 label_loc = c_parser_peek_token (parser)->location;
5696 last_label = true;
5697 last_stmt = false;
5698 mark_valid_location_for_stdc_pragma (false);
5699 c_parser_label (parser, std_attrs);
5700 }
5701 else if (c_parser_next_tokens_start_declaration (parser)
5702 || (have_std_attrs
5703 && c_parser_next_token_is (parser, CPP_SEMICOLON)))
5704 {
5705 if (last_label)
5706 pedwarn_c11 (c_parser_peek_token (parser)->location, OPT_Wpedantic,
5707 "a label can only be part of a statement and "
5708 "a declaration is not a statement");
5709
5710 mark_valid_location_for_stdc_pragma (false);
5711 bool fallthru_attr_p = false;
5712 c_parser_declaration_or_fndef (parser, true, !have_std_attrs,
5713 true, true, true, NULL,
5714 NULL, have_std_attrs, std_attrs,
5715 NULL, &fallthru_attr_p);
5716
5717 if (last_stmt && !fallthru_attr_p)
5718 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
5719 "ISO C90 forbids mixed declarations and code");
5720 last_stmt = fallthru_attr_p;
5721 last_label = false;
5722 }
5723 else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
5724 {
5725 /* __extension__ can start a declaration, but is also an
5726 unary operator that can start an expression. Consume all
5727 but the last of a possible series of __extension__ to
5728 determine which. If standard attributes have already
5729 been seen, it must start a statement, not a declaration,
5730 but standard attributes starting a declaration may appear
5731 after __extension__. */
5732 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
5733 && (c_parser_peek_2nd_token (parser)->keyword
5734 == RID_EXTENSION))
5735 c_parser_consume_token (parser);
5736 if (!have_std_attrs
5737 && (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
5738 || c_parser_nth_token_starts_std_attributes (parser, 2)))
5739 {
5740 int ext;
5741 ext = disable_extension_diagnostics ();
5742 c_parser_consume_token (parser);
5743 last_label = false;
5744 mark_valid_location_for_stdc_pragma (false);
5745 c_parser_declaration_or_fndef (parser, true, true, true, true,
5746 true);
5747 /* Following the old parser, __extension__ does not
5748 disable this diagnostic. */
5749 restore_extension_diagnostics (ext);
5750 if (last_stmt)
5751 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
5752 "ISO C90 forbids mixed declarations and code");
5753 last_stmt = false;
5754 }
5755 else
5756 goto statement;
5757 }
5758 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
5759 {
5760 if (have_std_attrs)
5761 c_parser_error (parser, "expected declaration or statement");
5762 /* External pragmas, and some omp pragmas, are not associated
5763 with regular c code, and so are not to be considered statements
5764 syntactically. This ensures that the user doesn't put them
5765 places that would turn into syntax errors if the directive
5766 were ignored. */
5767 if (c_parser_pragma (parser,
5768 last_label ? pragma_stmt : pragma_compound,
5769 NULL))
5770 last_label = false, last_stmt = true;
5771 }
5772 else if (c_parser_next_token_is (parser, CPP_EOF))
5773 {
5774 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5775 c_parser_error (parser, "expected declaration or statement");
5776 return c_parser_peek_token (parser)->location;
5777 }
5778 else if (c_parser_next_token_is_keyword (parser, RID_ELSE))
5779 {
5780 if (parser->in_if_block)
5781 {
5782 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5783 error_at (loc, "expected %<}%> before %<else%>");
5784 return c_parser_peek_token (parser)->location;
5785 }
5786 else
5787 {
5788 error_at (loc, "%<else%> without a previous %<if%>");
5789 c_parser_consume_token (parser);
5790 continue;
5791 }
5792 }
5793 else
5794 {
5795 statement:
5796 c_warn_unused_attributes (std_attrs);
5797 last_label = false;
5798 last_stmt = true;
5799 mark_valid_location_for_stdc_pragma (false);
5800 c_parser_statement_after_labels (parser, NULL);
5801 }
5802
5803 parser->error = false;
5804 }
5805 if (last_label)
5806 pedwarn_c11 (label_loc, OPT_Wpedantic, "label at end of compound statement");
5807 location_t endloc = c_parser_peek_token (parser)->location;
5808 c_parser_consume_token (parser);
5809 /* Restore the value we started with. */
5810 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5811 return endloc;
5812 }
5813
5814 /* Parse all consecutive labels, possibly preceded by standard
5815 attributes. In this context, a statement is required, not a
5816 declaration, so attributes must be followed by a statement that is
5817 not just a semicolon. */
5818
5819 static void
5820 c_parser_all_labels (c_parser *parser)
5821 {
5822 tree std_attrs = NULL;
5823 if (c_parser_nth_token_starts_std_attributes (parser, 1))
5824 {
5825 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5826 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5827 c_parser_error (parser, "expected statement");
5828 }
5829 while (c_parser_next_token_is_keyword (parser, RID_CASE)
5830 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
5831 || (c_parser_next_token_is (parser, CPP_NAME)
5832 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5833 {
5834 c_parser_label (parser, std_attrs);
5835 std_attrs = NULL;
5836 if (c_parser_nth_token_starts_std_attributes (parser, 1))
5837 {
5838 std_attrs = c_parser_std_attribute_specifier_sequence (parser);
5839 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5840 c_parser_error (parser, "expected statement");
5841 }
5842 }
5843 if (std_attrs)
5844 c_warn_unused_attributes (std_attrs);
5845 }
5846
5847 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
5848
5849 label:
5850 identifier : gnu-attributes[opt]
5851 case constant-expression :
5852 default :
5853
5854 GNU extensions:
5855
5856 label:
5857 case constant-expression ... constant-expression :
5858
5859 The use of gnu-attributes on labels is a GNU extension. The syntax in
5860 GNU C accepts any expressions without commas, non-constant
5861 expressions being rejected later. Any standard
5862 attribute-specifier-sequence before the first label has been parsed
5863 in the caller, to distinguish statements from declarations. Any
5864 attribute-specifier-sequence after the label is parsed in this
5865 function. */
5866 static void
5867 c_parser_label (c_parser *parser, tree std_attrs)
5868 {
5869 location_t loc1 = c_parser_peek_token (parser)->location;
5870 tree label = NULL_TREE;
5871
5872 /* Remember whether this case or a user-defined label is allowed to fall
5873 through to. */
5874 bool fallthrough_p = c_parser_peek_token (parser)->flags & PREV_FALLTHROUGH;
5875
5876 if (c_parser_next_token_is_keyword (parser, RID_CASE))
5877 {
5878 tree exp1, exp2;
5879 c_parser_consume_token (parser);
5880 exp1 = c_parser_expr_no_commas (parser, NULL).value;
5881 if (c_parser_next_token_is (parser, CPP_COLON))
5882 {
5883 c_parser_consume_token (parser);
5884 label = do_case (loc1, exp1, NULL_TREE);
5885 }
5886 else if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
5887 {
5888 c_parser_consume_token (parser);
5889 exp2 = c_parser_expr_no_commas (parser, NULL).value;
5890 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
5891 label = do_case (loc1, exp1, exp2);
5892 }
5893 else
5894 c_parser_error (parser, "expected %<:%> or %<...%>");
5895 }
5896 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
5897 {
5898 c_parser_consume_token (parser);
5899 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
5900 label = do_case (loc1, NULL_TREE, NULL_TREE);
5901 }
5902 else
5903 {
5904 tree name = c_parser_peek_token (parser)->value;
5905 tree tlab;
5906 tree attrs;
5907 location_t loc2 = c_parser_peek_token (parser)->location;
5908 gcc_assert (c_parser_next_token_is (parser, CPP_NAME));
5909 c_parser_consume_token (parser);
5910 gcc_assert (c_parser_next_token_is (parser, CPP_COLON));
5911 c_parser_consume_token (parser);
5912 attrs = c_parser_gnu_attributes (parser);
5913 tlab = define_label (loc2, name);
5914 if (tlab)
5915 {
5916 decl_attributes (&tlab, attrs, 0);
5917 decl_attributes (&tlab, std_attrs, 0);
5918 label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab));
5919 }
5920 if (attrs
5921 && c_parser_next_tokens_start_declaration (parser))
5922 warning_at (loc2, OPT_Wattributes, "GNU-style attribute between"
5923 " label and declaration appertains to the label");
5924 }
5925 if (label)
5926 {
5927 if (TREE_CODE (label) == LABEL_EXPR)
5928 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label)) = fallthrough_p;
5929 else
5930 FALLTHROUGH_LABEL_P (CASE_LABEL (label)) = fallthrough_p;
5931 }
5932 }
5933
5934 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
5935
5936 statement:
5937 labeled-statement
5938 attribute-specifier-sequence[opt] compound-statement
5939 expression-statement
5940 attribute-specifier-sequence[opt] selection-statement
5941 attribute-specifier-sequence[opt] iteration-statement
5942 attribute-specifier-sequence[opt] jump-statement
5943
5944 labeled-statement:
5945 attribute-specifier-sequence[opt] label statement
5946
5947 expression-statement:
5948 expression[opt] ;
5949 attribute-specifier-sequence expression ;
5950
5951 selection-statement:
5952 if-statement
5953 switch-statement
5954
5955 iteration-statement:
5956 while-statement
5957 do-statement
5958 for-statement
5959
5960 jump-statement:
5961 goto identifier ;
5962 continue ;
5963 break ;
5964 return expression[opt] ;
5965
5966 GNU extensions:
5967
5968 statement:
5969 attribute-specifier-sequence[opt] asm-statement
5970
5971 jump-statement:
5972 goto * expression ;
5973
5974 expression-statement:
5975 gnu-attributes ;
5976
5977 Objective-C:
5978
5979 statement:
5980 attribute-specifier-sequence[opt] objc-throw-statement
5981 attribute-specifier-sequence[opt] objc-try-catch-statement
5982 attribute-specifier-sequence[opt] objc-synchronized-statement
5983
5984 objc-throw-statement:
5985 @throw expression ;
5986 @throw ;
5987
5988 OpenACC:
5989
5990 statement:
5991 attribute-specifier-sequence[opt] openacc-construct
5992
5993 openacc-construct:
5994 parallel-construct
5995 kernels-construct
5996 data-construct
5997 loop-construct
5998
5999 parallel-construct:
6000 parallel-directive structured-block
6001
6002 kernels-construct:
6003 kernels-directive structured-block
6004
6005 data-construct:
6006 data-directive structured-block
6007
6008 loop-construct:
6009 loop-directive structured-block
6010
6011 OpenMP:
6012
6013 statement:
6014 attribute-specifier-sequence[opt] openmp-construct
6015
6016 openmp-construct:
6017 parallel-construct
6018 for-construct
6019 simd-construct
6020 for-simd-construct
6021 sections-construct
6022 single-construct
6023 parallel-for-construct
6024 parallel-for-simd-construct
6025 parallel-sections-construct
6026 master-construct
6027 critical-construct
6028 atomic-construct
6029 ordered-construct
6030
6031 parallel-construct:
6032 parallel-directive structured-block
6033
6034 for-construct:
6035 for-directive iteration-statement
6036
6037 simd-construct:
6038 simd-directive iteration-statements
6039
6040 for-simd-construct:
6041 for-simd-directive iteration-statements
6042
6043 sections-construct:
6044 sections-directive section-scope
6045
6046 single-construct:
6047 single-directive structured-block
6048
6049 parallel-for-construct:
6050 parallel-for-directive iteration-statement
6051
6052 parallel-for-simd-construct:
6053 parallel-for-simd-directive iteration-statement
6054
6055 parallel-sections-construct:
6056 parallel-sections-directive section-scope
6057
6058 master-construct:
6059 master-directive structured-block
6060
6061 critical-construct:
6062 critical-directive structured-block
6063
6064 atomic-construct:
6065 atomic-directive expression-statement
6066
6067 ordered-construct:
6068 ordered-directive structured-block
6069
6070 Transactional Memory:
6071
6072 statement:
6073 attribute-specifier-sequence[opt] transaction-statement
6074 attribute-specifier-sequence[opt] transaction-cancel-statement
6075
6076 IF_P is used to track whether there's a (possibly labeled) if statement
6077 which is not enclosed in braces and has an else clause. This is used to
6078 implement -Wparentheses. */
6079
6080 static void
6081 c_parser_statement (c_parser *parser, bool *if_p, location_t *loc_after_labels)
6082 {
6083 c_parser_all_labels (parser);
6084 if (loc_after_labels)
6085 *loc_after_labels = c_parser_peek_token (parser)->location;
6086 c_parser_statement_after_labels (parser, if_p, NULL);
6087 }
6088
6089 /* Parse a statement, other than a labeled statement. CHAIN is a vector
6090 of if-else-if conditions. All labels and standard attributes have
6091 been parsed in the caller.
6092
6093 IF_P is used to track whether there's a (possibly labeled) if statement
6094 which is not enclosed in braces and has an else clause. This is used to
6095 implement -Wparentheses. */
6096
6097 static void
6098 c_parser_statement_after_labels (c_parser *parser, bool *if_p,
6099 vec<tree> *chain)
6100 {
6101 location_t loc = c_parser_peek_token (parser)->location;
6102 tree stmt = NULL_TREE;
6103 bool in_if_block = parser->in_if_block;
6104 parser->in_if_block = false;
6105 if (if_p != NULL)
6106 *if_p = false;
6107
6108 if (c_parser_peek_token (parser)->type != CPP_OPEN_BRACE)
6109 add_debug_begin_stmt (loc);
6110
6111 restart:
6112 switch (c_parser_peek_token (parser)->type)
6113 {
6114 case CPP_OPEN_BRACE:
6115 add_stmt (c_parser_compound_statement (parser));
6116 break;
6117 case CPP_KEYWORD:
6118 switch (c_parser_peek_token (parser)->keyword)
6119 {
6120 case RID_IF:
6121 c_parser_if_statement (parser, if_p, chain);
6122 break;
6123 case RID_SWITCH:
6124 c_parser_switch_statement (parser, if_p);
6125 break;
6126 case RID_WHILE:
6127 c_parser_while_statement (parser, false, 0, if_p);
6128 break;
6129 case RID_DO:
6130 c_parser_do_statement (parser, false, 0);
6131 break;
6132 case RID_FOR:
6133 c_parser_for_statement (parser, false, 0, if_p);
6134 break;
6135 case RID_GOTO:
6136 c_parser_consume_token (parser);
6137 if (c_parser_next_token_is (parser, CPP_NAME))
6138 {
6139 stmt = c_finish_goto_label (loc,
6140 c_parser_peek_token (parser)->value);
6141 c_parser_consume_token (parser);
6142 }
6143 else if (c_parser_next_token_is (parser, CPP_MULT))
6144 {
6145 struct c_expr val;
6146
6147 c_parser_consume_token (parser);
6148 val = c_parser_expression (parser);
6149 val = convert_lvalue_to_rvalue (loc, val, false, true);
6150 stmt = c_finish_goto_ptr (loc, val);
6151 }
6152 else
6153 c_parser_error (parser, "expected identifier or %<*%>");
6154 goto expect_semicolon;
6155 case RID_CONTINUE:
6156 c_parser_consume_token (parser);
6157 stmt = c_finish_bc_stmt (loc, objc_foreach_continue_label, false);
6158 goto expect_semicolon;
6159 case RID_BREAK:
6160 c_parser_consume_token (parser);
6161 stmt = c_finish_bc_stmt (loc, objc_foreach_break_label, true);
6162 goto expect_semicolon;
6163 case RID_RETURN:
6164 c_parser_consume_token (parser);
6165 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6166 {
6167 stmt = c_finish_return (loc, NULL_TREE, NULL_TREE);
6168 c_parser_consume_token (parser);
6169 }
6170 else
6171 {
6172 location_t xloc = c_parser_peek_token (parser)->location;
6173 struct c_expr expr = c_parser_expression_conv (parser);
6174 mark_exp_read (expr.value);
6175 stmt = c_finish_return (EXPR_LOC_OR_LOC (expr.value, xloc),
6176 expr.value, expr.original_type);
6177 goto expect_semicolon;
6178 }
6179 break;
6180 case RID_ASM:
6181 stmt = c_parser_asm_statement (parser);
6182 break;
6183 case RID_TRANSACTION_ATOMIC:
6184 case RID_TRANSACTION_RELAXED:
6185 stmt = c_parser_transaction (parser,
6186 c_parser_peek_token (parser)->keyword);
6187 break;
6188 case RID_TRANSACTION_CANCEL:
6189 stmt = c_parser_transaction_cancel (parser);
6190 goto expect_semicolon;
6191 case RID_AT_THROW:
6192 gcc_assert (c_dialect_objc ());
6193 c_parser_consume_token (parser);
6194 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6195 {
6196 stmt = objc_build_throw_stmt (loc, NULL_TREE);
6197 c_parser_consume_token (parser);
6198 }
6199 else
6200 {
6201 struct c_expr expr = c_parser_expression (parser);
6202 expr = convert_lvalue_to_rvalue (loc, expr, false, false);
6203 expr.value = c_fully_fold (expr.value, false, NULL);
6204 stmt = objc_build_throw_stmt (loc, expr.value);
6205 goto expect_semicolon;
6206 }
6207 break;
6208 case RID_AT_TRY:
6209 gcc_assert (c_dialect_objc ());
6210 c_parser_objc_try_catch_finally_statement (parser);
6211 break;
6212 case RID_AT_SYNCHRONIZED:
6213 gcc_assert (c_dialect_objc ());
6214 c_parser_objc_synchronized_statement (parser);
6215 break;
6216 case RID_ATTRIBUTE:
6217 {
6218 /* Allow '__attribute__((fallthrough));'. */
6219 tree attrs = c_parser_gnu_attributes (parser);
6220 if (attribute_fallthrough_p (attrs))
6221 {
6222 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6223 {
6224 tree fn = build_call_expr_internal_loc (loc,
6225 IFN_FALLTHROUGH,
6226 void_type_node, 0);
6227 add_stmt (fn);
6228 /* Eat the ';'. */
6229 c_parser_consume_token (parser);
6230 }
6231 else
6232 warning_at (loc, OPT_Wattributes,
6233 "%<fallthrough%> attribute not followed "
6234 "by %<;%>");
6235 }
6236 else if (attrs != NULL_TREE)
6237 warning_at (loc, OPT_Wattributes, "only attribute %<fallthrough%>"
6238 " can be applied to a null statement");
6239 break;
6240 }
6241 default:
6242 goto expr_stmt;
6243 }
6244 break;
6245 case CPP_SEMICOLON:
6246 c_parser_consume_token (parser);
6247 break;
6248 case CPP_CLOSE_PAREN:
6249 case CPP_CLOSE_SQUARE:
6250 /* Avoid infinite loop in error recovery:
6251 c_parser_skip_until_found stops at a closing nesting
6252 delimiter without consuming it, but here we need to consume
6253 it to proceed further. */
6254 c_parser_error (parser, "expected statement");
6255 c_parser_consume_token (parser);
6256 break;
6257 case CPP_PRAGMA:
6258 if (!c_parser_pragma (parser, pragma_stmt, if_p))
6259 goto restart;
6260 break;
6261 default:
6262 expr_stmt:
6263 stmt = c_finish_expr_stmt (loc, c_parser_expression_conv (parser).value);
6264 expect_semicolon:
6265 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
6266 break;
6267 }
6268 /* Two cases cannot and do not have line numbers associated: If stmt
6269 is degenerate, such as "2;", then stmt is an INTEGER_CST, which
6270 cannot hold line numbers. But that's OK because the statement
6271 will either be changed to a MODIFY_EXPR during gimplification of
6272 the statement expr, or discarded. If stmt was compound, but
6273 without new variables, we will have skipped the creation of a
6274 BIND and will have a bare STATEMENT_LIST. But that's OK because
6275 (recursively) all of the component statements should already have
6276 line numbers assigned. ??? Can we discard no-op statements
6277 earlier? */
6278 if (EXPR_LOCATION (stmt) == UNKNOWN_LOCATION)
6279 protected_set_expr_location (stmt, loc);
6280
6281 parser->in_if_block = in_if_block;
6282 }
6283
6284 /* Parse the condition from an if, do, while or for statements. */
6285
6286 static tree
6287 c_parser_condition (c_parser *parser)
6288 {
6289 location_t loc = c_parser_peek_token (parser)->location;
6290 tree cond;
6291 cond = c_parser_expression_conv (parser).value;
6292 cond = c_objc_common_truthvalue_conversion (loc, cond);
6293 cond = c_fully_fold (cond, false, NULL);
6294 if (warn_sequence_point)
6295 verify_sequence_points (cond);
6296 return cond;
6297 }
6298
6299 /* Parse a parenthesized condition from an if, do or while statement.
6300
6301 condition:
6302 ( expression )
6303 */
6304 static tree
6305 c_parser_paren_condition (c_parser *parser)
6306 {
6307 tree cond;
6308 matching_parens parens;
6309 if (!parens.require_open (parser))
6310 return error_mark_node;
6311 cond = c_parser_condition (parser);
6312 parens.skip_until_found_close (parser);
6313 return cond;
6314 }
6315
6316 /* Parse a statement which is a block in C99.
6317
6318 IF_P is used to track whether there's a (possibly labeled) if statement
6319 which is not enclosed in braces and has an else clause. This is used to
6320 implement -Wparentheses. */
6321
6322 static tree
6323 c_parser_c99_block_statement (c_parser *parser, bool *if_p,
6324 location_t *loc_after_labels)
6325 {
6326 tree block = c_begin_compound_stmt (flag_isoc99);
6327 location_t loc = c_parser_peek_token (parser)->location;
6328 c_parser_statement (parser, if_p, loc_after_labels);
6329 return c_end_compound_stmt (loc, block, flag_isoc99);
6330 }
6331
6332 /* Parse the body of an if statement. This is just parsing a
6333 statement but (a) it is a block in C99, (b) we track whether the
6334 body is an if statement for the sake of -Wparentheses warnings, (c)
6335 we handle an empty body specially for the sake of -Wempty-body
6336 warnings, and (d) we call parser_compound_statement directly
6337 because c_parser_statement_after_labels resets
6338 parser->in_if_block.
6339
6340 IF_P is used to track whether there's a (possibly labeled) if statement
6341 which is not enclosed in braces and has an else clause. This is used to
6342 implement -Wparentheses. */
6343
6344 static tree
6345 c_parser_if_body (c_parser *parser, bool *if_p,
6346 const token_indent_info &if_tinfo)
6347 {
6348 tree block = c_begin_compound_stmt (flag_isoc99);
6349 location_t body_loc = c_parser_peek_token (parser)->location;
6350 location_t body_loc_after_labels = UNKNOWN_LOCATION;
6351 token_indent_info body_tinfo
6352 = get_token_indent_info (c_parser_peek_token (parser));
6353
6354 c_parser_all_labels (parser);
6355 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6356 {
6357 location_t loc = c_parser_peek_token (parser)->location;
6358 add_stmt (build_empty_stmt (loc));
6359 c_parser_consume_token (parser);
6360 if (!c_parser_next_token_is_keyword (parser, RID_ELSE))
6361 warning_at (loc, OPT_Wempty_body,
6362 "suggest braces around empty body in an %<if%> statement");
6363 }
6364 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6365 add_stmt (c_parser_compound_statement (parser));
6366 else
6367 {
6368 body_loc_after_labels = c_parser_peek_token (parser)->location;
6369 c_parser_statement_after_labels (parser, if_p);
6370 }
6371
6372 token_indent_info next_tinfo
6373 = get_token_indent_info (c_parser_peek_token (parser));
6374 warn_for_misleading_indentation (if_tinfo, body_tinfo, next_tinfo);
6375 if (body_loc_after_labels != UNKNOWN_LOCATION
6376 && next_tinfo.type != CPP_SEMICOLON)
6377 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
6378 if_tinfo.location, RID_IF);
6379
6380 return c_end_compound_stmt (body_loc, block, flag_isoc99);
6381 }
6382
6383 /* Parse the else body of an if statement. This is just parsing a
6384 statement but (a) it is a block in C99, (b) we handle an empty body
6385 specially for the sake of -Wempty-body warnings. CHAIN is a vector
6386 of if-else-if conditions. */
6387
6388 static tree
6389 c_parser_else_body (c_parser *parser, const token_indent_info &else_tinfo,
6390 vec<tree> *chain)
6391 {
6392 location_t body_loc = c_parser_peek_token (parser)->location;
6393 tree block = c_begin_compound_stmt (flag_isoc99);
6394 token_indent_info body_tinfo
6395 = get_token_indent_info (c_parser_peek_token (parser));
6396 location_t body_loc_after_labels = UNKNOWN_LOCATION;
6397
6398 c_parser_all_labels (parser);
6399 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6400 {
6401 location_t loc = c_parser_peek_token (parser)->location;
6402 warning_at (loc,
6403 OPT_Wempty_body,
6404 "suggest braces around empty body in an %<else%> statement");
6405 add_stmt (build_empty_stmt (loc));
6406 c_parser_consume_token (parser);
6407 }
6408 else
6409 {
6410 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
6411 body_loc_after_labels = c_parser_peek_token (parser)->location;
6412 c_parser_statement_after_labels (parser, NULL, chain);
6413 }
6414
6415 token_indent_info next_tinfo
6416 = get_token_indent_info (c_parser_peek_token (parser));
6417 warn_for_misleading_indentation (else_tinfo, body_tinfo, next_tinfo);
6418 if (body_loc_after_labels != UNKNOWN_LOCATION
6419 && next_tinfo.type != CPP_SEMICOLON)
6420 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
6421 else_tinfo.location, RID_ELSE);
6422
6423 return c_end_compound_stmt (body_loc, block, flag_isoc99);
6424 }
6425
6426 /* We might need to reclassify any previously-lexed identifier, e.g.
6427 when we've left a for loop with an if-statement without else in the
6428 body - we might have used a wrong scope for the token. See PR67784. */
6429
6430 static void
6431 c_parser_maybe_reclassify_token (c_parser *parser)
6432 {
6433 if (c_parser_next_token_is (parser, CPP_NAME))
6434 {
6435 c_token *token = c_parser_peek_token (parser);
6436
6437 if (token->id_kind != C_ID_CLASSNAME)
6438 {
6439 tree decl = lookup_name (token->value);
6440
6441 token->id_kind = C_ID_ID;
6442 if (decl)
6443 {
6444 if (TREE_CODE (decl) == TYPE_DECL)
6445 token->id_kind = C_ID_TYPENAME;
6446 }
6447 else if (c_dialect_objc ())
6448 {
6449 tree objc_interface_decl = objc_is_class_name (token->value);
6450 /* Objective-C class names are in the same namespace as
6451 variables and typedefs, and hence are shadowed by local
6452 declarations. */
6453 if (objc_interface_decl)
6454 {
6455 token->value = objc_interface_decl;
6456 token->id_kind = C_ID_CLASSNAME;
6457 }
6458 }
6459 }
6460 }
6461 }
6462
6463 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6464
6465 if-statement:
6466 if ( expression ) statement
6467 if ( expression ) statement else statement
6468
6469 CHAIN is a vector of if-else-if conditions.
6470 IF_P is used to track whether there's a (possibly labeled) if statement
6471 which is not enclosed in braces and has an else clause. This is used to
6472 implement -Wparentheses. */
6473
6474 static void
6475 c_parser_if_statement (c_parser *parser, bool *if_p, vec<tree> *chain)
6476 {
6477 tree block;
6478 location_t loc;
6479 tree cond;
6480 bool nested_if = false;
6481 tree first_body, second_body;
6482 bool in_if_block;
6483
6484 gcc_assert (c_parser_next_token_is_keyword (parser, RID_IF));
6485 token_indent_info if_tinfo
6486 = get_token_indent_info (c_parser_peek_token (parser));
6487 c_parser_consume_token (parser);
6488 block = c_begin_compound_stmt (flag_isoc99);
6489 loc = c_parser_peek_token (parser)->location;
6490 cond = c_parser_paren_condition (parser);
6491 in_if_block = parser->in_if_block;
6492 parser->in_if_block = true;
6493 first_body = c_parser_if_body (parser, &nested_if, if_tinfo);
6494 parser->in_if_block = in_if_block;
6495
6496 if (warn_duplicated_cond)
6497 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond), cond, &chain);
6498
6499 if (c_parser_next_token_is_keyword (parser, RID_ELSE))
6500 {
6501 token_indent_info else_tinfo
6502 = get_token_indent_info (c_parser_peek_token (parser));
6503 c_parser_consume_token (parser);
6504 if (warn_duplicated_cond)
6505 {
6506 if (c_parser_next_token_is_keyword (parser, RID_IF)
6507 && chain == NULL)
6508 {
6509 /* We've got "if (COND) else if (COND2)". Start the
6510 condition chain and add COND as the first element. */
6511 chain = new vec<tree> ();
6512 if (!CONSTANT_CLASS_P (cond) && !TREE_SIDE_EFFECTS (cond))
6513 chain->safe_push (cond);
6514 }
6515 else if (!c_parser_next_token_is_keyword (parser, RID_IF))
6516 /* This is if-else without subsequent if. Zap the condition
6517 chain; we would have already warned at this point. */
6518 vec_free (chain);
6519 }
6520 second_body = c_parser_else_body (parser, else_tinfo, chain);
6521 /* Set IF_P to true to indicate that this if statement has an
6522 else clause. This may trigger the Wparentheses warning
6523 below when we get back up to the parent if statement. */
6524 if (if_p != NULL)
6525 *if_p = true;
6526 }
6527 else
6528 {
6529 second_body = NULL_TREE;
6530
6531 /* Diagnose an ambiguous else if if-then-else is nested inside
6532 if-then. */
6533 if (nested_if)
6534 warning_at (loc, OPT_Wdangling_else,
6535 "suggest explicit braces to avoid ambiguous %<else%>");
6536
6537 if (warn_duplicated_cond)
6538 /* This if statement does not have an else clause. We don't
6539 need the condition chain anymore. */
6540 vec_free (chain);
6541 }
6542 c_finish_if_stmt (loc, cond, first_body, second_body);
6543 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6544
6545 c_parser_maybe_reclassify_token (parser);
6546 }
6547
6548 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
6549
6550 switch-statement:
6551 switch (expression) statement
6552 */
6553
6554 static void
6555 c_parser_switch_statement (c_parser *parser, bool *if_p)
6556 {
6557 struct c_expr ce;
6558 tree block, expr, body;
6559 unsigned char save_in_statement;
6560 location_t switch_loc = c_parser_peek_token (parser)->location;
6561 location_t switch_cond_loc;
6562 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH));
6563 c_parser_consume_token (parser);
6564 block = c_begin_compound_stmt (flag_isoc99);
6565 bool explicit_cast_p = false;
6566 matching_parens parens;
6567 if (parens.require_open (parser))
6568 {
6569 switch_cond_loc = c_parser_peek_token (parser)->location;
6570 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
6571 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
6572 explicit_cast_p = true;
6573 ce = c_parser_expression (parser);
6574 ce = convert_lvalue_to_rvalue (switch_cond_loc, ce, true, true);
6575 expr = ce.value;
6576 /* ??? expr has no valid location? */
6577 parens.skip_until_found_close (parser);
6578 }
6579 else
6580 {
6581 switch_cond_loc = UNKNOWN_LOCATION;
6582 expr = error_mark_node;
6583 ce.original_type = error_mark_node;
6584 }
6585 c_start_switch (switch_loc, switch_cond_loc, expr, explicit_cast_p);
6586 save_in_statement = in_statement;
6587 in_statement |= IN_SWITCH_STMT;
6588 location_t loc_after_labels;
6589 bool open_brace_p = c_parser_peek_token (parser)->type == CPP_OPEN_BRACE;
6590 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6591 location_t next_loc = c_parser_peek_token (parser)->location;
6592 if (!open_brace_p && c_parser_peek_token (parser)->type != CPP_SEMICOLON)
6593 warn_for_multistatement_macros (loc_after_labels, next_loc, switch_loc,
6594 RID_SWITCH);
6595 c_finish_switch (body, ce.original_type);
6596 in_statement = save_in_statement;
6597 add_stmt (c_end_compound_stmt (switch_loc, block, flag_isoc99));
6598 c_parser_maybe_reclassify_token (parser);
6599 }
6600
6601 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6602
6603 while-statement:
6604 while (expression) statement
6605
6606 IF_P is used to track whether there's a (possibly labeled) if statement
6607 which is not enclosed in braces and has an else clause. This is used to
6608 implement -Wparentheses. */
6609
6610 static void
6611 c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6612 bool *if_p)
6613 {
6614 tree block, cond, body;
6615 unsigned char save_in_statement;
6616 location_t loc;
6617 gcc_assert (c_parser_next_token_is_keyword (parser, RID_WHILE));
6618 token_indent_info while_tinfo
6619 = get_token_indent_info (c_parser_peek_token (parser));
6620 c_parser_consume_token (parser);
6621 block = c_begin_compound_stmt (flag_isoc99);
6622 loc = c_parser_peek_token (parser)->location;
6623 cond = c_parser_paren_condition (parser);
6624 if (ivdep && cond != error_mark_node)
6625 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6626 build_int_cst (integer_type_node,
6627 annot_expr_ivdep_kind),
6628 integer_zero_node);
6629 if (unroll && cond != error_mark_node)
6630 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6631 build_int_cst (integer_type_node,
6632 annot_expr_unroll_kind),
6633 build_int_cst (integer_type_node, unroll));
6634 save_in_statement = in_statement;
6635 in_statement = IN_ITERATION_STMT;
6636
6637 token_indent_info body_tinfo
6638 = get_token_indent_info (c_parser_peek_token (parser));
6639
6640 location_t loc_after_labels;
6641 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
6642 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6643 add_stmt (build_stmt (loc, WHILE_STMT, cond, body));
6644 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6645 c_parser_maybe_reclassify_token (parser);
6646
6647 token_indent_info next_tinfo
6648 = get_token_indent_info (c_parser_peek_token (parser));
6649 warn_for_misleading_indentation (while_tinfo, body_tinfo, next_tinfo);
6650
6651 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
6652 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
6653 while_tinfo.location, RID_WHILE);
6654
6655 in_statement = save_in_statement;
6656 }
6657
6658 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6659
6660 do-statement:
6661 do statement while ( expression ) ;
6662 */
6663
6664 static void
6665 c_parser_do_statement (c_parser *parser, bool ivdep, unsigned short unroll)
6666 {
6667 tree block, cond, body;
6668 unsigned char save_in_statement;
6669 location_t loc;
6670 gcc_assert (c_parser_next_token_is_keyword (parser, RID_DO));
6671 c_parser_consume_token (parser);
6672 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6673 warning_at (c_parser_peek_token (parser)->location,
6674 OPT_Wempty_body,
6675 "suggest braces around empty body in %<do%> statement");
6676 block = c_begin_compound_stmt (flag_isoc99);
6677 loc = c_parser_peek_token (parser)->location;
6678 save_in_statement = in_statement;
6679 in_statement = IN_ITERATION_STMT;
6680 body = c_parser_c99_block_statement (parser, NULL);
6681 c_parser_require_keyword (parser, RID_WHILE, "expected %<while%>");
6682 in_statement = save_in_statement;
6683 cond = c_parser_paren_condition (parser);
6684 if (ivdep && cond != error_mark_node)
6685 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6686 build_int_cst (integer_type_node,
6687 annot_expr_ivdep_kind),
6688 integer_zero_node);
6689 if (unroll && cond != error_mark_node)
6690 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6691 build_int_cst (integer_type_node,
6692 annot_expr_unroll_kind),
6693 build_int_cst (integer_type_node, unroll));
6694 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
6695 c_parser_skip_to_end_of_block_or_statement (parser);
6696
6697 add_stmt (build_stmt (loc, DO_STMT, cond, body));
6698 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6699 }
6700
6701 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6702
6703 for-statement:
6704 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
6705 for ( nested-declaration expression[opt] ; expression[opt] ) statement
6706
6707 The form with a declaration is new in C99.
6708
6709 ??? In accordance with the old parser, the declaration may be a
6710 nested function, which is then rejected in check_for_loop_decls,
6711 but does it make any sense for this to be included in the grammar?
6712 Note in particular that the nested function does not include a
6713 trailing ';', whereas the "declaration" production includes one.
6714 Also, can we reject bad declarations earlier and cheaper than
6715 check_for_loop_decls?
6716
6717 In Objective-C, there are two additional variants:
6718
6719 foreach-statement:
6720 for ( expression in expresssion ) statement
6721 for ( declaration in expression ) statement
6722
6723 This is inconsistent with C, because the second variant is allowed
6724 even if c99 is not enabled.
6725
6726 The rest of the comment documents these Objective-C foreach-statement.
6727
6728 Here is the canonical example of the first variant:
6729 for (object in array) { do something with object }
6730 we call the first expression ("object") the "object_expression" and
6731 the second expression ("array") the "collection_expression".
6732 object_expression must be an lvalue of type "id" (a generic Objective-C
6733 object) because the loop works by assigning to object_expression the
6734 various objects from the collection_expression. collection_expression
6735 must evaluate to something of type "id" which responds to the method
6736 countByEnumeratingWithState:objects:count:.
6737
6738 The canonical example of the second variant is:
6739 for (id object in array) { do something with object }
6740 which is completely equivalent to
6741 {
6742 id object;
6743 for (object in array) { do something with object }
6744 }
6745 Note that initizializing 'object' in some way (eg, "for ((object =
6746 xxx) in array) { do something with object }") is possibly
6747 technically valid, but completely pointless as 'object' will be
6748 assigned to something else as soon as the loop starts. We should
6749 most likely reject it (TODO).
6750
6751 The beginning of the Objective-C foreach-statement looks exactly
6752 like the beginning of the for-statement, and we can tell it is a
6753 foreach-statement only because the initial declaration or
6754 expression is terminated by 'in' instead of ';'.
6755
6756 IF_P is used to track whether there's a (possibly labeled) if statement
6757 which is not enclosed in braces and has an else clause. This is used to
6758 implement -Wparentheses. */
6759
6760 static void
6761 c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6762 bool *if_p)
6763 {
6764 tree block, cond, incr, body;
6765 unsigned char save_in_statement;
6766 tree save_objc_foreach_break_label, save_objc_foreach_continue_label;
6767 /* The following are only used when parsing an ObjC foreach statement. */
6768 tree object_expression;
6769 /* Silence the bogus uninitialized warning. */
6770 tree collection_expression = NULL;
6771 location_t loc = c_parser_peek_token (parser)->location;
6772 location_t for_loc = loc;
6773 bool is_foreach_statement = false;
6774 gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
6775 token_indent_info for_tinfo
6776 = get_token_indent_info (c_parser_peek_token (parser));
6777 c_parser_consume_token (parser);
6778 /* Open a compound statement in Objective-C as well, just in case this is
6779 as foreach expression. */
6780 block = c_begin_compound_stmt (flag_isoc99 || c_dialect_objc ());
6781 cond = error_mark_node;
6782 incr = error_mark_node;
6783 matching_parens parens;
6784 if (parens.require_open (parser))
6785 {
6786 /* Parse the initialization declaration or expression. */
6787 object_expression = error_mark_node;
6788 parser->objc_could_be_foreach_context = c_dialect_objc ();
6789 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6790 {
6791 parser->objc_could_be_foreach_context = false;
6792 c_parser_consume_token (parser);
6793 c_finish_expr_stmt (loc, NULL_TREE);
6794 }
6795 else if (c_parser_next_tokens_start_declaration (parser)
6796 || c_parser_nth_token_starts_std_attributes (parser, 1))
6797 {
6798 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
6799 &object_expression);
6800 parser->objc_could_be_foreach_context = false;
6801
6802 if (c_parser_next_token_is_keyword (parser, RID_IN))
6803 {
6804 c_parser_consume_token (parser);
6805 is_foreach_statement = true;
6806 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
6807 c_parser_error (parser, "multiple iterating variables in "
6808 "fast enumeration");
6809 }
6810 else
6811 check_for_loop_decls (for_loc, flag_isoc99);
6812 }
6813 else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
6814 {
6815 /* __extension__ can start a declaration, but is also an
6816 unary operator that can start an expression. Consume all
6817 but the last of a possible series of __extension__ to
6818 determine which. */
6819 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
6820 && (c_parser_peek_2nd_token (parser)->keyword
6821 == RID_EXTENSION))
6822 c_parser_consume_token (parser);
6823 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser))
6824 || c_parser_nth_token_starts_std_attributes (parser, 2))
6825 {
6826 int ext;
6827 ext = disable_extension_diagnostics ();
6828 c_parser_consume_token (parser);
6829 c_parser_declaration_or_fndef (parser, true, true, true, true,
6830 true, &object_expression);
6831 parser->objc_could_be_foreach_context = false;
6832
6833 restore_extension_diagnostics (ext);
6834 if (c_parser_next_token_is_keyword (parser, RID_IN))
6835 {
6836 c_parser_consume_token (parser);
6837 is_foreach_statement = true;
6838 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
6839 c_parser_error (parser, "multiple iterating variables in "
6840 "fast enumeration");
6841 }
6842 else
6843 check_for_loop_decls (for_loc, flag_isoc99);
6844 }
6845 else
6846 goto init_expr;
6847 }
6848 else
6849 {
6850 init_expr:
6851 {
6852 struct c_expr ce;
6853 tree init_expression;
6854 ce = c_parser_expression (parser);
6855 init_expression = ce.value;
6856 parser->objc_could_be_foreach_context = false;
6857 if (c_parser_next_token_is_keyword (parser, RID_IN))
6858 {
6859 c_parser_consume_token (parser);
6860 is_foreach_statement = true;
6861 if (! lvalue_p (init_expression))
6862 c_parser_error (parser, "invalid iterating variable in "
6863 "fast enumeration");
6864 object_expression
6865 = c_fully_fold (init_expression, false, NULL);
6866 }
6867 else
6868 {
6869 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
6870 init_expression = ce.value;
6871 c_finish_expr_stmt (loc, init_expression);
6872 c_parser_skip_until_found (parser, CPP_SEMICOLON,
6873 "expected %<;%>");
6874 }
6875 }
6876 }
6877 /* Parse the loop condition. In the case of a foreach
6878 statement, there is no loop condition. */
6879 gcc_assert (!parser->objc_could_be_foreach_context);
6880 if (!is_foreach_statement)
6881 {
6882 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6883 {
6884 if (ivdep)
6885 {
6886 c_parser_error (parser, "missing loop condition in loop "
6887 "with %<GCC ivdep%> pragma");
6888 cond = error_mark_node;
6889 }
6890 else if (unroll)
6891 {
6892 c_parser_error (parser, "missing loop condition in loop "
6893 "with %<GCC unroll%> pragma");
6894 cond = error_mark_node;
6895 }
6896 else
6897 {
6898 c_parser_consume_token (parser);
6899 cond = NULL_TREE;
6900 }
6901 }
6902 else
6903 {
6904 cond = c_parser_condition (parser);
6905 c_parser_skip_until_found (parser, CPP_SEMICOLON,
6906 "expected %<;%>");
6907 }
6908 if (ivdep && cond != error_mark_node)
6909 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6910 build_int_cst (integer_type_node,
6911 annot_expr_ivdep_kind),
6912 integer_zero_node);
6913 if (unroll && cond != error_mark_node)
6914 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6915 build_int_cst (integer_type_node,
6916 annot_expr_unroll_kind),
6917 build_int_cst (integer_type_node, unroll));
6918 }
6919 /* Parse the increment expression (the third expression in a
6920 for-statement). In the case of a foreach-statement, this is
6921 the expression that follows the 'in'. */
6922 loc = c_parser_peek_token (parser)->location;
6923 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
6924 {
6925 if (is_foreach_statement)
6926 {
6927 c_parser_error (parser,
6928 "missing collection in fast enumeration");
6929 collection_expression = error_mark_node;
6930 }
6931 else
6932 incr = c_process_expr_stmt (loc, NULL_TREE);
6933 }
6934 else
6935 {
6936 if (is_foreach_statement)
6937 collection_expression
6938 = c_fully_fold (c_parser_expression (parser).value, false, NULL);
6939 else
6940 {
6941 struct c_expr ce = c_parser_expression (parser);
6942 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
6943 incr = c_process_expr_stmt (loc, ce.value);
6944 }
6945 }
6946 parens.skip_until_found_close (parser);
6947 }
6948 save_in_statement = in_statement;
6949 if (is_foreach_statement)
6950 {
6951 in_statement = IN_OBJC_FOREACH;
6952 save_objc_foreach_break_label = objc_foreach_break_label;
6953 save_objc_foreach_continue_label = objc_foreach_continue_label;
6954 objc_foreach_break_label = create_artificial_label (loc);
6955 objc_foreach_continue_label = create_artificial_label (loc);
6956 }
6957 else
6958 in_statement = IN_ITERATION_STMT;
6959
6960 token_indent_info body_tinfo
6961 = get_token_indent_info (c_parser_peek_token (parser));
6962
6963 location_t loc_after_labels;
6964 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
6965 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6966
6967 if (is_foreach_statement)
6968 objc_finish_foreach_loop (for_loc, object_expression,
6969 collection_expression, body,
6970 objc_foreach_break_label,
6971 objc_foreach_continue_label);
6972 else
6973 add_stmt (build_stmt (for_loc, FOR_STMT, NULL_TREE, cond, incr,
6974 body, NULL_TREE));
6975 add_stmt (c_end_compound_stmt (for_loc, block,
6976 flag_isoc99 || c_dialect_objc ()));
6977 c_parser_maybe_reclassify_token (parser);
6978
6979 token_indent_info next_tinfo
6980 = get_token_indent_info (c_parser_peek_token (parser));
6981 warn_for_misleading_indentation (for_tinfo, body_tinfo, next_tinfo);
6982
6983 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
6984 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
6985 for_tinfo.location, RID_FOR);
6986
6987 in_statement = save_in_statement;
6988 if (is_foreach_statement)
6989 {
6990 objc_foreach_break_label = save_objc_foreach_break_label;
6991 objc_foreach_continue_label = save_objc_foreach_continue_label;
6992 }
6993 }
6994
6995 /* Parse an asm statement, a GNU extension. This is a full-blown asm
6996 statement with inputs, outputs, clobbers, and volatile, inline, and goto
6997 tags allowed.
6998
6999 asm-qualifier:
7000 volatile
7001 inline
7002 goto
7003
7004 asm-qualifier-list:
7005 asm-qualifier-list asm-qualifier
7006 asm-qualifier
7007
7008 asm-statement:
7009 asm asm-qualifier-list[opt] ( asm-argument ) ;
7010
7011 asm-argument:
7012 asm-string-literal
7013 asm-string-literal : asm-operands[opt]
7014 asm-string-literal : asm-operands[opt] : asm-operands[opt]
7015 asm-string-literal : asm-operands[opt] : asm-operands[opt] \
7016 : asm-clobbers[opt]
7017 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
7018 : asm-goto-operands
7019
7020 The form with asm-goto-operands is valid if and only if the
7021 asm-qualifier-list contains goto, and is the only allowed form in that case.
7022 Duplicate asm-qualifiers are not allowed.
7023
7024 The :: token is considered equivalent to two consecutive : tokens. */
7025
7026 static tree
7027 c_parser_asm_statement (c_parser *parser)
7028 {
7029 tree str, outputs, inputs, clobbers, labels, ret;
7030 bool simple;
7031 location_t asm_loc = c_parser_peek_token (parser)->location;
7032 int section, nsections;
7033
7034 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
7035 c_parser_consume_token (parser);
7036
7037 /* Handle the asm-qualifier-list. */
7038 location_t volatile_loc = UNKNOWN_LOCATION;
7039 location_t inline_loc = UNKNOWN_LOCATION;
7040 location_t goto_loc = UNKNOWN_LOCATION;
7041 for (;;)
7042 {
7043 c_token *token = c_parser_peek_token (parser);
7044 location_t loc = token->location;
7045 switch (token->keyword)
7046 {
7047 case RID_VOLATILE:
7048 if (volatile_loc)
7049 {
7050 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7051 inform (volatile_loc, "first seen here");
7052 }
7053 else
7054 volatile_loc = loc;
7055 c_parser_consume_token (parser);
7056 continue;
7057
7058 case RID_INLINE:
7059 if (inline_loc)
7060 {
7061 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7062 inform (inline_loc, "first seen here");
7063 }
7064 else
7065 inline_loc = loc;
7066 c_parser_consume_token (parser);
7067 continue;
7068
7069 case RID_GOTO:
7070 if (goto_loc)
7071 {
7072 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
7073 inform (goto_loc, "first seen here");
7074 }
7075 else
7076 goto_loc = loc;
7077 c_parser_consume_token (parser);
7078 continue;
7079
7080 case RID_CONST:
7081 case RID_RESTRICT:
7082 error_at (loc, "%qE is not a valid %<asm%> qualifier", token->value);
7083 c_parser_consume_token (parser);
7084 continue;
7085
7086 default:
7087 break;
7088 }
7089 break;
7090 }
7091
7092 bool is_volatile = (volatile_loc != UNKNOWN_LOCATION);
7093 bool is_inline = (inline_loc != UNKNOWN_LOCATION);
7094 bool is_goto = (goto_loc != UNKNOWN_LOCATION);
7095
7096 ret = NULL;
7097
7098 matching_parens parens;
7099 if (!parens.require_open (parser))
7100 goto error;
7101
7102 str = c_parser_asm_string_literal (parser);
7103 if (str == NULL_TREE)
7104 goto error_close_paren;
7105
7106 simple = true;
7107 outputs = NULL_TREE;
7108 inputs = NULL_TREE;
7109 clobbers = NULL_TREE;
7110 labels = NULL_TREE;
7111
7112 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
7113 goto done_asm;
7114
7115 /* Parse each colon-delimited section of operands. */
7116 nsections = 3 + is_goto;
7117 for (section = 0; section < nsections; ++section)
7118 {
7119 if (c_parser_next_token_is (parser, CPP_SCOPE))
7120 {
7121 ++section;
7122 if (section == nsections)
7123 {
7124 c_parser_error (parser, "expected %<)%>");
7125 goto error_close_paren;
7126 }
7127 c_parser_consume_token (parser);
7128 }
7129 else if (!c_parser_require (parser, CPP_COLON,
7130 is_goto
7131 ? G_("expected %<:%>")
7132 : G_("expected %<:%> or %<)%>"),
7133 UNKNOWN_LOCATION, is_goto))
7134 goto error_close_paren;
7135
7136 /* Once past any colon, we're no longer a simple asm. */
7137 simple = false;
7138
7139 if ((!c_parser_next_token_is (parser, CPP_COLON)
7140 && !c_parser_next_token_is (parser, CPP_SCOPE)
7141 && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
7142 || section == 3)
7143 switch (section)
7144 {
7145 case 0:
7146 outputs = c_parser_asm_operands (parser);
7147 break;
7148 case 1:
7149 inputs = c_parser_asm_operands (parser);
7150 break;
7151 case 2:
7152 clobbers = c_parser_asm_clobbers (parser);
7153 break;
7154 case 3:
7155 labels = c_parser_asm_goto_operands (parser);
7156 break;
7157 default:
7158 gcc_unreachable ();
7159 }
7160
7161 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
7162 goto done_asm;
7163 }
7164
7165 done_asm:
7166 if (!parens.require_close (parser))
7167 {
7168 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7169 goto error;
7170 }
7171
7172 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
7173 c_parser_skip_to_end_of_block_or_statement (parser);
7174
7175 ret = build_asm_stmt (is_volatile,
7176 build_asm_expr (asm_loc, str, outputs, inputs,
7177 clobbers, labels, simple, is_inline));
7178
7179 error:
7180 return ret;
7181
7182 error_close_paren:
7183 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7184 goto error;
7185 }
7186
7187 /* Parse asm operands, a GNU extension.
7188
7189 asm-operands:
7190 asm-operand
7191 asm-operands , asm-operand
7192
7193 asm-operand:
7194 asm-string-literal ( expression )
7195 [ identifier ] asm-string-literal ( expression )
7196 */
7197
7198 static tree
7199 c_parser_asm_operands (c_parser *parser)
7200 {
7201 tree list = NULL_TREE;
7202 while (true)
7203 {
7204 tree name, str;
7205 struct c_expr expr;
7206 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
7207 {
7208 c_parser_consume_token (parser);
7209 if (c_parser_next_token_is (parser, CPP_NAME))
7210 {
7211 tree id = c_parser_peek_token (parser)->value;
7212 c_parser_consume_token (parser);
7213 name = build_string (IDENTIFIER_LENGTH (id),
7214 IDENTIFIER_POINTER (id));
7215 }
7216 else
7217 {
7218 c_parser_error (parser, "expected identifier");
7219 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
7220 return NULL_TREE;
7221 }
7222 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
7223 "expected %<]%>");
7224 }
7225 else
7226 name = NULL_TREE;
7227 str = c_parser_asm_string_literal (parser);
7228 if (str == NULL_TREE)
7229 return NULL_TREE;
7230 matching_parens parens;
7231 if (!parens.require_open (parser))
7232 return NULL_TREE;
7233 expr = c_parser_expression (parser);
7234 mark_exp_read (expr.value);
7235 if (!parens.require_close (parser))
7236 {
7237 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7238 return NULL_TREE;
7239 }
7240 list = chainon (list, build_tree_list (build_tree_list (name, str),
7241 expr.value));
7242 if (c_parser_next_token_is (parser, CPP_COMMA))
7243 c_parser_consume_token (parser);
7244 else
7245 break;
7246 }
7247 return list;
7248 }
7249
7250 /* Parse asm clobbers, a GNU extension.
7251
7252 asm-clobbers:
7253 asm-string-literal
7254 asm-clobbers , asm-string-literal
7255 */
7256
7257 static tree
7258 c_parser_asm_clobbers (c_parser *parser)
7259 {
7260 tree list = NULL_TREE;
7261 while (true)
7262 {
7263 tree str = c_parser_asm_string_literal (parser);
7264 if (str)
7265 list = tree_cons (NULL_TREE, str, list);
7266 else
7267 return NULL_TREE;
7268 if (c_parser_next_token_is (parser, CPP_COMMA))
7269 c_parser_consume_token (parser);
7270 else
7271 break;
7272 }
7273 return list;
7274 }
7275
7276 /* Parse asm goto labels, a GNU extension.
7277
7278 asm-goto-operands:
7279 identifier
7280 asm-goto-operands , identifier
7281 */
7282
7283 static tree
7284 c_parser_asm_goto_operands (c_parser *parser)
7285 {
7286 tree list = NULL_TREE;
7287 while (true)
7288 {
7289 tree name, label;
7290
7291 if (c_parser_next_token_is (parser, CPP_NAME))
7292 {
7293 c_token *tok = c_parser_peek_token (parser);
7294 name = tok->value;
7295 label = lookup_label_for_goto (tok->location, name);
7296 c_parser_consume_token (parser);
7297 TREE_USED (label) = 1;
7298 }
7299 else
7300 {
7301 c_parser_error (parser, "expected identifier");
7302 return NULL_TREE;
7303 }
7304
7305 name = build_string (IDENTIFIER_LENGTH (name),
7306 IDENTIFIER_POINTER (name));
7307 list = tree_cons (name, label, list);
7308 if (c_parser_next_token_is (parser, CPP_COMMA))
7309 c_parser_consume_token (parser);
7310 else
7311 return nreverse (list);
7312 }
7313 }
7314
7315 /* Parse a possibly concatenated sequence of string literals.
7316 TRANSLATE says whether to translate them to the execution character
7317 set; WIDE_OK says whether any kind of prefixed string literal is
7318 permitted in this context. This code is based on that in
7319 lex_string. */
7320
7321 struct c_expr
7322 c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok)
7323 {
7324 struct c_expr ret;
7325 size_t count;
7326 struct obstack str_ob;
7327 struct obstack loc_ob;
7328 cpp_string str, istr, *strs;
7329 c_token *tok;
7330 location_t loc, last_tok_loc;
7331 enum cpp_ttype type;
7332 tree value, string_tree;
7333
7334 tok = c_parser_peek_token (parser);
7335 loc = tok->location;
7336 last_tok_loc = linemap_resolve_location (line_table, loc,
7337 LRK_MACRO_DEFINITION_LOCATION,
7338 NULL);
7339 type = tok->type;
7340 switch (type)
7341 {
7342 case CPP_STRING:
7343 case CPP_WSTRING:
7344 case CPP_STRING16:
7345 case CPP_STRING32:
7346 case CPP_UTF8STRING:
7347 string_tree = tok->value;
7348 break;
7349
7350 default:
7351 c_parser_error (parser, "expected string literal");
7352 ret.set_error ();
7353 ret.value = NULL_TREE;
7354 ret.original_code = ERROR_MARK;
7355 ret.original_type = NULL_TREE;
7356 return ret;
7357 }
7358
7359 /* Try to avoid the overhead of creating and destroying an obstack
7360 for the common case of just one string. */
7361 switch (c_parser_peek_2nd_token (parser)->type)
7362 {
7363 default:
7364 c_parser_consume_token (parser);
7365 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
7366 str.len = TREE_STRING_LENGTH (string_tree);
7367 count = 1;
7368 strs = &str;
7369 break;
7370
7371 case CPP_STRING:
7372 case CPP_WSTRING:
7373 case CPP_STRING16:
7374 case CPP_STRING32:
7375 case CPP_UTF8STRING:
7376 gcc_obstack_init (&str_ob);
7377 gcc_obstack_init (&loc_ob);
7378 count = 0;
7379 do
7380 {
7381 c_parser_consume_token (parser);
7382 count++;
7383 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
7384 str.len = TREE_STRING_LENGTH (string_tree);
7385 if (type != tok->type)
7386 {
7387 if (type == CPP_STRING)
7388 type = tok->type;
7389 else if (tok->type != CPP_STRING)
7390 error ("unsupported non-standard concatenation "
7391 "of string literals");
7392 }
7393 obstack_grow (&str_ob, &str, sizeof (cpp_string));
7394 obstack_grow (&loc_ob, &last_tok_loc, sizeof (location_t));
7395 tok = c_parser_peek_token (parser);
7396 string_tree = tok->value;
7397 last_tok_loc
7398 = linemap_resolve_location (line_table, tok->location,
7399 LRK_MACRO_DEFINITION_LOCATION, NULL);
7400 }
7401 while (tok->type == CPP_STRING
7402 || tok->type == CPP_WSTRING
7403 || tok->type == CPP_STRING16
7404 || tok->type == CPP_STRING32
7405 || tok->type == CPP_UTF8STRING);
7406 strs = (cpp_string *) obstack_finish (&str_ob);
7407 }
7408
7409 if (count > 1 && !in_system_header_at (input_location))
7410 warning (OPT_Wtraditional,
7411 "traditional C rejects string constant concatenation");
7412
7413 if ((type == CPP_STRING || wide_ok)
7414 && ((translate
7415 ? cpp_interpret_string : cpp_interpret_string_notranslate)
7416 (parse_in, strs, count, &istr, type)))
7417 {
7418 value = build_string (istr.len, (const char *) istr.text);
7419 free (CONST_CAST (unsigned char *, istr.text));
7420 if (count > 1)
7421 {
7422 location_t *locs = (location_t *) obstack_finish (&loc_ob);
7423 gcc_assert (g_string_concat_db);
7424 g_string_concat_db->record_string_concatenation (count, locs);
7425 }
7426 }
7427 else
7428 {
7429 if (type != CPP_STRING && !wide_ok)
7430 {
7431 error_at (loc, "a wide string is invalid in this context");
7432 type = CPP_STRING;
7433 }
7434 /* Callers cannot generally handle error_mark_node in this
7435 context, so return the empty string instead. An error has
7436 been issued, either above or from cpp_interpret_string. */
7437 switch (type)
7438 {
7439 default:
7440 case CPP_STRING:
7441 case CPP_UTF8STRING:
7442 value = build_string (1, "");
7443 break;
7444 case CPP_STRING16:
7445 value = build_string (TYPE_PRECISION (char16_type_node)
7446 / TYPE_PRECISION (char_type_node),
7447 "\0"); /* char16_t is 16 bits */
7448 break;
7449 case CPP_STRING32:
7450 value = build_string (TYPE_PRECISION (char32_type_node)
7451 / TYPE_PRECISION (char_type_node),
7452 "\0\0\0"); /* char32_t is 32 bits */
7453 break;
7454 case CPP_WSTRING:
7455 value = build_string (TYPE_PRECISION (wchar_type_node)
7456 / TYPE_PRECISION (char_type_node),
7457 "\0\0\0"); /* widest supported wchar_t
7458 is 32 bits */
7459 break;
7460 }
7461 }
7462
7463 switch (type)
7464 {
7465 default:
7466 case CPP_STRING:
7467 case CPP_UTF8STRING:
7468 TREE_TYPE (value) = char_array_type_node;
7469 break;
7470 case CPP_STRING16:
7471 TREE_TYPE (value) = char16_array_type_node;
7472 break;
7473 case CPP_STRING32:
7474 TREE_TYPE (value) = char32_array_type_node;
7475 break;
7476 case CPP_WSTRING:
7477 TREE_TYPE (value) = wchar_array_type_node;
7478 }
7479 value = fix_string_type (value);
7480
7481 if (count > 1)
7482 {
7483 obstack_free (&str_ob, 0);
7484 obstack_free (&loc_ob, 0);
7485 }
7486
7487 ret.value = value;
7488 ret.original_code = STRING_CST;
7489 ret.original_type = NULL_TREE;
7490 set_c_expr_source_range (&ret, get_range_from_loc (line_table, loc));
7491 parser->seen_string_literal = true;
7492 return ret;
7493 }
7494
7495 /* Parse an expression other than a compound expression; that is, an
7496 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If
7497 AFTER is not NULL then it is an Objective-C message expression which
7498 is the primary-expression starting the expression as an initializer.
7499
7500 assignment-expression:
7501 conditional-expression
7502 unary-expression assignment-operator assignment-expression
7503
7504 assignment-operator: one of
7505 = *= /= %= += -= <<= >>= &= ^= |=
7506
7507 In GNU C we accept any conditional expression on the LHS and
7508 diagnose the invalid lvalue rather than producing a syntax
7509 error. */
7510
7511 static struct c_expr
7512 c_parser_expr_no_commas (c_parser *parser, struct c_expr *after,
7513 tree omp_atomic_lhs)
7514 {
7515 struct c_expr lhs, rhs, ret;
7516 enum tree_code code;
7517 location_t op_location, exp_location;
7518 bool save_in_omp_for = c_in_omp_for;
7519 c_in_omp_for = false;
7520 gcc_assert (!after || c_dialect_objc ());
7521 lhs = c_parser_conditional_expression (parser, after, omp_atomic_lhs);
7522 op_location = c_parser_peek_token (parser)->location;
7523 switch (c_parser_peek_token (parser)->type)
7524 {
7525 case CPP_EQ:
7526 code = NOP_EXPR;
7527 break;
7528 case CPP_MULT_EQ:
7529 code = MULT_EXPR;
7530 break;
7531 case CPP_DIV_EQ:
7532 code = TRUNC_DIV_EXPR;
7533 break;
7534 case CPP_MOD_EQ:
7535 code = TRUNC_MOD_EXPR;
7536 break;
7537 case CPP_PLUS_EQ:
7538 code = PLUS_EXPR;
7539 break;
7540 case CPP_MINUS_EQ:
7541 code = MINUS_EXPR;
7542 break;
7543 case CPP_LSHIFT_EQ:
7544 code = LSHIFT_EXPR;
7545 break;
7546 case CPP_RSHIFT_EQ:
7547 code = RSHIFT_EXPR;
7548 break;
7549 case CPP_AND_EQ:
7550 code = BIT_AND_EXPR;
7551 break;
7552 case CPP_XOR_EQ:
7553 code = BIT_XOR_EXPR;
7554 break;
7555 case CPP_OR_EQ:
7556 code = BIT_IOR_EXPR;
7557 break;
7558 default:
7559 c_in_omp_for = save_in_omp_for;
7560 return lhs;
7561 }
7562 c_parser_consume_token (parser);
7563 exp_location = c_parser_peek_token (parser)->location;
7564 rhs = c_parser_expr_no_commas (parser, NULL);
7565 rhs = convert_lvalue_to_rvalue (exp_location, rhs, true, true);
7566
7567 ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
7568 code, exp_location, rhs.value,
7569 rhs.original_type);
7570 set_c_expr_source_range (&ret, lhs.get_start (), rhs.get_finish ());
7571 if (code == NOP_EXPR)
7572 ret.original_code = MODIFY_EXPR;
7573 else
7574 {
7575 suppress_warning (ret.value, OPT_Wparentheses);
7576 ret.original_code = ERROR_MARK;
7577 }
7578 ret.original_type = NULL;
7579 c_in_omp_for = save_in_omp_for;
7580 return ret;
7581 }
7582
7583 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If
7584 AFTER is not NULL then it is an Objective-C message expression which is
7585 the primary-expression starting the expression as an initializer.
7586
7587 conditional-expression:
7588 logical-OR-expression
7589 logical-OR-expression ? expression : conditional-expression
7590
7591 GNU extensions:
7592
7593 conditional-expression:
7594 logical-OR-expression ? : conditional-expression
7595 */
7596
7597 static struct c_expr
7598 c_parser_conditional_expression (c_parser *parser, struct c_expr *after,
7599 tree omp_atomic_lhs)
7600 {
7601 struct c_expr cond, exp1, exp2, ret;
7602 location_t start, cond_loc, colon_loc;
7603
7604 gcc_assert (!after || c_dialect_objc ());
7605
7606 cond = c_parser_binary_expression (parser, after, omp_atomic_lhs);
7607
7608 if (c_parser_next_token_is_not (parser, CPP_QUERY))
7609 return cond;
7610 if (cond.value != error_mark_node)
7611 start = cond.get_start ();
7612 else
7613 start = UNKNOWN_LOCATION;
7614 cond_loc = c_parser_peek_token (parser)->location;
7615 cond = convert_lvalue_to_rvalue (cond_loc, cond, true, true);
7616 c_parser_consume_token (parser);
7617 if (c_parser_next_token_is (parser, CPP_COLON))
7618 {
7619 tree eptype = NULL_TREE;
7620
7621 location_t middle_loc = c_parser_peek_token (parser)->location;
7622 pedwarn (middle_loc, OPT_Wpedantic,
7623 "ISO C forbids omitting the middle term of a %<?:%> expression");
7624 if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR)
7625 {
7626 eptype = TREE_TYPE (cond.value);
7627 cond.value = TREE_OPERAND (cond.value, 0);
7628 }
7629 tree e = cond.value;
7630 while (TREE_CODE (e) == COMPOUND_EXPR)
7631 e = TREE_OPERAND (e, 1);
7632 warn_for_omitted_condop (middle_loc, e);
7633 /* Make sure first operand is calculated only once. */
7634 exp1.value = save_expr (default_conversion (cond.value));
7635 if (eptype)
7636 exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value);
7637 exp1.original_type = NULL;
7638 exp1.src_range = cond.src_range;
7639 cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value);
7640 c_inhibit_evaluation_warnings += cond.value == truthvalue_true_node;
7641 }
7642 else
7643 {
7644 cond.value
7645 = c_objc_common_truthvalue_conversion
7646 (cond_loc, default_conversion (cond.value));
7647 c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node;
7648 exp1 = c_parser_expression_conv (parser);
7649 mark_exp_read (exp1.value);
7650 c_inhibit_evaluation_warnings +=
7651 ((cond.value == truthvalue_true_node)
7652 - (cond.value == truthvalue_false_node));
7653 }
7654
7655 colon_loc = c_parser_peek_token (parser)->location;
7656 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
7657 {
7658 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
7659 ret.set_error ();
7660 ret.original_code = ERROR_MARK;
7661 ret.original_type = NULL;
7662 return ret;
7663 }
7664 {
7665 location_t exp2_loc = c_parser_peek_token (parser)->location;
7666 exp2 = c_parser_conditional_expression (parser, NULL, NULL_TREE);
7667 exp2 = convert_lvalue_to_rvalue (exp2_loc, exp2, true, true);
7668 }
7669 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
7670 location_t loc1 = make_location (exp1.get_start (), exp1.src_range);
7671 location_t loc2 = make_location (exp2.get_start (), exp2.src_range);
7672 if (__builtin_expect (omp_atomic_lhs != NULL, 0)
7673 && (TREE_CODE (cond.value) == GT_EXPR
7674 || TREE_CODE (cond.value) == LT_EXPR
7675 || TREE_CODE (cond.value) == EQ_EXPR)
7676 && c_tree_equal (exp2.value, omp_atomic_lhs)
7677 && (c_tree_equal (TREE_OPERAND (cond.value, 0), omp_atomic_lhs)
7678 || c_tree_equal (TREE_OPERAND (cond.value, 1), omp_atomic_lhs)))
7679 ret.value = build3_loc (colon_loc, COND_EXPR, TREE_TYPE (omp_atomic_lhs),
7680 cond.value, exp1.value, exp2.value);
7681 else
7682 ret.value
7683 = build_conditional_expr (colon_loc, cond.value,
7684 cond.original_code == C_MAYBE_CONST_EXPR,
7685 exp1.value, exp1.original_type, loc1,
7686 exp2.value, exp2.original_type, loc2);
7687 ret.original_code = ERROR_MARK;
7688 if (exp1.value == error_mark_node || exp2.value == error_mark_node)
7689 ret.original_type = NULL;
7690 else
7691 {
7692 tree t1, t2;
7693
7694 /* If both sides are enum type, the default conversion will have
7695 made the type of the result be an integer type. We want to
7696 remember the enum types we started with. */
7697 t1 = exp1.original_type ? exp1.original_type : TREE_TYPE (exp1.value);
7698 t2 = exp2.original_type ? exp2.original_type : TREE_TYPE (exp2.value);
7699 ret.original_type = ((t1 != error_mark_node
7700 && t2 != error_mark_node
7701 && (TYPE_MAIN_VARIANT (t1)
7702 == TYPE_MAIN_VARIANT (t2)))
7703 ? t1
7704 : NULL);
7705 }
7706 set_c_expr_source_range (&ret, start, exp2.get_finish ());
7707 return ret;
7708 }
7709
7710 /* Parse a binary expression; that is, a logical-OR-expression (C90
7711 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not
7712 NULL then it is an Objective-C message expression which is the
7713 primary-expression starting the expression as an initializer.
7714
7715 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
7716 when it should be the unfolded lhs. In a valid OpenMP source,
7717 one of the operands of the toplevel binary expression must be equal
7718 to it. In that case, just return a build2 created binary operation
7719 rather than result of parser_build_binary_op.
7720
7721 multiplicative-expression:
7722 cast-expression
7723 multiplicative-expression * cast-expression
7724 multiplicative-expression / cast-expression
7725 multiplicative-expression % cast-expression
7726
7727 additive-expression:
7728 multiplicative-expression
7729 additive-expression + multiplicative-expression
7730 additive-expression - multiplicative-expression
7731
7732 shift-expression:
7733 additive-expression
7734 shift-expression << additive-expression
7735 shift-expression >> additive-expression
7736
7737 relational-expression:
7738 shift-expression
7739 relational-expression < shift-expression
7740 relational-expression > shift-expression
7741 relational-expression <= shift-expression
7742 relational-expression >= shift-expression
7743
7744 equality-expression:
7745 relational-expression
7746 equality-expression == relational-expression
7747 equality-expression != relational-expression
7748
7749 AND-expression:
7750 equality-expression
7751 AND-expression & equality-expression
7752
7753 exclusive-OR-expression:
7754 AND-expression
7755 exclusive-OR-expression ^ AND-expression
7756
7757 inclusive-OR-expression:
7758 exclusive-OR-expression
7759 inclusive-OR-expression | exclusive-OR-expression
7760
7761 logical-AND-expression:
7762 inclusive-OR-expression
7763 logical-AND-expression && inclusive-OR-expression
7764
7765 logical-OR-expression:
7766 logical-AND-expression
7767 logical-OR-expression || logical-AND-expression
7768 */
7769
7770 static struct c_expr
7771 c_parser_binary_expression (c_parser *parser, struct c_expr *after,
7772 tree omp_atomic_lhs)
7773 {
7774 /* A binary expression is parsed using operator-precedence parsing,
7775 with the operands being cast expressions. All the binary
7776 operators are left-associative. Thus a binary expression is of
7777 form:
7778
7779 E0 op1 E1 op2 E2 ...
7780
7781 which we represent on a stack. On the stack, the precedence
7782 levels are strictly increasing. When a new operator is
7783 encountered of higher precedence than that at the top of the
7784 stack, it is pushed; its LHS is the top expression, and its RHS
7785 is everything parsed until it is popped. When a new operator is
7786 encountered with precedence less than or equal to that at the top
7787 of the stack, triples E[i-1] op[i] E[i] are popped and replaced
7788 by the result of the operation until the operator at the top of
7789 the stack has lower precedence than the new operator or there is
7790 only one element on the stack; then the top expression is the LHS
7791 of the new operator. In the case of logical AND and OR
7792 expressions, we also need to adjust c_inhibit_evaluation_warnings
7793 as appropriate when the operators are pushed and popped. */
7794
7795 struct {
7796 /* The expression at this stack level. */
7797 struct c_expr expr;
7798 /* The precedence of the operator on its left, PREC_NONE at the
7799 bottom of the stack. */
7800 enum c_parser_prec prec;
7801 /* The operation on its left. */
7802 enum tree_code op;
7803 /* The source location of this operation. */
7804 location_t loc;
7805 /* The sizeof argument if expr.original_code == {PAREN_,}SIZEOF_EXPR. */
7806 tree sizeof_arg;
7807 } stack[NUM_PRECS];
7808 int sp;
7809 /* Location of the binary operator. */
7810 location_t binary_loc = UNKNOWN_LOCATION; /* Quiet warning. */
7811 #define POP \
7812 do { \
7813 switch (stack[sp].op) \
7814 { \
7815 case TRUTH_ANDIF_EXPR: \
7816 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7817 == truthvalue_false_node); \
7818 break; \
7819 case TRUTH_ORIF_EXPR: \
7820 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7821 == truthvalue_true_node); \
7822 break; \
7823 case TRUNC_DIV_EXPR: \
7824 if ((stack[sp - 1].expr.original_code == SIZEOF_EXPR \
7825 || stack[sp - 1].expr.original_code == PAREN_SIZEOF_EXPR) \
7826 && (stack[sp].expr.original_code == SIZEOF_EXPR \
7827 || stack[sp].expr.original_code == PAREN_SIZEOF_EXPR)) \
7828 { \
7829 tree type0 = stack[sp - 1].sizeof_arg; \
7830 tree type1 = stack[sp].sizeof_arg; \
7831 tree first_arg = type0; \
7832 if (!TYPE_P (type0)) \
7833 type0 = TREE_TYPE (type0); \
7834 if (!TYPE_P (type1)) \
7835 type1 = TREE_TYPE (type1); \
7836 if (POINTER_TYPE_P (type0) \
7837 && comptypes (TREE_TYPE (type0), type1) \
7838 && !(TREE_CODE (first_arg) == PARM_DECL \
7839 && C_ARRAY_PARAMETER (first_arg) \
7840 && warn_sizeof_array_argument)) \
7841 { \
7842 auto_diagnostic_group d; \
7843 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
7844 "division %<sizeof (%T) / sizeof (%T)%> " \
7845 "does not compute the number of array " \
7846 "elements", \
7847 type0, type1)) \
7848 if (DECL_P (first_arg)) \
7849 inform (DECL_SOURCE_LOCATION (first_arg), \
7850 "first %<sizeof%> operand was declared here"); \
7851 } \
7852 else if (TREE_CODE (type0) == ARRAY_TYPE \
7853 && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0))) \
7854 && stack[sp].expr.original_code != PAREN_SIZEOF_EXPR) \
7855 maybe_warn_sizeof_array_div (stack[sp].loc, first_arg, type0, \
7856 stack[sp].sizeof_arg, type1); \
7857 } \
7858 break; \
7859 default: \
7860 break; \
7861 } \
7862 stack[sp - 1].expr \
7863 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \
7864 stack[sp - 1].expr, true, true); \
7865 stack[sp].expr \
7866 = convert_lvalue_to_rvalue (stack[sp].loc, \
7867 stack[sp].expr, true, true); \
7868 if (__builtin_expect (omp_atomic_lhs != NULL_TREE, 0) && sp == 1 \
7869 && ((c_parser_next_token_is (parser, CPP_SEMICOLON) \
7870 && ((1 << stack[sp].prec) \
7871 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) \
7872 | (1 << PREC_BITAND) | (1 << PREC_SHIFT) \
7873 | (1 << PREC_ADD) | (1 << PREC_MULT) \
7874 | (1 << PREC_EQ)))) \
7875 || ((c_parser_next_token_is (parser, CPP_QUERY) \
7876 || (omp_atomic_lhs == void_list_node \
7877 && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))) \
7878 && (stack[sp].prec == PREC_REL || stack[sp].prec == PREC_EQ)))\
7879 && stack[sp].op != TRUNC_MOD_EXPR \
7880 && stack[sp].op != GE_EXPR \
7881 && stack[sp].op != LE_EXPR \
7882 && stack[sp].op != NE_EXPR \
7883 && stack[0].expr.value != error_mark_node \
7884 && stack[1].expr.value != error_mark_node \
7885 && (omp_atomic_lhs == void_list_node \
7886 || c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
7887 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs) \
7888 || (stack[sp].op == EQ_EXPR \
7889 && c_parser_peek_2nd_token (parser)->keyword == RID_IF))) \
7890 { \
7891 tree t = make_node (stack[1].op); \
7892 TREE_TYPE (t) = TREE_TYPE (stack[0].expr.value); \
7893 TREE_OPERAND (t, 0) = stack[0].expr.value; \
7894 TREE_OPERAND (t, 1) = stack[1].expr.value; \
7895 stack[0].expr.value = t; \
7896 } \
7897 else \
7898 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
7899 stack[sp].op, \
7900 stack[sp - 1].expr, \
7901 stack[sp].expr); \
7902 sp--; \
7903 } while (0)
7904 gcc_assert (!after || c_dialect_objc ());
7905 stack[0].loc = c_parser_peek_token (parser)->location;
7906 stack[0].expr = c_parser_cast_expression (parser, after);
7907 stack[0].prec = PREC_NONE;
7908 stack[0].sizeof_arg = c_last_sizeof_arg;
7909 sp = 0;
7910 while (true)
7911 {
7912 enum c_parser_prec oprec;
7913 enum tree_code ocode;
7914 source_range src_range;
7915 if (parser->error)
7916 goto out;
7917 switch (c_parser_peek_token (parser)->type)
7918 {
7919 case CPP_MULT:
7920 oprec = PREC_MULT;
7921 ocode = MULT_EXPR;
7922 break;
7923 case CPP_DIV:
7924 oprec = PREC_MULT;
7925 ocode = TRUNC_DIV_EXPR;
7926 break;
7927 case CPP_MOD:
7928 oprec = PREC_MULT;
7929 ocode = TRUNC_MOD_EXPR;
7930 break;
7931 case CPP_PLUS:
7932 oprec = PREC_ADD;
7933 ocode = PLUS_EXPR;
7934 break;
7935 case CPP_MINUS:
7936 oprec = PREC_ADD;
7937 ocode = MINUS_EXPR;
7938 break;
7939 case CPP_LSHIFT:
7940 oprec = PREC_SHIFT;
7941 ocode = LSHIFT_EXPR;
7942 break;
7943 case CPP_RSHIFT:
7944 oprec = PREC_SHIFT;
7945 ocode = RSHIFT_EXPR;
7946 break;
7947 case CPP_LESS:
7948 oprec = PREC_REL;
7949 ocode = LT_EXPR;
7950 break;
7951 case CPP_GREATER:
7952 oprec = PREC_REL;
7953 ocode = GT_EXPR;
7954 break;
7955 case CPP_LESS_EQ:
7956 oprec = PREC_REL;
7957 ocode = LE_EXPR;
7958 break;
7959 case CPP_GREATER_EQ:
7960 oprec = PREC_REL;
7961 ocode = GE_EXPR;
7962 break;
7963 case CPP_EQ_EQ:
7964 oprec = PREC_EQ;
7965 ocode = EQ_EXPR;
7966 break;
7967 case CPP_NOT_EQ:
7968 oprec = PREC_EQ;
7969 ocode = NE_EXPR;
7970 break;
7971 case CPP_AND:
7972 oprec = PREC_BITAND;
7973 ocode = BIT_AND_EXPR;
7974 break;
7975 case CPP_XOR:
7976 oprec = PREC_BITXOR;
7977 ocode = BIT_XOR_EXPR;
7978 break;
7979 case CPP_OR:
7980 oprec = PREC_BITOR;
7981 ocode = BIT_IOR_EXPR;
7982 break;
7983 case CPP_AND_AND:
7984 oprec = PREC_LOGAND;
7985 ocode = TRUTH_ANDIF_EXPR;
7986 break;
7987 case CPP_OR_OR:
7988 oprec = PREC_LOGOR;
7989 ocode = TRUTH_ORIF_EXPR;
7990 break;
7991 default:
7992 /* Not a binary operator, so end of the binary
7993 expression. */
7994 goto out;
7995 }
7996 binary_loc = c_parser_peek_token (parser)->location;
7997 while (oprec <= stack[sp].prec)
7998 POP;
7999 c_parser_consume_token (parser);
8000 switch (ocode)
8001 {
8002 case TRUTH_ANDIF_EXPR:
8003 src_range = stack[sp].expr.src_range;
8004 stack[sp].expr
8005 = convert_lvalue_to_rvalue (stack[sp].loc,
8006 stack[sp].expr, true, true);
8007 stack[sp].expr.value = c_objc_common_truthvalue_conversion
8008 (stack[sp].loc, default_conversion (stack[sp].expr.value));
8009 c_inhibit_evaluation_warnings += (stack[sp].expr.value
8010 == truthvalue_false_node);
8011 set_c_expr_source_range (&stack[sp].expr, src_range);
8012 break;
8013 case TRUTH_ORIF_EXPR:
8014 src_range = stack[sp].expr.src_range;
8015 stack[sp].expr
8016 = convert_lvalue_to_rvalue (stack[sp].loc,
8017 stack[sp].expr, true, true);
8018 stack[sp].expr.value = c_objc_common_truthvalue_conversion
8019 (stack[sp].loc, default_conversion (stack[sp].expr.value));
8020 c_inhibit_evaluation_warnings += (stack[sp].expr.value
8021 == truthvalue_true_node);
8022 set_c_expr_source_range (&stack[sp].expr, src_range);
8023 break;
8024 default:
8025 break;
8026 }
8027 sp++;
8028 stack[sp].loc = binary_loc;
8029 stack[sp].expr = c_parser_cast_expression (parser, NULL);
8030 stack[sp].prec = oprec;
8031 stack[sp].op = ocode;
8032 stack[sp].sizeof_arg = c_last_sizeof_arg;
8033 }
8034 out:
8035 while (sp > 0)
8036 POP;
8037 return stack[0].expr;
8038 #undef POP
8039 }
8040
8041 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER
8042 is not NULL then it is an Objective-C message expression which is the
8043 primary-expression starting the expression as an initializer.
8044
8045 cast-expression:
8046 unary-expression
8047 ( type-name ) unary-expression
8048 */
8049
8050 static struct c_expr
8051 c_parser_cast_expression (c_parser *parser, struct c_expr *after)
8052 {
8053 location_t cast_loc = c_parser_peek_token (parser)->location;
8054 gcc_assert (!after || c_dialect_objc ());
8055 if (after)
8056 return c_parser_postfix_expression_after_primary (parser,
8057 cast_loc, *after);
8058 /* If the expression begins with a parenthesized type name, it may
8059 be either a cast or a compound literal; we need to see whether
8060 the next character is '{' to tell the difference. If not, it is
8061 an unary expression. Full detection of unknown typenames here
8062 would require a 3-token lookahead. */
8063 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8064 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8065 {
8066 struct c_type_name *type_name;
8067 struct c_expr ret;
8068 struct c_expr expr;
8069 matching_parens parens;
8070 parens.consume_open (parser);
8071 type_name = c_parser_type_name (parser, true);
8072 parens.skip_until_found_close (parser);
8073 if (type_name == NULL)
8074 {
8075 ret.set_error ();
8076 ret.original_code = ERROR_MARK;
8077 ret.original_type = NULL;
8078 return ret;
8079 }
8080
8081 /* Save casted types in the function's used types hash table. */
8082 used_types_insert (type_name->specs->type);
8083
8084 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8085 return c_parser_postfix_expression_after_paren_type (parser, type_name,
8086 cast_loc);
8087 if (type_name->specs->alignas_p)
8088 error_at (type_name->specs->locations[cdw_alignas],
8089 "alignment specified for type name in cast");
8090 {
8091 location_t expr_loc = c_parser_peek_token (parser)->location;
8092 expr = c_parser_cast_expression (parser, NULL);
8093 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
8094 }
8095 ret.value = c_cast_expr (cast_loc, type_name, expr.value);
8096 if (ret.value && expr.value)
8097 set_c_expr_source_range (&ret, cast_loc, expr.get_finish ());
8098 ret.original_code = ERROR_MARK;
8099 ret.original_type = NULL;
8100 return ret;
8101 }
8102 else
8103 return c_parser_unary_expression (parser);
8104 }
8105
8106 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
8107
8108 unary-expression:
8109 postfix-expression
8110 ++ unary-expression
8111 -- unary-expression
8112 unary-operator cast-expression
8113 sizeof unary-expression
8114 sizeof ( type-name )
8115
8116 unary-operator: one of
8117 & * + - ~ !
8118
8119 GNU extensions:
8120
8121 unary-expression:
8122 __alignof__ unary-expression
8123 __alignof__ ( type-name )
8124 && identifier
8125
8126 (C11 permits _Alignof with type names only.)
8127
8128 unary-operator: one of
8129 __extension__ __real__ __imag__
8130
8131 Transactional Memory:
8132
8133 unary-expression:
8134 transaction-expression
8135
8136 In addition, the GNU syntax treats ++ and -- as unary operators, so
8137 they may be applied to cast expressions with errors for non-lvalues
8138 given later. */
8139
8140 static struct c_expr
8141 c_parser_unary_expression (c_parser *parser)
8142 {
8143 int ext;
8144 struct c_expr ret, op;
8145 location_t op_loc = c_parser_peek_token (parser)->location;
8146 location_t exp_loc;
8147 location_t finish;
8148 ret.original_code = ERROR_MARK;
8149 ret.original_type = NULL;
8150 switch (c_parser_peek_token (parser)->type)
8151 {
8152 case CPP_PLUS_PLUS:
8153 c_parser_consume_token (parser);
8154 exp_loc = c_parser_peek_token (parser)->location;
8155 op = c_parser_cast_expression (parser, NULL);
8156
8157 op = default_function_array_read_conversion (exp_loc, op);
8158 return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
8159 case CPP_MINUS_MINUS:
8160 c_parser_consume_token (parser);
8161 exp_loc = c_parser_peek_token (parser)->location;
8162 op = c_parser_cast_expression (parser, NULL);
8163
8164 op = default_function_array_read_conversion (exp_loc, op);
8165 return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
8166 case CPP_AND:
8167 c_parser_consume_token (parser);
8168 op = c_parser_cast_expression (parser, NULL);
8169 mark_exp_read (op.value);
8170 return parser_build_unary_op (op_loc, ADDR_EXPR, op);
8171 case CPP_MULT:
8172 {
8173 c_parser_consume_token (parser);
8174 exp_loc = c_parser_peek_token (parser)->location;
8175 op = c_parser_cast_expression (parser, NULL);
8176 finish = op.get_finish ();
8177 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8178 location_t combined_loc = make_location (op_loc, op_loc, finish);
8179 ret.value = build_indirect_ref (combined_loc, op.value, RO_UNARY_STAR);
8180 ret.src_range.m_start = op_loc;
8181 ret.src_range.m_finish = finish;
8182 return ret;
8183 }
8184 case CPP_PLUS:
8185 if (!c_dialect_objc () && !in_system_header_at (input_location))
8186 warning_at (op_loc,
8187 OPT_Wtraditional,
8188 "traditional C rejects the unary plus operator");
8189 c_parser_consume_token (parser);
8190 exp_loc = c_parser_peek_token (parser)->location;
8191 op = c_parser_cast_expression (parser, NULL);
8192 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8193 return parser_build_unary_op (op_loc, CONVERT_EXPR, op);
8194 case CPP_MINUS:
8195 c_parser_consume_token (parser);
8196 exp_loc = c_parser_peek_token (parser)->location;
8197 op = c_parser_cast_expression (parser, NULL);
8198 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8199 return parser_build_unary_op (op_loc, NEGATE_EXPR, op);
8200 case CPP_COMPL:
8201 c_parser_consume_token (parser);
8202 exp_loc = c_parser_peek_token (parser)->location;
8203 op = c_parser_cast_expression (parser, NULL);
8204 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8205 return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
8206 case CPP_NOT:
8207 c_parser_consume_token (parser);
8208 exp_loc = c_parser_peek_token (parser)->location;
8209 op = c_parser_cast_expression (parser, NULL);
8210 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
8211 return parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op);
8212 case CPP_AND_AND:
8213 /* Refer to the address of a label as a pointer. */
8214 c_parser_consume_token (parser);
8215 if (c_parser_next_token_is (parser, CPP_NAME))
8216 {
8217 ret.value = finish_label_address_expr
8218 (c_parser_peek_token (parser)->value, op_loc);
8219 set_c_expr_source_range (&ret, op_loc,
8220 c_parser_peek_token (parser)->get_finish ());
8221 c_parser_consume_token (parser);
8222 }
8223 else
8224 {
8225 c_parser_error (parser, "expected identifier");
8226 ret.set_error ();
8227 }
8228 return ret;
8229 case CPP_KEYWORD:
8230 switch (c_parser_peek_token (parser)->keyword)
8231 {
8232 case RID_SIZEOF:
8233 return c_parser_sizeof_expression (parser);
8234 case RID_ALIGNOF:
8235 return c_parser_alignof_expression (parser);
8236 case RID_BUILTIN_HAS_ATTRIBUTE:
8237 return c_parser_has_attribute_expression (parser);
8238 case RID_EXTENSION:
8239 c_parser_consume_token (parser);
8240 ext = disable_extension_diagnostics ();
8241 ret = c_parser_cast_expression (parser, NULL);
8242 restore_extension_diagnostics (ext);
8243 return ret;
8244 case RID_REALPART:
8245 c_parser_consume_token (parser);
8246 exp_loc = c_parser_peek_token (parser)->location;
8247 op = c_parser_cast_expression (parser, NULL);
8248 op = default_function_array_conversion (exp_loc, op);
8249 return parser_build_unary_op (op_loc, REALPART_EXPR, op);
8250 case RID_IMAGPART:
8251 c_parser_consume_token (parser);
8252 exp_loc = c_parser_peek_token (parser)->location;
8253 op = c_parser_cast_expression (parser, NULL);
8254 op = default_function_array_conversion (exp_loc, op);
8255 return parser_build_unary_op (op_loc, IMAGPART_EXPR, op);
8256 case RID_TRANSACTION_ATOMIC:
8257 case RID_TRANSACTION_RELAXED:
8258 return c_parser_transaction_expression (parser,
8259 c_parser_peek_token (parser)->keyword);
8260 default:
8261 return c_parser_postfix_expression (parser);
8262 }
8263 default:
8264 return c_parser_postfix_expression (parser);
8265 }
8266 }
8267
8268 /* Parse a sizeof expression. */
8269
8270 static struct c_expr
8271 c_parser_sizeof_expression (c_parser *parser)
8272 {
8273 struct c_expr expr;
8274 struct c_expr result;
8275 location_t expr_loc;
8276 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF));
8277
8278 location_t start;
8279 location_t finish = UNKNOWN_LOCATION;
8280
8281 start = c_parser_peek_token (parser)->location;
8282
8283 c_parser_consume_token (parser);
8284 c_inhibit_evaluation_warnings++;
8285 in_sizeof++;
8286 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8287 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8288 {
8289 /* Either sizeof ( type-name ) or sizeof unary-expression
8290 starting with a compound literal. */
8291 struct c_type_name *type_name;
8292 matching_parens parens;
8293 parens.consume_open (parser);
8294 expr_loc = c_parser_peek_token (parser)->location;
8295 type_name = c_parser_type_name (parser, true);
8296 parens.skip_until_found_close (parser);
8297 finish = parser->tokens_buf[0].location;
8298 if (type_name == NULL)
8299 {
8300 struct c_expr ret;
8301 c_inhibit_evaluation_warnings--;
8302 in_sizeof--;
8303 ret.set_error ();
8304 ret.original_code = ERROR_MARK;
8305 ret.original_type = NULL;
8306 return ret;
8307 }
8308 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8309 {
8310 expr = c_parser_postfix_expression_after_paren_type (parser,
8311 type_name,
8312 expr_loc);
8313 finish = expr.get_finish ();
8314 goto sizeof_expr;
8315 }
8316 /* sizeof ( type-name ). */
8317 if (type_name->specs->alignas_p)
8318 error_at (type_name->specs->locations[cdw_alignas],
8319 "alignment specified for type name in %<sizeof%>");
8320 c_inhibit_evaluation_warnings--;
8321 in_sizeof--;
8322 result = c_expr_sizeof_type (expr_loc, type_name);
8323 }
8324 else
8325 {
8326 expr_loc = c_parser_peek_token (parser)->location;
8327 expr = c_parser_unary_expression (parser);
8328 finish = expr.get_finish ();
8329 sizeof_expr:
8330 c_inhibit_evaluation_warnings--;
8331 in_sizeof--;
8332 mark_exp_read (expr.value);
8333 if (TREE_CODE (expr.value) == COMPONENT_REF
8334 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
8335 error_at (expr_loc, "%<sizeof%> applied to a bit-field");
8336 result = c_expr_sizeof_expr (expr_loc, expr);
8337 }
8338 if (finish == UNKNOWN_LOCATION)
8339 finish = start;
8340 set_c_expr_source_range (&result, start, finish);
8341 return result;
8342 }
8343
8344 /* Parse an alignof expression. */
8345
8346 static struct c_expr
8347 c_parser_alignof_expression (c_parser *parser)
8348 {
8349 struct c_expr expr;
8350 location_t start_loc = c_parser_peek_token (parser)->location;
8351 location_t end_loc;
8352 tree alignof_spelling = c_parser_peek_token (parser)->value;
8353 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF));
8354 bool is_c11_alignof = strcmp (IDENTIFIER_POINTER (alignof_spelling),
8355 "_Alignof") == 0;
8356 /* A diagnostic is not required for the use of this identifier in
8357 the implementation namespace; only diagnose it for the C11
8358 spelling because of existing code using the other spellings. */
8359 if (is_c11_alignof)
8360 {
8361 if (flag_isoc99)
8362 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C99 does not support %qE",
8363 alignof_spelling);
8364 else
8365 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C90 does not support %qE",
8366 alignof_spelling);
8367 }
8368 c_parser_consume_token (parser);
8369 c_inhibit_evaluation_warnings++;
8370 in_alignof++;
8371 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
8372 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
8373 {
8374 /* Either __alignof__ ( type-name ) or __alignof__
8375 unary-expression starting with a compound literal. */
8376 location_t loc;
8377 struct c_type_name *type_name;
8378 struct c_expr ret;
8379 matching_parens parens;
8380 parens.consume_open (parser);
8381 loc = c_parser_peek_token (parser)->location;
8382 type_name = c_parser_type_name (parser, true);
8383 end_loc = c_parser_peek_token (parser)->location;
8384 parens.skip_until_found_close (parser);
8385 if (type_name == NULL)
8386 {
8387 struct c_expr ret;
8388 c_inhibit_evaluation_warnings--;
8389 in_alignof--;
8390 ret.set_error ();
8391 ret.original_code = ERROR_MARK;
8392 ret.original_type = NULL;
8393 return ret;
8394 }
8395 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
8396 {
8397 expr = c_parser_postfix_expression_after_paren_type (parser,
8398 type_name,
8399 loc);
8400 goto alignof_expr;
8401 }
8402 /* alignof ( type-name ). */
8403 if (type_name->specs->alignas_p)
8404 error_at (type_name->specs->locations[cdw_alignas],
8405 "alignment specified for type name in %qE",
8406 alignof_spelling);
8407 c_inhibit_evaluation_warnings--;
8408 in_alignof--;
8409 ret.value = c_sizeof_or_alignof_type (loc, groktypename (type_name,
8410 NULL, NULL),
8411 false, is_c11_alignof, 1);
8412 ret.original_code = ERROR_MARK;
8413 ret.original_type = NULL;
8414 set_c_expr_source_range (&ret, start_loc, end_loc);
8415 return ret;
8416 }
8417 else
8418 {
8419 struct c_expr ret;
8420 expr = c_parser_unary_expression (parser);
8421 end_loc = expr.src_range.m_finish;
8422 alignof_expr:
8423 mark_exp_read (expr.value);
8424 c_inhibit_evaluation_warnings--;
8425 in_alignof--;
8426 if (is_c11_alignof)
8427 pedwarn (start_loc,
8428 OPT_Wpedantic, "ISO C does not allow %<%E (expression)%>",
8429 alignof_spelling);
8430 ret.value = c_alignof_expr (start_loc, expr.value);
8431 ret.original_code = ERROR_MARK;
8432 ret.original_type = NULL;
8433 set_c_expr_source_range (&ret, start_loc, end_loc);
8434 return ret;
8435 }
8436 }
8437
8438 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
8439 expression. */
8440
8441 static struct c_expr
8442 c_parser_has_attribute_expression (c_parser *parser)
8443 {
8444 gcc_assert (c_parser_next_token_is_keyword (parser,
8445 RID_BUILTIN_HAS_ATTRIBUTE));
8446 location_t start = c_parser_peek_token (parser)->location;
8447 c_parser_consume_token (parser);
8448
8449 c_inhibit_evaluation_warnings++;
8450
8451 matching_parens parens;
8452 if (!parens.require_open (parser))
8453 {
8454 c_inhibit_evaluation_warnings--;
8455 in_typeof--;
8456
8457 struct c_expr result;
8458 result.set_error ();
8459 result.original_code = ERROR_MARK;
8460 result.original_type = NULL;
8461 return result;
8462 }
8463
8464 /* Treat the type argument the same way as in typeof for the purposes
8465 of warnings. FIXME: Generalize this so the warning refers to
8466 __builtin_has_attribute rather than typeof. */
8467 in_typeof++;
8468
8469 /* The first operand: one of DECL, EXPR, or TYPE. */
8470 tree oper = NULL_TREE;
8471 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
8472 {
8473 struct c_type_name *tname = c_parser_type_name (parser);
8474 in_typeof--;
8475 if (tname)
8476 {
8477 oper = groktypename (tname, NULL, NULL);
8478 pop_maybe_used (variably_modified_type_p (oper, NULL_TREE));
8479 }
8480 }
8481 else
8482 {
8483 struct c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
8484 c_inhibit_evaluation_warnings--;
8485 in_typeof--;
8486 if (cexpr.value != error_mark_node)
8487 {
8488 mark_exp_read (cexpr.value);
8489 oper = cexpr.value;
8490 tree etype = TREE_TYPE (oper);
8491 bool was_vm = variably_modified_type_p (etype, NULL_TREE);
8492 /* This is returned with the type so that when the type is
8493 evaluated, this can be evaluated. */
8494 if (was_vm)
8495 oper = c_fully_fold (oper, false, NULL);
8496 pop_maybe_used (was_vm);
8497 }
8498 }
8499
8500 struct c_expr result;
8501 result.original_code = ERROR_MARK;
8502 result.original_type = NULL;
8503
8504 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8505 {
8506 /* Consume the closing parenthesis if that's the next token
8507 in the likely case the built-in was invoked with fewer
8508 than two arguments. */
8509 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8510 c_parser_consume_token (parser);
8511 c_inhibit_evaluation_warnings--;
8512 result.set_error ();
8513 return result;
8514 }
8515
8516 bool save_translate_strings_p = parser->translate_strings_p;
8517
8518 location_t atloc = c_parser_peek_token (parser)->location;
8519 /* Parse a single attribute. Require no leading comma and do not
8520 allow empty attributes. */
8521 tree attr = c_parser_gnu_attribute (parser, NULL_TREE, false, false);
8522
8523 parser->translate_strings_p = save_translate_strings_p;
8524
8525 location_t finish = c_parser_peek_token (parser)->location;
8526 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8527 c_parser_consume_token (parser);
8528 else
8529 {
8530 c_parser_error (parser, "expected identifier");
8531 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8532
8533 result.set_error ();
8534 return result;
8535 }
8536
8537 if (!attr)
8538 {
8539 error_at (atloc, "expected identifier");
8540 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
8541 "expected %<)%>");
8542 result.set_error ();
8543 return result;
8544 }
8545
8546 result.original_code = INTEGER_CST;
8547 result.original_type = boolean_type_node;
8548
8549 if (has_attribute (atloc, oper, attr, default_conversion))
8550 result.value = boolean_true_node;
8551 else
8552 result.value = boolean_false_node;
8553
8554 set_c_expr_source_range (&result, start, finish);
8555 return result;
8556 }
8557
8558 /* Helper function to read arguments of builtins which are interfaces
8559 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
8560 others. The name of the builtin is passed using BNAME parameter.
8561 Function returns true if there were no errors while parsing and
8562 stores the arguments in CEXPR_LIST. If it returns true,
8563 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
8564 parenthesis. */
8565 static bool
8566 c_parser_get_builtin_args (c_parser *parser, const char *bname,
8567 vec<c_expr_t, va_gc> **ret_cexpr_list,
8568 bool choose_expr_p,
8569 location_t *out_close_paren_loc)
8570 {
8571 location_t loc = c_parser_peek_token (parser)->location;
8572 vec<c_expr_t, va_gc> *cexpr_list;
8573 c_expr_t expr;
8574 bool saved_force_folding_builtin_constant_p;
8575
8576 *ret_cexpr_list = NULL;
8577 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
8578 {
8579 error_at (loc, "cannot take address of %qs", bname);
8580 return false;
8581 }
8582
8583 c_parser_consume_token (parser);
8584
8585 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
8586 {
8587 *out_close_paren_loc = c_parser_peek_token (parser)->location;
8588 c_parser_consume_token (parser);
8589 return true;
8590 }
8591
8592 saved_force_folding_builtin_constant_p
8593 = force_folding_builtin_constant_p;
8594 force_folding_builtin_constant_p |= choose_expr_p;
8595 expr = c_parser_expr_no_commas (parser, NULL);
8596 force_folding_builtin_constant_p
8597 = saved_force_folding_builtin_constant_p;
8598 vec_alloc (cexpr_list, 1);
8599 vec_safe_push (cexpr_list, expr);
8600 while (c_parser_next_token_is (parser, CPP_COMMA))
8601 {
8602 c_parser_consume_token (parser);
8603 expr = c_parser_expr_no_commas (parser, NULL);
8604 vec_safe_push (cexpr_list, expr);
8605 }
8606
8607 *out_close_paren_loc = c_parser_peek_token (parser)->location;
8608 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
8609 return false;
8610
8611 *ret_cexpr_list = cexpr_list;
8612 return true;
8613 }
8614
8615 /* This represents a single generic-association. */
8616
8617 struct c_generic_association
8618 {
8619 /* The location of the starting token of the type. */
8620 location_t type_location;
8621 /* The association's type, or NULL_TREE for 'default'. */
8622 tree type;
8623 /* The association's expression. */
8624 struct c_expr expression;
8625 };
8626
8627 /* Parse a generic-selection. (C11 6.5.1.1).
8628
8629 generic-selection:
8630 _Generic ( assignment-expression , generic-assoc-list )
8631
8632 generic-assoc-list:
8633 generic-association
8634 generic-assoc-list , generic-association
8635
8636 generic-association:
8637 type-name : assignment-expression
8638 default : assignment-expression
8639 */
8640
8641 static struct c_expr
8642 c_parser_generic_selection (c_parser *parser)
8643 {
8644 struct c_expr selector, error_expr;
8645 tree selector_type;
8646 struct c_generic_association matched_assoc;
8647 int match_found = -1;
8648 location_t generic_loc, selector_loc;
8649
8650 error_expr.original_code = ERROR_MARK;
8651 error_expr.original_type = NULL;
8652 error_expr.set_error ();
8653 matched_assoc.type_location = UNKNOWN_LOCATION;
8654 matched_assoc.type = NULL_TREE;
8655 matched_assoc.expression = error_expr;
8656
8657 gcc_assert (c_parser_next_token_is_keyword (parser, RID_GENERIC));
8658 generic_loc = c_parser_peek_token (parser)->location;
8659 c_parser_consume_token (parser);
8660 if (flag_isoc99)
8661 pedwarn_c99 (generic_loc, OPT_Wpedantic,
8662 "ISO C99 does not support %<_Generic%>");
8663 else
8664 pedwarn_c99 (generic_loc, OPT_Wpedantic,
8665 "ISO C90 does not support %<_Generic%>");
8666
8667 matching_parens parens;
8668 if (!parens.require_open (parser))
8669 return error_expr;
8670
8671 c_inhibit_evaluation_warnings++;
8672 selector_loc = c_parser_peek_token (parser)->location;
8673 selector = c_parser_expr_no_commas (parser, NULL);
8674 selector = default_function_array_conversion (selector_loc, selector);
8675 c_inhibit_evaluation_warnings--;
8676
8677 if (selector.value == error_mark_node)
8678 {
8679 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8680 return selector;
8681 }
8682 mark_exp_read (selector.value);
8683 selector_type = TREE_TYPE (selector.value);
8684 /* In ISO C terms, rvalues (including the controlling expression of
8685 _Generic) do not have qualified types. */
8686 if (TREE_CODE (selector_type) != ARRAY_TYPE)
8687 selector_type = TYPE_MAIN_VARIANT (selector_type);
8688 /* In ISO C terms, _Noreturn is not part of the type of expressions
8689 such as &abort, but in GCC it is represented internally as a type
8690 qualifier. */
8691 if (FUNCTION_POINTER_TYPE_P (selector_type)
8692 && TYPE_QUALS (TREE_TYPE (selector_type)) != TYPE_UNQUALIFIED)
8693 selector_type
8694 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type)));
8695
8696 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8697 {
8698 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8699 return error_expr;
8700 }
8701
8702 auto_vec<c_generic_association> associations;
8703 while (1)
8704 {
8705 struct c_generic_association assoc, *iter;
8706 unsigned int ix;
8707 c_token *token = c_parser_peek_token (parser);
8708
8709 assoc.type_location = token->location;
8710 if (token->type == CPP_KEYWORD && token->keyword == RID_DEFAULT)
8711 {
8712 c_parser_consume_token (parser);
8713 assoc.type = NULL_TREE;
8714 }
8715 else
8716 {
8717 struct c_type_name *type_name;
8718
8719 type_name = c_parser_type_name (parser);
8720 if (type_name == NULL)
8721 {
8722 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8723 return error_expr;
8724 }
8725 assoc.type = groktypename (type_name, NULL, NULL);
8726 if (assoc.type == error_mark_node)
8727 {
8728 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8729 return error_expr;
8730 }
8731
8732 if (TREE_CODE (assoc.type) == FUNCTION_TYPE)
8733 error_at (assoc.type_location,
8734 "%<_Generic%> association has function type");
8735 else if (!COMPLETE_TYPE_P (assoc.type))
8736 error_at (assoc.type_location,
8737 "%<_Generic%> association has incomplete type");
8738
8739 if (variably_modified_type_p (assoc.type, NULL_TREE))
8740 error_at (assoc.type_location,
8741 "%<_Generic%> association has "
8742 "variable length type");
8743 }
8744
8745 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
8746 {
8747 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8748 return error_expr;
8749 }
8750
8751 assoc.expression = c_parser_expr_no_commas (parser, NULL);
8752 if (assoc.expression.value == error_mark_node)
8753 {
8754 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8755 return error_expr;
8756 }
8757
8758 for (ix = 0; associations.iterate (ix, &iter); ++ix)
8759 {
8760 if (assoc.type == NULL_TREE)
8761 {
8762 if (iter->type == NULL_TREE)
8763 {
8764 error_at (assoc.type_location,
8765 "duplicate %<default%> case in %<_Generic%>");
8766 inform (iter->type_location, "original %<default%> is here");
8767 }
8768 }
8769 else if (iter->type != NULL_TREE)
8770 {
8771 if (comptypes (assoc.type, iter->type))
8772 {
8773 error_at (assoc.type_location,
8774 "%<_Generic%> specifies two compatible types");
8775 inform (iter->type_location, "compatible type is here");
8776 }
8777 }
8778 }
8779
8780 if (assoc.type == NULL_TREE)
8781 {
8782 if (match_found < 0)
8783 {
8784 matched_assoc = assoc;
8785 match_found = associations.length ();
8786 }
8787 }
8788 else if (comptypes (assoc.type, selector_type))
8789 {
8790 if (match_found < 0 || matched_assoc.type == NULL_TREE)
8791 {
8792 matched_assoc = assoc;
8793 match_found = associations.length ();
8794 }
8795 else
8796 {
8797 error_at (assoc.type_location,
8798 "%<_Generic%> selector matches multiple associations");
8799 inform (matched_assoc.type_location,
8800 "other match is here");
8801 }
8802 }
8803
8804 associations.safe_push (assoc);
8805
8806 if (c_parser_peek_token (parser)->type != CPP_COMMA)
8807 break;
8808 c_parser_consume_token (parser);
8809 }
8810
8811 unsigned int ix;
8812 struct c_generic_association *iter;
8813 FOR_EACH_VEC_ELT (associations, ix, iter)
8814 if (ix != (unsigned) match_found)
8815 mark_exp_read (iter->expression.value);
8816
8817 if (!parens.require_close (parser))
8818 {
8819 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8820 return error_expr;
8821 }
8822
8823 if (match_found < 0)
8824 {
8825 error_at (selector_loc, "%<_Generic%> selector of type %qT is not "
8826 "compatible with any association",
8827 selector_type);
8828 return error_expr;
8829 }
8830
8831 return matched_assoc.expression;
8832 }
8833
8834 /* Check the validity of a function pointer argument *EXPR (argument
8835 position POS) to __builtin_tgmath. Return the number of function
8836 arguments if possibly valid; return 0 having reported an error if
8837 not valid. */
8838
8839 static unsigned int
8840 check_tgmath_function (c_expr *expr, unsigned int pos)
8841 {
8842 tree type = TREE_TYPE (expr->value);
8843 if (!FUNCTION_POINTER_TYPE_P (type))
8844 {
8845 error_at (expr->get_location (),
8846 "argument %u of %<__builtin_tgmath%> is not a function pointer",
8847 pos);
8848 return 0;
8849 }
8850 type = TREE_TYPE (type);
8851 if (!prototype_p (type))
8852 {
8853 error_at (expr->get_location (),
8854 "argument %u of %<__builtin_tgmath%> is unprototyped", pos);
8855 return 0;
8856 }
8857 if (stdarg_p (type))
8858 {
8859 error_at (expr->get_location (),
8860 "argument %u of %<__builtin_tgmath%> has variable arguments",
8861 pos);
8862 return 0;
8863 }
8864 unsigned int nargs = 0;
8865 function_args_iterator iter;
8866 tree t;
8867 FOREACH_FUNCTION_ARGS (type, t, iter)
8868 {
8869 if (t == void_type_node)
8870 break;
8871 nargs++;
8872 }
8873 if (nargs == 0)
8874 {
8875 error_at (expr->get_location (),
8876 "argument %u of %<__builtin_tgmath%> has no arguments", pos);
8877 return 0;
8878 }
8879 return nargs;
8880 }
8881
8882 /* Ways in which a parameter or return value of a type-generic macro
8883 may vary between the different functions the macro may call. */
8884 enum tgmath_parm_kind
8885 {
8886 tgmath_fixed, tgmath_real, tgmath_complex
8887 };
8888
8889 /* Helper function for c_parser_postfix_expression. Parse predefined
8890 identifiers. */
8891
8892 static struct c_expr
8893 c_parser_predefined_identifier (c_parser *parser)
8894 {
8895 location_t loc = c_parser_peek_token (parser)->location;
8896 switch (c_parser_peek_token (parser)->keyword)
8897 {
8898 case RID_FUNCTION_NAME:
8899 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
8900 "identifier", "__FUNCTION__");
8901 break;
8902 case RID_PRETTY_FUNCTION_NAME:
8903 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
8904 "identifier", "__PRETTY_FUNCTION__");
8905 break;
8906 case RID_C99_FUNCTION_NAME:
8907 pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not support "
8908 "%<__func__%> predefined identifier");
8909 break;
8910 default:
8911 gcc_unreachable ();
8912 }
8913
8914 struct c_expr expr;
8915 expr.original_code = ERROR_MARK;
8916 expr.original_type = NULL;
8917 expr.value = fname_decl (loc, c_parser_peek_token (parser)->keyword,
8918 c_parser_peek_token (parser)->value);
8919 set_c_expr_source_range (&expr, loc, loc);
8920 c_parser_consume_token (parser);
8921 return expr;
8922 }
8923
8924 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
8925 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to
8926 call c_parser_postfix_expression_after_paren_type on encountering them.
8927
8928 postfix-expression:
8929 primary-expression
8930 postfix-expression [ expression ]
8931 postfix-expression ( argument-expression-list[opt] )
8932 postfix-expression . identifier
8933 postfix-expression -> identifier
8934 postfix-expression ++
8935 postfix-expression --
8936 ( type-name ) { initializer-list }
8937 ( type-name ) { initializer-list , }
8938
8939 argument-expression-list:
8940 argument-expression
8941 argument-expression-list , argument-expression
8942
8943 primary-expression:
8944 identifier
8945 constant
8946 string-literal
8947 ( expression )
8948 generic-selection
8949
8950 GNU extensions:
8951
8952 primary-expression:
8953 __func__
8954 (treated as a keyword in GNU C)
8955 __FUNCTION__
8956 __PRETTY_FUNCTION__
8957 ( compound-statement )
8958 __builtin_va_arg ( assignment-expression , type-name )
8959 __builtin_offsetof ( type-name , offsetof-member-designator )
8960 __builtin_choose_expr ( assignment-expression ,
8961 assignment-expression ,
8962 assignment-expression )
8963 __builtin_types_compatible_p ( type-name , type-name )
8964 __builtin_tgmath ( expr-list )
8965 __builtin_complex ( assignment-expression , assignment-expression )
8966 __builtin_shuffle ( assignment-expression , assignment-expression )
8967 __builtin_shuffle ( assignment-expression ,
8968 assignment-expression ,
8969 assignment-expression, )
8970 __builtin_convertvector ( assignment-expression , type-name )
8971 __builtin_assoc_barrier ( assignment-expression )
8972
8973 offsetof-member-designator:
8974 identifier
8975 offsetof-member-designator . identifier
8976 offsetof-member-designator [ expression ]
8977
8978 Objective-C:
8979
8980 primary-expression:
8981 [ objc-receiver objc-message-args ]
8982 @selector ( objc-selector-arg )
8983 @protocol ( identifier )
8984 @encode ( type-name )
8985 objc-string-literal
8986 Classname . identifier
8987 */
8988
8989 static struct c_expr
8990 c_parser_postfix_expression (c_parser *parser)
8991 {
8992 struct c_expr expr, e1;
8993 struct c_type_name *t1, *t2;
8994 location_t loc = c_parser_peek_token (parser)->location;
8995 source_range tok_range = c_parser_peek_token (parser)->get_range ();
8996 expr.original_code = ERROR_MARK;
8997 expr.original_type = NULL;
8998 switch (c_parser_peek_token (parser)->type)
8999 {
9000 case CPP_NUMBER:
9001 expr.value = c_parser_peek_token (parser)->value;
9002 set_c_expr_source_range (&expr, tok_range);
9003 loc = c_parser_peek_token (parser)->location;
9004 c_parser_consume_token (parser);
9005 if (TREE_CODE (expr.value) == FIXED_CST
9006 && !targetm.fixed_point_supported_p ())
9007 {
9008 error_at (loc, "fixed-point types not supported for this target");
9009 expr.set_error ();
9010 }
9011 break;
9012 case CPP_CHAR:
9013 case CPP_CHAR16:
9014 case CPP_CHAR32:
9015 case CPP_UTF8CHAR:
9016 case CPP_WCHAR:
9017 expr.value = c_parser_peek_token (parser)->value;
9018 /* For the purpose of warning when a pointer is compared with
9019 a zero character constant. */
9020 expr.original_type = char_type_node;
9021 set_c_expr_source_range (&expr, tok_range);
9022 c_parser_consume_token (parser);
9023 break;
9024 case CPP_STRING:
9025 case CPP_STRING16:
9026 case CPP_STRING32:
9027 case CPP_WSTRING:
9028 case CPP_UTF8STRING:
9029 expr = c_parser_string_literal (parser, parser->translate_strings_p,
9030 true);
9031 break;
9032 case CPP_OBJC_STRING:
9033 gcc_assert (c_dialect_objc ());
9034 expr.value
9035 = objc_build_string_object (c_parser_peek_token (parser)->value);
9036 set_c_expr_source_range (&expr, tok_range);
9037 c_parser_consume_token (parser);
9038 break;
9039 case CPP_NAME:
9040 switch (c_parser_peek_token (parser)->id_kind)
9041 {
9042 case C_ID_ID:
9043 {
9044 tree id = c_parser_peek_token (parser)->value;
9045 c_parser_consume_token (parser);
9046 expr.value = build_external_ref (loc, id,
9047 (c_parser_peek_token (parser)->type
9048 == CPP_OPEN_PAREN),
9049 &expr.original_type);
9050 set_c_expr_source_range (&expr, tok_range);
9051 break;
9052 }
9053 case C_ID_CLASSNAME:
9054 {
9055 /* Here we parse the Objective-C 2.0 Class.name dot
9056 syntax. */
9057 tree class_name = c_parser_peek_token (parser)->value;
9058 tree component;
9059 c_parser_consume_token (parser);
9060 gcc_assert (c_dialect_objc ());
9061 if (!c_parser_require (parser, CPP_DOT, "expected %<.%>"))
9062 {
9063 expr.set_error ();
9064 break;
9065 }
9066 if (c_parser_next_token_is_not (parser, CPP_NAME))
9067 {
9068 c_parser_error (parser, "expected identifier");
9069 expr.set_error ();
9070 break;
9071 }
9072 c_token *component_tok = c_parser_peek_token (parser);
9073 component = component_tok->value;
9074 location_t end_loc = component_tok->get_finish ();
9075 c_parser_consume_token (parser);
9076 expr.value = objc_build_class_component_ref (class_name,
9077 component);
9078 set_c_expr_source_range (&expr, loc, end_loc);
9079 break;
9080 }
9081 default:
9082 c_parser_error (parser, "expected expression");
9083 expr.set_error ();
9084 break;
9085 }
9086 break;
9087 case CPP_OPEN_PAREN:
9088 /* A parenthesized expression, statement expression or compound
9089 literal. */
9090 if (c_parser_peek_2nd_token (parser)->type == CPP_OPEN_BRACE)
9091 {
9092 /* A statement expression. */
9093 tree stmt;
9094 location_t brace_loc;
9095 c_parser_consume_token (parser);
9096 brace_loc = c_parser_peek_token (parser)->location;
9097 c_parser_consume_token (parser);
9098 /* If we've not yet started the current function's statement list,
9099 or we're in the parameter scope of an old-style function
9100 declaration, statement expressions are not allowed. */
9101 if (!building_stmt_list_p () || old_style_parameter_scope ())
9102 {
9103 error_at (loc, "braced-group within expression allowed "
9104 "only inside a function");
9105 parser->error = true;
9106 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
9107 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9108 expr.set_error ();
9109 break;
9110 }
9111 stmt = c_begin_stmt_expr ();
9112 c_parser_compound_statement_nostart (parser);
9113 location_t close_loc = c_parser_peek_token (parser)->location;
9114 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9115 "expected %<)%>");
9116 pedwarn (loc, OPT_Wpedantic,
9117 "ISO C forbids braced-groups within expressions");
9118 expr.value = c_finish_stmt_expr (brace_loc, stmt);
9119 set_c_expr_source_range (&expr, loc, close_loc);
9120 mark_exp_read (expr.value);
9121 }
9122 else
9123 {
9124 /* A parenthesized expression. */
9125 location_t loc_open_paren = c_parser_peek_token (parser)->location;
9126 c_parser_consume_token (parser);
9127 expr = c_parser_expression (parser);
9128 if (TREE_CODE (expr.value) == MODIFY_EXPR)
9129 suppress_warning (expr.value, OPT_Wparentheses);
9130 if (expr.original_code != C_MAYBE_CONST_EXPR
9131 && expr.original_code != SIZEOF_EXPR)
9132 expr.original_code = ERROR_MARK;
9133 /* Remember that we saw ( ) around the sizeof. */
9134 if (expr.original_code == SIZEOF_EXPR)
9135 expr.original_code = PAREN_SIZEOF_EXPR;
9136 /* Don't change EXPR.ORIGINAL_TYPE. */
9137 location_t loc_close_paren = c_parser_peek_token (parser)->location;
9138 set_c_expr_source_range (&expr, loc_open_paren, loc_close_paren);
9139 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9140 "expected %<)%>", loc_open_paren);
9141 }
9142 break;
9143 case CPP_KEYWORD:
9144 switch (c_parser_peek_token (parser)->keyword)
9145 {
9146 case RID_FUNCTION_NAME:
9147 case RID_PRETTY_FUNCTION_NAME:
9148 case RID_C99_FUNCTION_NAME:
9149 expr = c_parser_predefined_identifier (parser);
9150 break;
9151 case RID_VA_ARG:
9152 {
9153 location_t start_loc = loc;
9154 c_parser_consume_token (parser);
9155 matching_parens parens;
9156 if (!parens.require_open (parser))
9157 {
9158 expr.set_error ();
9159 break;
9160 }
9161 e1 = c_parser_expr_no_commas (parser, NULL);
9162 mark_exp_read (e1.value);
9163 e1.value = c_fully_fold (e1.value, false, NULL);
9164 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9165 {
9166 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9167 expr.set_error ();
9168 break;
9169 }
9170 loc = c_parser_peek_token (parser)->location;
9171 t1 = c_parser_type_name (parser);
9172 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
9173 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9174 "expected %<)%>");
9175 if (t1 == NULL)
9176 {
9177 expr.set_error ();
9178 }
9179 else
9180 {
9181 tree type_expr = NULL_TREE;
9182 expr.value = c_build_va_arg (start_loc, e1.value, loc,
9183 groktypename (t1, &type_expr, NULL));
9184 if (type_expr)
9185 {
9186 expr.value = build2 (C_MAYBE_CONST_EXPR,
9187 TREE_TYPE (expr.value), type_expr,
9188 expr.value);
9189 C_MAYBE_CONST_EXPR_NON_CONST (expr.value) = true;
9190 }
9191 set_c_expr_source_range (&expr, start_loc, end_loc);
9192 }
9193 }
9194 break;
9195 case RID_OFFSETOF:
9196 {
9197 c_parser_consume_token (parser);
9198 matching_parens parens;
9199 if (!parens.require_open (parser))
9200 {
9201 expr.set_error ();
9202 break;
9203 }
9204 t1 = c_parser_type_name (parser);
9205 if (t1 == NULL)
9206 parser->error = true;
9207 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9208 gcc_assert (parser->error);
9209 if (parser->error)
9210 {
9211 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9212 expr.set_error ();
9213 break;
9214 }
9215 tree type = groktypename (t1, NULL, NULL);
9216 tree offsetof_ref;
9217 if (type == error_mark_node)
9218 offsetof_ref = error_mark_node;
9219 else
9220 {
9221 offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
9222 SET_EXPR_LOCATION (offsetof_ref, loc);
9223 }
9224 /* Parse the second argument to __builtin_offsetof. We
9225 must have one identifier, and beyond that we want to
9226 accept sub structure and sub array references. */
9227 if (c_parser_next_token_is (parser, CPP_NAME))
9228 {
9229 c_token *comp_tok = c_parser_peek_token (parser);
9230 offsetof_ref = build_component_ref
9231 (loc, offsetof_ref, comp_tok->value, comp_tok->location);
9232 c_parser_consume_token (parser);
9233 while (c_parser_next_token_is (parser, CPP_DOT)
9234 || c_parser_next_token_is (parser,
9235 CPP_OPEN_SQUARE)
9236 || c_parser_next_token_is (parser,
9237 CPP_DEREF))
9238 {
9239 if (c_parser_next_token_is (parser, CPP_DEREF))
9240 {
9241 loc = c_parser_peek_token (parser)->location;
9242 offsetof_ref = build_array_ref (loc,
9243 offsetof_ref,
9244 integer_zero_node);
9245 goto do_dot;
9246 }
9247 else if (c_parser_next_token_is (parser, CPP_DOT))
9248 {
9249 do_dot:
9250 c_parser_consume_token (parser);
9251 if (c_parser_next_token_is_not (parser,
9252 CPP_NAME))
9253 {
9254 c_parser_error (parser, "expected identifier");
9255 break;
9256 }
9257 c_token *comp_tok = c_parser_peek_token (parser);
9258 offsetof_ref = build_component_ref
9259 (loc, offsetof_ref, comp_tok->value,
9260 comp_tok->location);
9261 c_parser_consume_token (parser);
9262 }
9263 else
9264 {
9265 struct c_expr ce;
9266 tree idx;
9267 loc = c_parser_peek_token (parser)->location;
9268 c_parser_consume_token (parser);
9269 ce = c_parser_expression (parser);
9270 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
9271 idx = ce.value;
9272 idx = c_fully_fold (idx, false, NULL);
9273 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
9274 "expected %<]%>");
9275 offsetof_ref = build_array_ref (loc, offsetof_ref, idx);
9276 }
9277 }
9278 }
9279 else
9280 c_parser_error (parser, "expected identifier");
9281 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
9282 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9283 "expected %<)%>");
9284 expr.value = fold_offsetof (offsetof_ref);
9285 set_c_expr_source_range (&expr, loc, end_loc);
9286 }
9287 break;
9288 case RID_CHOOSE_EXPR:
9289 {
9290 vec<c_expr_t, va_gc> *cexpr_list;
9291 c_expr_t *e1_p, *e2_p, *e3_p;
9292 tree c;
9293 location_t close_paren_loc;
9294
9295 c_parser_consume_token (parser);
9296 if (!c_parser_get_builtin_args (parser,
9297 "__builtin_choose_expr",
9298 &cexpr_list, true,
9299 &close_paren_loc))
9300 {
9301 expr.set_error ();
9302 break;
9303 }
9304
9305 if (vec_safe_length (cexpr_list) != 3)
9306 {
9307 error_at (loc, "wrong number of arguments to "
9308 "%<__builtin_choose_expr%>");
9309 expr.set_error ();
9310 break;
9311 }
9312
9313 e1_p = &(*cexpr_list)[0];
9314 e2_p = &(*cexpr_list)[1];
9315 e3_p = &(*cexpr_list)[2];
9316
9317 c = e1_p->value;
9318 mark_exp_read (e2_p->value);
9319 mark_exp_read (e3_p->value);
9320 if (TREE_CODE (c) != INTEGER_CST
9321 || !INTEGRAL_TYPE_P (TREE_TYPE (c)))
9322 error_at (loc,
9323 "first argument to %<__builtin_choose_expr%> not"
9324 " a constant");
9325 constant_expression_warning (c);
9326 expr = integer_zerop (c) ? *e3_p : *e2_p;
9327 set_c_expr_source_range (&expr, loc, close_paren_loc);
9328 break;
9329 }
9330 case RID_TYPES_COMPATIBLE_P:
9331 {
9332 c_parser_consume_token (parser);
9333 matching_parens parens;
9334 if (!parens.require_open (parser))
9335 {
9336 expr.set_error ();
9337 break;
9338 }
9339 t1 = c_parser_type_name (parser);
9340 if (t1 == NULL)
9341 {
9342 expr.set_error ();
9343 break;
9344 }
9345 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9346 {
9347 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9348 expr.set_error ();
9349 break;
9350 }
9351 t2 = c_parser_type_name (parser);
9352 if (t2 == NULL)
9353 {
9354 expr.set_error ();
9355 break;
9356 }
9357 location_t close_paren_loc = c_parser_peek_token (parser)->location;
9358 parens.skip_until_found_close (parser);
9359 tree e1, e2;
9360 e1 = groktypename (t1, NULL, NULL);
9361 e2 = groktypename (t2, NULL, NULL);
9362 if (e1 == error_mark_node || e2 == error_mark_node)
9363 {
9364 expr.set_error ();
9365 break;
9366 }
9367
9368 e1 = TYPE_MAIN_VARIANT (e1);
9369 e2 = TYPE_MAIN_VARIANT (e2);
9370
9371 expr.value
9372 = comptypes (e1, e2) ? integer_one_node : integer_zero_node;
9373 set_c_expr_source_range (&expr, loc, close_paren_loc);
9374 }
9375 break;
9376 case RID_BUILTIN_TGMATH:
9377 {
9378 vec<c_expr_t, va_gc> *cexpr_list;
9379 location_t close_paren_loc;
9380
9381 c_parser_consume_token (parser);
9382 if (!c_parser_get_builtin_args (parser,
9383 "__builtin_tgmath",
9384 &cexpr_list, false,
9385 &close_paren_loc))
9386 {
9387 expr.set_error ();
9388 break;
9389 }
9390
9391 if (vec_safe_length (cexpr_list) < 3)
9392 {
9393 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9394 expr.set_error ();
9395 break;
9396 }
9397
9398 unsigned int i;
9399 c_expr_t *p;
9400 FOR_EACH_VEC_ELT (*cexpr_list, i, p)
9401 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
9402 unsigned int nargs = check_tgmath_function (&(*cexpr_list)[0], 1);
9403 if (nargs == 0)
9404 {
9405 expr.set_error ();
9406 break;
9407 }
9408 if (vec_safe_length (cexpr_list) < nargs)
9409 {
9410 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9411 expr.set_error ();
9412 break;
9413 }
9414 unsigned int num_functions = vec_safe_length (cexpr_list) - nargs;
9415 if (num_functions < 2)
9416 {
9417 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
9418 expr.set_error ();
9419 break;
9420 }
9421
9422 /* The first NUM_FUNCTIONS expressions are the function
9423 pointers. The remaining NARGS expressions are the
9424 arguments that are to be passed to one of those
9425 functions, chosen following <tgmath.h> rules. */
9426 for (unsigned int j = 1; j < num_functions; j++)
9427 {
9428 unsigned int this_nargs
9429 = check_tgmath_function (&(*cexpr_list)[j], j + 1);
9430 if (this_nargs == 0)
9431 {
9432 expr.set_error ();
9433 goto out;
9434 }
9435 if (this_nargs != nargs)
9436 {
9437 error_at ((*cexpr_list)[j].get_location (),
9438 "argument %u of %<__builtin_tgmath%> has "
9439 "wrong number of arguments", j + 1);
9440 expr.set_error ();
9441 goto out;
9442 }
9443 }
9444
9445 /* The functions all have the same number of arguments.
9446 Determine whether arguments and return types vary in
9447 ways permitted for <tgmath.h> functions. */
9448 /* The first entry in each of these vectors is for the
9449 return type, subsequent entries for parameter
9450 types. */
9451 auto_vec<enum tgmath_parm_kind> parm_kind (nargs + 1);
9452 auto_vec<tree> parm_first (nargs + 1);
9453 auto_vec<bool> parm_complex (nargs + 1);
9454 auto_vec<bool> parm_varies (nargs + 1);
9455 tree first_type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[0].value));
9456 tree first_ret = TYPE_MAIN_VARIANT (TREE_TYPE (first_type));
9457 parm_first.quick_push (first_ret);
9458 parm_complex.quick_push (TREE_CODE (first_ret) == COMPLEX_TYPE);
9459 parm_varies.quick_push (false);
9460 function_args_iterator iter;
9461 tree t;
9462 unsigned int argpos;
9463 FOREACH_FUNCTION_ARGS (first_type, t, iter)
9464 {
9465 if (t == void_type_node)
9466 break;
9467 parm_first.quick_push (TYPE_MAIN_VARIANT (t));
9468 parm_complex.quick_push (TREE_CODE (t) == COMPLEX_TYPE);
9469 parm_varies.quick_push (false);
9470 }
9471 for (unsigned int j = 1; j < num_functions; j++)
9472 {
9473 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9474 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
9475 if (ret != parm_first[0])
9476 {
9477 parm_varies[0] = true;
9478 if (!SCALAR_FLOAT_TYPE_P (parm_first[0])
9479 && !COMPLEX_FLOAT_TYPE_P (parm_first[0]))
9480 {
9481 error_at ((*cexpr_list)[0].get_location (),
9482 "invalid type-generic return type for "
9483 "argument %u of %<__builtin_tgmath%>",
9484 1);
9485 expr.set_error ();
9486 goto out;
9487 }
9488 if (!SCALAR_FLOAT_TYPE_P (ret)
9489 && !COMPLEX_FLOAT_TYPE_P (ret))
9490 {
9491 error_at ((*cexpr_list)[j].get_location (),
9492 "invalid type-generic return type for "
9493 "argument %u of %<__builtin_tgmath%>",
9494 j + 1);
9495 expr.set_error ();
9496 goto out;
9497 }
9498 }
9499 if (TREE_CODE (ret) == COMPLEX_TYPE)
9500 parm_complex[0] = true;
9501 argpos = 1;
9502 FOREACH_FUNCTION_ARGS (type, t, iter)
9503 {
9504 if (t == void_type_node)
9505 break;
9506 t = TYPE_MAIN_VARIANT (t);
9507 if (t != parm_first[argpos])
9508 {
9509 parm_varies[argpos] = true;
9510 if (!SCALAR_FLOAT_TYPE_P (parm_first[argpos])
9511 && !COMPLEX_FLOAT_TYPE_P (parm_first[argpos]))
9512 {
9513 error_at ((*cexpr_list)[0].get_location (),
9514 "invalid type-generic type for "
9515 "argument %u of argument %u of "
9516 "%<__builtin_tgmath%>", argpos, 1);
9517 expr.set_error ();
9518 goto out;
9519 }
9520 if (!SCALAR_FLOAT_TYPE_P (t)
9521 && !COMPLEX_FLOAT_TYPE_P (t))
9522 {
9523 error_at ((*cexpr_list)[j].get_location (),
9524 "invalid type-generic type for "
9525 "argument %u of argument %u of "
9526 "%<__builtin_tgmath%>", argpos, j + 1);
9527 expr.set_error ();
9528 goto out;
9529 }
9530 }
9531 if (TREE_CODE (t) == COMPLEX_TYPE)
9532 parm_complex[argpos] = true;
9533 argpos++;
9534 }
9535 }
9536 enum tgmath_parm_kind max_variation = tgmath_fixed;
9537 for (unsigned int j = 0; j <= nargs; j++)
9538 {
9539 enum tgmath_parm_kind this_kind;
9540 if (parm_varies[j])
9541 {
9542 if (parm_complex[j])
9543 max_variation = this_kind = tgmath_complex;
9544 else
9545 {
9546 this_kind = tgmath_real;
9547 if (max_variation != tgmath_complex)
9548 max_variation = tgmath_real;
9549 }
9550 }
9551 else
9552 this_kind = tgmath_fixed;
9553 parm_kind.quick_push (this_kind);
9554 }
9555 if (max_variation == tgmath_fixed)
9556 {
9557 error_at (loc, "function arguments of %<__builtin_tgmath%> "
9558 "all have the same type");
9559 expr.set_error ();
9560 break;
9561 }
9562
9563 /* Identify a parameter (not the return type) that varies,
9564 including with complex types if any variation includes
9565 complex types; there must be at least one such
9566 parameter. */
9567 unsigned int tgarg = 0;
9568 for (unsigned int j = 1; j <= nargs; j++)
9569 if (parm_kind[j] == max_variation)
9570 {
9571 tgarg = j;
9572 break;
9573 }
9574 if (tgarg == 0)
9575 {
9576 error_at (loc, "function arguments of %<__builtin_tgmath%> "
9577 "lack type-generic parameter");
9578 expr.set_error ();
9579 break;
9580 }
9581
9582 /* Determine the type of the relevant parameter for each
9583 function. */
9584 auto_vec<tree> tg_type (num_functions);
9585 for (unsigned int j = 0; j < num_functions; j++)
9586 {
9587 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9588 argpos = 1;
9589 FOREACH_FUNCTION_ARGS (type, t, iter)
9590 {
9591 if (argpos == tgarg)
9592 {
9593 tg_type.quick_push (TYPE_MAIN_VARIANT (t));
9594 break;
9595 }
9596 argpos++;
9597 }
9598 }
9599
9600 /* Verify that the corresponding types are different for
9601 all the listed functions. Also determine whether all
9602 the types are complex, whether all the types are
9603 standard or binary, and whether all the types are
9604 decimal. */
9605 bool all_complex = true;
9606 bool all_binary = true;
9607 bool all_decimal = true;
9608 hash_set<tree> tg_types;
9609 FOR_EACH_VEC_ELT (tg_type, i, t)
9610 {
9611 if (TREE_CODE (t) == COMPLEX_TYPE)
9612 all_decimal = false;
9613 else
9614 {
9615 all_complex = false;
9616 if (DECIMAL_FLOAT_TYPE_P (t))
9617 all_binary = false;
9618 else
9619 all_decimal = false;
9620 }
9621 if (tg_types.add (t))
9622 {
9623 error_at ((*cexpr_list)[i].get_location (),
9624 "duplicate type-generic parameter type for "
9625 "function argument %u of %<__builtin_tgmath%>",
9626 i + 1);
9627 expr.set_error ();
9628 goto out;
9629 }
9630 }
9631
9632 /* Verify that other parameters and the return type whose
9633 types vary have their types varying in the correct
9634 way. */
9635 for (unsigned int j = 0; j < num_functions; j++)
9636 {
9637 tree exp_type = tg_type[j];
9638 tree exp_real_type = exp_type;
9639 if (TREE_CODE (exp_type) == COMPLEX_TYPE)
9640 exp_real_type = TREE_TYPE (exp_type);
9641 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
9642 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
9643 if ((parm_kind[0] == tgmath_complex && ret != exp_type)
9644 || (parm_kind[0] == tgmath_real && ret != exp_real_type))
9645 {
9646 error_at ((*cexpr_list)[j].get_location (),
9647 "bad return type for function argument %u "
9648 "of %<__builtin_tgmath%>", j + 1);
9649 expr.set_error ();
9650 goto out;
9651 }
9652 argpos = 1;
9653 FOREACH_FUNCTION_ARGS (type, t, iter)
9654 {
9655 if (t == void_type_node)
9656 break;
9657 t = TYPE_MAIN_VARIANT (t);
9658 if ((parm_kind[argpos] == tgmath_complex
9659 && t != exp_type)
9660 || (parm_kind[argpos] == tgmath_real
9661 && t != exp_real_type))
9662 {
9663 error_at ((*cexpr_list)[j].get_location (),
9664 "bad type for argument %u of "
9665 "function argument %u of "
9666 "%<__builtin_tgmath%>", argpos, j + 1);
9667 expr.set_error ();
9668 goto out;
9669 }
9670 argpos++;
9671 }
9672 }
9673
9674 /* The functions listed are a valid set of functions for a
9675 <tgmath.h> macro to select between. Identify the
9676 matching function, if any. First, the argument types
9677 must be combined following <tgmath.h> rules. Integer
9678 types are treated as _Decimal64 if any type-generic
9679 argument is decimal, or if the only alternatives for
9680 type-generic arguments are of decimal types, and are
9681 otherwise treated as double (or _Complex double for
9682 complex integer types, or _Float64 or _Complex _Float64
9683 if all the return types are the same _FloatN or
9684 _FloatNx type). After that adjustment, types are
9685 combined following the usual arithmetic conversions.
9686 If the function only accepts complex arguments, a
9687 complex type is produced. */
9688 bool arg_complex = all_complex;
9689 bool arg_binary = all_binary;
9690 bool arg_int_decimal = all_decimal;
9691 for (unsigned int j = 1; j <= nargs; j++)
9692 {
9693 if (parm_kind[j] == tgmath_fixed)
9694 continue;
9695 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
9696 tree type = TREE_TYPE (ce->value);
9697 if (!INTEGRAL_TYPE_P (type)
9698 && !SCALAR_FLOAT_TYPE_P (type)
9699 && TREE_CODE (type) != COMPLEX_TYPE)
9700 {
9701 error_at (ce->get_location (),
9702 "invalid type of argument %u of type-generic "
9703 "function", j);
9704 expr.set_error ();
9705 goto out;
9706 }
9707 if (DECIMAL_FLOAT_TYPE_P (type))
9708 {
9709 arg_int_decimal = true;
9710 if (all_complex)
9711 {
9712 error_at (ce->get_location (),
9713 "decimal floating-point argument %u to "
9714 "complex-only type-generic function", j);
9715 expr.set_error ();
9716 goto out;
9717 }
9718 else if (all_binary)
9719 {
9720 error_at (ce->get_location (),
9721 "decimal floating-point argument %u to "
9722 "binary-only type-generic function", j);
9723 expr.set_error ();
9724 goto out;
9725 }
9726 else if (arg_complex)
9727 {
9728 error_at (ce->get_location (),
9729 "both complex and decimal floating-point "
9730 "arguments to type-generic function");
9731 expr.set_error ();
9732 goto out;
9733 }
9734 else if (arg_binary)
9735 {
9736 error_at (ce->get_location (),
9737 "both binary and decimal floating-point "
9738 "arguments to type-generic function");
9739 expr.set_error ();
9740 goto out;
9741 }
9742 }
9743 else if (TREE_CODE (type) == COMPLEX_TYPE)
9744 {
9745 arg_complex = true;
9746 if (COMPLEX_FLOAT_TYPE_P (type))
9747 arg_binary = true;
9748 if (all_decimal)
9749 {
9750 error_at (ce->get_location (),
9751 "complex argument %u to "
9752 "decimal-only type-generic function", j);
9753 expr.set_error ();
9754 goto out;
9755 }
9756 else if (arg_int_decimal)
9757 {
9758 error_at (ce->get_location (),
9759 "both complex and decimal floating-point "
9760 "arguments to type-generic function");
9761 expr.set_error ();
9762 goto out;
9763 }
9764 }
9765 else if (SCALAR_FLOAT_TYPE_P (type))
9766 {
9767 arg_binary = true;
9768 if (all_decimal)
9769 {
9770 error_at (ce->get_location (),
9771 "binary argument %u to "
9772 "decimal-only type-generic function", j);
9773 expr.set_error ();
9774 goto out;
9775 }
9776 else if (arg_int_decimal)
9777 {
9778 error_at (ce->get_location (),
9779 "both binary and decimal floating-point "
9780 "arguments to type-generic function");
9781 expr.set_error ();
9782 goto out;
9783 }
9784 }
9785 }
9786 /* For a macro rounding its result to a narrower type, map
9787 integer types to _Float64 not double if the return type
9788 is a _FloatN or _FloatNx type. */
9789 bool arg_int_float64 = false;
9790 if (parm_kind[0] == tgmath_fixed
9791 && SCALAR_FLOAT_TYPE_P (parm_first[0])
9792 && float64_type_node != NULL_TREE)
9793 for (unsigned int j = 0; j < NUM_FLOATN_NX_TYPES; j++)
9794 if (parm_first[0] == FLOATN_TYPE_NODE (j))
9795 {
9796 arg_int_float64 = true;
9797 break;
9798 }
9799 tree arg_real = NULL_TREE;
9800 for (unsigned int j = 1; j <= nargs; j++)
9801 {
9802 if (parm_kind[j] == tgmath_fixed)
9803 continue;
9804 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
9805 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ce->value));
9806 if (TREE_CODE (type) == COMPLEX_TYPE)
9807 type = TREE_TYPE (type);
9808 if (INTEGRAL_TYPE_P (type))
9809 type = (arg_int_decimal
9810 ? dfloat64_type_node
9811 : arg_int_float64
9812 ? float64_type_node
9813 : double_type_node);
9814 if (arg_real == NULL_TREE)
9815 arg_real = type;
9816 else
9817 arg_real = common_type (arg_real, type);
9818 if (arg_real == error_mark_node)
9819 {
9820 expr.set_error ();
9821 goto out;
9822 }
9823 }
9824 tree arg_type = (arg_complex
9825 ? build_complex_type (arg_real)
9826 : arg_real);
9827
9828 /* Look for a function to call with type-generic parameter
9829 type ARG_TYPE. */
9830 c_expr_t *fn = NULL;
9831 for (unsigned int j = 0; j < num_functions; j++)
9832 {
9833 if (tg_type[j] == arg_type)
9834 {
9835 fn = &(*cexpr_list)[j];
9836 break;
9837 }
9838 }
9839 if (fn == NULL
9840 && parm_kind[0] == tgmath_fixed
9841 && SCALAR_FLOAT_TYPE_P (parm_first[0]))
9842 {
9843 /* Presume this is a macro that rounds its result to a
9844 narrower type, and look for the first function with
9845 at least the range and precision of the argument
9846 type. */
9847 for (unsigned int j = 0; j < num_functions; j++)
9848 {
9849 if (arg_complex
9850 != (TREE_CODE (tg_type[j]) == COMPLEX_TYPE))
9851 continue;
9852 tree real_tg_type = (arg_complex
9853 ? TREE_TYPE (tg_type[j])
9854 : tg_type[j]);
9855 if (DECIMAL_FLOAT_TYPE_P (arg_real)
9856 != DECIMAL_FLOAT_TYPE_P (real_tg_type))
9857 continue;
9858 scalar_float_mode arg_mode
9859 = SCALAR_FLOAT_TYPE_MODE (arg_real);
9860 scalar_float_mode tg_mode
9861 = SCALAR_FLOAT_TYPE_MODE (real_tg_type);
9862 const real_format *arg_fmt = REAL_MODE_FORMAT (arg_mode);
9863 const real_format *tg_fmt = REAL_MODE_FORMAT (tg_mode);
9864 if (arg_fmt->b == tg_fmt->b
9865 && arg_fmt->p <= tg_fmt->p
9866 && arg_fmt->emax <= tg_fmt->emax
9867 && (arg_fmt->emin - arg_fmt->p
9868 >= tg_fmt->emin - tg_fmt->p))
9869 {
9870 fn = &(*cexpr_list)[j];
9871 break;
9872 }
9873 }
9874 }
9875 if (fn == NULL)
9876 {
9877 error_at (loc, "no matching function for type-generic call");
9878 expr.set_error ();
9879 break;
9880 }
9881
9882 /* Construct a call to FN. */
9883 vec<tree, va_gc> *args;
9884 vec_alloc (args, nargs);
9885 vec<tree, va_gc> *origtypes;
9886 vec_alloc (origtypes, nargs);
9887 auto_vec<location_t> arg_loc (nargs);
9888 for (unsigned int j = 0; j < nargs; j++)
9889 {
9890 c_expr_t *ce = &(*cexpr_list)[num_functions + j];
9891 args->quick_push (ce->value);
9892 arg_loc.quick_push (ce->get_location ());
9893 origtypes->quick_push (ce->original_type);
9894 }
9895 expr.value = c_build_function_call_vec (loc, arg_loc, fn->value,
9896 args, origtypes);
9897 set_c_expr_source_range (&expr, loc, close_paren_loc);
9898 break;
9899 }
9900 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN:
9901 {
9902 vec<c_expr_t, va_gc> *cexpr_list;
9903 c_expr_t *e2_p;
9904 tree chain_value;
9905 location_t close_paren_loc;
9906
9907 c_parser_consume_token (parser);
9908 if (!c_parser_get_builtin_args (parser,
9909 "__builtin_call_with_static_chain",
9910 &cexpr_list, false,
9911 &close_paren_loc))
9912 {
9913 expr.set_error ();
9914 break;
9915 }
9916 if (vec_safe_length (cexpr_list) != 2)
9917 {
9918 error_at (loc, "wrong number of arguments to "
9919 "%<__builtin_call_with_static_chain%>");
9920 expr.set_error ();
9921 break;
9922 }
9923
9924 expr = (*cexpr_list)[0];
9925 e2_p = &(*cexpr_list)[1];
9926 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
9927 chain_value = e2_p->value;
9928 mark_exp_read (chain_value);
9929
9930 if (TREE_CODE (expr.value) != CALL_EXPR)
9931 error_at (loc, "first argument to "
9932 "%<__builtin_call_with_static_chain%> "
9933 "must be a call expression");
9934 else if (TREE_CODE (TREE_TYPE (chain_value)) != POINTER_TYPE)
9935 error_at (loc, "second argument to "
9936 "%<__builtin_call_with_static_chain%> "
9937 "must be a pointer type");
9938 else
9939 CALL_EXPR_STATIC_CHAIN (expr.value) = chain_value;
9940 set_c_expr_source_range (&expr, loc, close_paren_loc);
9941 break;
9942 }
9943 case RID_BUILTIN_COMPLEX:
9944 {
9945 vec<c_expr_t, va_gc> *cexpr_list;
9946 c_expr_t *e1_p, *e2_p;
9947 location_t close_paren_loc;
9948
9949 c_parser_consume_token (parser);
9950 if (!c_parser_get_builtin_args (parser,
9951 "__builtin_complex",
9952 &cexpr_list, false,
9953 &close_paren_loc))
9954 {
9955 expr.set_error ();
9956 break;
9957 }
9958
9959 if (vec_safe_length (cexpr_list) != 2)
9960 {
9961 error_at (loc, "wrong number of arguments to "
9962 "%<__builtin_complex%>");
9963 expr.set_error ();
9964 break;
9965 }
9966
9967 e1_p = &(*cexpr_list)[0];
9968 e2_p = &(*cexpr_list)[1];
9969
9970 *e1_p = convert_lvalue_to_rvalue (loc, *e1_p, true, true);
9971 if (TREE_CODE (e1_p->value) == EXCESS_PRECISION_EXPR)
9972 e1_p->value = convert (TREE_TYPE (e1_p->value),
9973 TREE_OPERAND (e1_p->value, 0));
9974 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
9975 if (TREE_CODE (e2_p->value) == EXCESS_PRECISION_EXPR)
9976 e2_p->value = convert (TREE_TYPE (e2_p->value),
9977 TREE_OPERAND (e2_p->value, 0));
9978 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
9979 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
9980 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p->value))
9981 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p->value)))
9982 {
9983 error_at (loc, "%<__builtin_complex%> operand "
9984 "not of real binary floating-point type");
9985 expr.set_error ();
9986 break;
9987 }
9988 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p->value))
9989 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p->value)))
9990 {
9991 error_at (loc,
9992 "%<__builtin_complex%> operands of different types");
9993 expr.set_error ();
9994 break;
9995 }
9996 pedwarn_c90 (loc, OPT_Wpedantic,
9997 "ISO C90 does not support complex types");
9998 expr.value = build2_loc (loc, COMPLEX_EXPR,
9999 build_complex_type
10000 (TYPE_MAIN_VARIANT
10001 (TREE_TYPE (e1_p->value))),
10002 e1_p->value, e2_p->value);
10003 set_c_expr_source_range (&expr, loc, close_paren_loc);
10004 break;
10005 }
10006 case RID_BUILTIN_SHUFFLE:
10007 {
10008 vec<c_expr_t, va_gc> *cexpr_list;
10009 unsigned int i;
10010 c_expr_t *p;
10011 location_t close_paren_loc;
10012
10013 c_parser_consume_token (parser);
10014 if (!c_parser_get_builtin_args (parser,
10015 "__builtin_shuffle",
10016 &cexpr_list, false,
10017 &close_paren_loc))
10018 {
10019 expr.set_error ();
10020 break;
10021 }
10022
10023 FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
10024 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
10025
10026 if (vec_safe_length (cexpr_list) == 2)
10027 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
10028 NULL_TREE,
10029 (*cexpr_list)[1].value);
10030
10031 else if (vec_safe_length (cexpr_list) == 3)
10032 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
10033 (*cexpr_list)[1].value,
10034 (*cexpr_list)[2].value);
10035 else
10036 {
10037 error_at (loc, "wrong number of arguments to "
10038 "%<__builtin_shuffle%>");
10039 expr.set_error ();
10040 }
10041 set_c_expr_source_range (&expr, loc, close_paren_loc);
10042 break;
10043 }
10044 case RID_BUILTIN_SHUFFLEVECTOR:
10045 {
10046 vec<c_expr_t, va_gc> *cexpr_list;
10047 unsigned int i;
10048 c_expr_t *p;
10049 location_t close_paren_loc;
10050
10051 c_parser_consume_token (parser);
10052 if (!c_parser_get_builtin_args (parser,
10053 "__builtin_shufflevector",
10054 &cexpr_list, false,
10055 &close_paren_loc))
10056 {
10057 expr.set_error ();
10058 break;
10059 }
10060
10061 FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
10062 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
10063
10064 if (vec_safe_length (cexpr_list) < 3)
10065 {
10066 error_at (loc, "wrong number of arguments to "
10067 "%<__builtin_shuffle%>");
10068 expr.set_error ();
10069 }
10070 else
10071 {
10072 auto_vec<tree, 16> mask;
10073 for (i = 2; i < cexpr_list->length (); ++i)
10074 mask.safe_push ((*cexpr_list)[i].value);
10075 expr.value = c_build_shufflevector (loc, (*cexpr_list)[0].value,
10076 (*cexpr_list)[1].value,
10077 mask);
10078 }
10079 set_c_expr_source_range (&expr, loc, close_paren_loc);
10080 break;
10081 }
10082 case RID_BUILTIN_CONVERTVECTOR:
10083 {
10084 location_t start_loc = loc;
10085 c_parser_consume_token (parser);
10086 matching_parens parens;
10087 if (!parens.require_open (parser))
10088 {
10089 expr.set_error ();
10090 break;
10091 }
10092 e1 = c_parser_expr_no_commas (parser, NULL);
10093 mark_exp_read (e1.value);
10094 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
10095 {
10096 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10097 expr.set_error ();
10098 break;
10099 }
10100 loc = c_parser_peek_token (parser)->location;
10101 t1 = c_parser_type_name (parser);
10102 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
10103 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10104 "expected %<)%>");
10105 if (t1 == NULL)
10106 expr.set_error ();
10107 else
10108 {
10109 tree type_expr = NULL_TREE;
10110 expr.value = c_build_vec_convert (start_loc, e1.value, loc,
10111 groktypename (t1, &type_expr,
10112 NULL));
10113 set_c_expr_source_range (&expr, start_loc, end_loc);
10114 }
10115 }
10116 break;
10117 case RID_BUILTIN_ASSOC_BARRIER:
10118 {
10119 location_t start_loc = loc;
10120 c_parser_consume_token (parser);
10121 matching_parens parens;
10122 if (!parens.require_open (parser))
10123 {
10124 expr.set_error ();
10125 break;
10126 }
10127 e1 = c_parser_expr_no_commas (parser, NULL);
10128 mark_exp_read (e1.value);
10129 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
10130 parens.skip_until_found_close (parser);
10131 expr = parser_build_unary_op (loc, PAREN_EXPR, e1);
10132 set_c_expr_source_range (&expr, start_loc, end_loc);
10133 }
10134 break;
10135 case RID_AT_SELECTOR:
10136 {
10137 gcc_assert (c_dialect_objc ());
10138 c_parser_consume_token (parser);
10139 matching_parens parens;
10140 if (!parens.require_open (parser))
10141 {
10142 expr.set_error ();
10143 break;
10144 }
10145 tree sel = c_parser_objc_selector_arg (parser);
10146 location_t close_loc = c_parser_peek_token (parser)->location;
10147 parens.skip_until_found_close (parser);
10148 expr.value = objc_build_selector_expr (loc, sel);
10149 set_c_expr_source_range (&expr, loc, close_loc);
10150 }
10151 break;
10152 case RID_AT_PROTOCOL:
10153 {
10154 gcc_assert (c_dialect_objc ());
10155 c_parser_consume_token (parser);
10156 matching_parens parens;
10157 if (!parens.require_open (parser))
10158 {
10159 expr.set_error ();
10160 break;
10161 }
10162 if (c_parser_next_token_is_not (parser, CPP_NAME))
10163 {
10164 c_parser_error (parser, "expected identifier");
10165 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10166 expr.set_error ();
10167 break;
10168 }
10169 tree id = c_parser_peek_token (parser)->value;
10170 c_parser_consume_token (parser);
10171 location_t close_loc = c_parser_peek_token (parser)->location;
10172 parens.skip_until_found_close (parser);
10173 expr.value = objc_build_protocol_expr (id);
10174 set_c_expr_source_range (&expr, loc, close_loc);
10175 }
10176 break;
10177 case RID_AT_ENCODE:
10178 {
10179 /* Extension to support C-structures in the archiver. */
10180 gcc_assert (c_dialect_objc ());
10181 c_parser_consume_token (parser);
10182 matching_parens parens;
10183 if (!parens.require_open (parser))
10184 {
10185 expr.set_error ();
10186 break;
10187 }
10188 t1 = c_parser_type_name (parser);
10189 if (t1 == NULL)
10190 {
10191 expr.set_error ();
10192 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10193 break;
10194 }
10195 location_t close_loc = c_parser_peek_token (parser)->location;
10196 parens.skip_until_found_close (parser);
10197 tree type = groktypename (t1, NULL, NULL);
10198 expr.value = objc_build_encode_expr (type);
10199 set_c_expr_source_range (&expr, loc, close_loc);
10200 }
10201 break;
10202 case RID_GENERIC:
10203 expr = c_parser_generic_selection (parser);
10204 break;
10205 default:
10206 c_parser_error (parser, "expected expression");
10207 expr.set_error ();
10208 break;
10209 }
10210 break;
10211 case CPP_OPEN_SQUARE:
10212 if (c_dialect_objc ())
10213 {
10214 tree receiver, args;
10215 c_parser_consume_token (parser);
10216 receiver = c_parser_objc_receiver (parser);
10217 args = c_parser_objc_message_args (parser);
10218 location_t close_loc = c_parser_peek_token (parser)->location;
10219 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10220 "expected %<]%>");
10221 expr.value = objc_build_message_expr (receiver, args);
10222 set_c_expr_source_range (&expr, loc, close_loc);
10223 break;
10224 }
10225 /* Else fall through to report error. */
10226 /* FALLTHRU */
10227 default:
10228 c_parser_error (parser, "expected expression");
10229 expr.set_error ();
10230 break;
10231 }
10232 out:
10233 return c_parser_postfix_expression_after_primary
10234 (parser, EXPR_LOC_OR_LOC (expr.value, loc), expr);
10235 }
10236
10237 /* Parse a postfix expression after a parenthesized type name: the
10238 brace-enclosed initializer of a compound literal, possibly followed
10239 by some postfix operators. This is separate because it is not
10240 possible to tell until after the type name whether a cast
10241 expression has a cast or a compound literal, or whether the operand
10242 of sizeof is a parenthesized type name or starts with a compound
10243 literal. TYPE_LOC is the location where TYPE_NAME starts--the
10244 location of the first token after the parentheses around the type
10245 name. */
10246
10247 static struct c_expr
10248 c_parser_postfix_expression_after_paren_type (c_parser *parser,
10249 struct c_type_name *type_name,
10250 location_t type_loc)
10251 {
10252 tree type;
10253 struct c_expr init;
10254 bool non_const;
10255 struct c_expr expr;
10256 location_t start_loc;
10257 tree type_expr = NULL_TREE;
10258 bool type_expr_const = true;
10259 check_compound_literal_type (type_loc, type_name);
10260 rich_location richloc (line_table, type_loc);
10261 start_init (NULL_TREE, NULL, 0, &richloc);
10262 type = groktypename (type_name, &type_expr, &type_expr_const);
10263 start_loc = c_parser_peek_token (parser)->location;
10264 if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type))
10265 {
10266 error_at (type_loc, "compound literal has variable size");
10267 type = error_mark_node;
10268 }
10269 init = c_parser_braced_init (parser, type, false, NULL);
10270 finish_init ();
10271 maybe_warn_string_init (type_loc, type, init);
10272
10273 if (type != error_mark_node
10274 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type))
10275 && current_function_decl)
10276 {
10277 error ("compound literal qualified by address-space qualifier");
10278 type = error_mark_node;
10279 }
10280
10281 pedwarn_c90 (start_loc, OPT_Wpedantic, "ISO C90 forbids compound literals");
10282 non_const = ((init.value && TREE_CODE (init.value) == CONSTRUCTOR)
10283 ? CONSTRUCTOR_NON_CONST (init.value)
10284 : init.original_code == C_MAYBE_CONST_EXPR);
10285 non_const |= !type_expr_const;
10286 unsigned int alignas_align = 0;
10287 if (type != error_mark_node
10288 && type_name->specs->align_log != -1)
10289 {
10290 alignas_align = 1U << type_name->specs->align_log;
10291 if (alignas_align < min_align_of_type (type))
10292 {
10293 error_at (type_name->specs->locations[cdw_alignas],
10294 "%<_Alignas%> specifiers cannot reduce "
10295 "alignment of compound literal");
10296 alignas_align = 0;
10297 }
10298 }
10299 expr.value = build_compound_literal (start_loc, type, init.value, non_const,
10300 alignas_align);
10301 set_c_expr_source_range (&expr, init.src_range);
10302 expr.original_code = ERROR_MARK;
10303 expr.original_type = NULL;
10304 if (type != error_mark_node
10305 && expr.value != error_mark_node
10306 && type_expr)
10307 {
10308 if (TREE_CODE (expr.value) == C_MAYBE_CONST_EXPR)
10309 {
10310 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr.value) == NULL_TREE);
10311 C_MAYBE_CONST_EXPR_PRE (expr.value) = type_expr;
10312 }
10313 else
10314 {
10315 gcc_assert (!non_const);
10316 expr.value = build2 (C_MAYBE_CONST_EXPR, type,
10317 type_expr, expr.value);
10318 }
10319 }
10320 return c_parser_postfix_expression_after_primary (parser, start_loc, expr);
10321 }
10322
10323 /* Callback function for sizeof_pointer_memaccess_warning to compare
10324 types. */
10325
10326 static bool
10327 sizeof_ptr_memacc_comptypes (tree type1, tree type2)
10328 {
10329 return comptypes (type1, type2) == 1;
10330 }
10331
10332 /* Warn for patterns where abs-like function appears to be used incorrectly,
10333 gracefully ignore any non-abs-like function. The warning location should
10334 be LOC. FNDECL is the declaration of called function, it must be a
10335 BUILT_IN_NORMAL function. ARG is the first and only argument of the
10336 call. */
10337
10338 static void
10339 warn_for_abs (location_t loc, tree fndecl, tree arg)
10340 {
10341 /* Avoid warning in unreachable subexpressions. */
10342 if (c_inhibit_evaluation_warnings)
10343 return;
10344
10345 tree atype = TREE_TYPE (arg);
10346
10347 /* Casts from pointers (and thus arrays and fndecls) will generate
10348 -Wint-conversion warnings. Most other wrong types hopefully lead to type
10349 mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P
10350 types and possibly other exotic types. */
10351 if (!INTEGRAL_TYPE_P (atype)
10352 && !SCALAR_FLOAT_TYPE_P (atype)
10353 && TREE_CODE (atype) != COMPLEX_TYPE)
10354 return;
10355
10356 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10357
10358 switch (fcode)
10359 {
10360 case BUILT_IN_ABS:
10361 case BUILT_IN_LABS:
10362 case BUILT_IN_LLABS:
10363 case BUILT_IN_IMAXABS:
10364 if (!INTEGRAL_TYPE_P (atype))
10365 {
10366 if (SCALAR_FLOAT_TYPE_P (atype))
10367 warning_at (loc, OPT_Wabsolute_value,
10368 "using integer absolute value function %qD when "
10369 "argument is of floating-point type %qT",
10370 fndecl, atype);
10371 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10372 warning_at (loc, OPT_Wabsolute_value,
10373 "using integer absolute value function %qD when "
10374 "argument is of complex type %qT", fndecl, atype);
10375 else
10376 gcc_unreachable ();
10377 return;
10378 }
10379 if (TYPE_UNSIGNED (atype))
10380 warning_at (loc, OPT_Wabsolute_value,
10381 "taking the absolute value of unsigned type %qT "
10382 "has no effect", atype);
10383 break;
10384
10385 CASE_FLT_FN (BUILT_IN_FABS):
10386 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS):
10387 if (!SCALAR_FLOAT_TYPE_P (atype)
10388 || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype)))
10389 {
10390 if (INTEGRAL_TYPE_P (atype))
10391 warning_at (loc, OPT_Wabsolute_value,
10392 "using floating-point absolute value function %qD "
10393 "when argument is of integer type %qT", fndecl, atype);
10394 else if (DECIMAL_FLOAT_TYPE_P (atype))
10395 warning_at (loc, OPT_Wabsolute_value,
10396 "using floating-point absolute value function %qD "
10397 "when argument is of decimal floating-point type %qT",
10398 fndecl, atype);
10399 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10400 warning_at (loc, OPT_Wabsolute_value,
10401 "using floating-point absolute value function %qD when "
10402 "argument is of complex type %qT", fndecl, atype);
10403 else
10404 gcc_unreachable ();
10405 return;
10406 }
10407 break;
10408
10409 CASE_FLT_FN (BUILT_IN_CABS):
10410 if (TREE_CODE (atype) != COMPLEX_TYPE)
10411 {
10412 if (INTEGRAL_TYPE_P (atype))
10413 warning_at (loc, OPT_Wabsolute_value,
10414 "using complex absolute value function %qD when "
10415 "argument is of integer type %qT", fndecl, atype);
10416 else if (SCALAR_FLOAT_TYPE_P (atype))
10417 warning_at (loc, OPT_Wabsolute_value,
10418 "using complex absolute value function %qD when "
10419 "argument is of floating-point type %qT",
10420 fndecl, atype);
10421 else
10422 gcc_unreachable ();
10423
10424 return;
10425 }
10426 break;
10427
10428 case BUILT_IN_FABSD32:
10429 case BUILT_IN_FABSD64:
10430 case BUILT_IN_FABSD128:
10431 if (!DECIMAL_FLOAT_TYPE_P (atype))
10432 {
10433 if (INTEGRAL_TYPE_P (atype))
10434 warning_at (loc, OPT_Wabsolute_value,
10435 "using decimal floating-point absolute value "
10436 "function %qD when argument is of integer type %qT",
10437 fndecl, atype);
10438 else if (SCALAR_FLOAT_TYPE_P (atype))
10439 warning_at (loc, OPT_Wabsolute_value,
10440 "using decimal floating-point absolute value "
10441 "function %qD when argument is of floating-point "
10442 "type %qT", fndecl, atype);
10443 else if (TREE_CODE (atype) == COMPLEX_TYPE)
10444 warning_at (loc, OPT_Wabsolute_value,
10445 "using decimal floating-point absolute value "
10446 "function %qD when argument is of complex type %qT",
10447 fndecl, atype);
10448 else
10449 gcc_unreachable ();
10450 return;
10451 }
10452 break;
10453
10454 default:
10455 return;
10456 }
10457
10458 if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
10459 return;
10460
10461 tree ftype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
10462 if (TREE_CODE (atype) == COMPLEX_TYPE)
10463 {
10464 gcc_assert (TREE_CODE (ftype) == COMPLEX_TYPE);
10465 atype = TREE_TYPE (atype);
10466 ftype = TREE_TYPE (ftype);
10467 }
10468
10469 if (TYPE_PRECISION (ftype) < TYPE_PRECISION (atype))
10470 warning_at (loc, OPT_Wabsolute_value,
10471 "absolute value function %qD given an argument of type %qT "
10472 "but has parameter of type %qT which may cause truncation "
10473 "of value", fndecl, atype, ftype);
10474 }
10475
10476
10477 /* Parse a postfix expression after the initial primary or compound
10478 literal; that is, parse a series of postfix operators.
10479
10480 EXPR_LOC is the location of the primary expression. */
10481
10482 static struct c_expr
10483 c_parser_postfix_expression_after_primary (c_parser *parser,
10484 location_t expr_loc,
10485 struct c_expr expr)
10486 {
10487 struct c_expr orig_expr;
10488 tree ident, idx;
10489 location_t sizeof_arg_loc[3], comp_loc;
10490 tree sizeof_arg[3];
10491 unsigned int literal_zero_mask;
10492 unsigned int i;
10493 vec<tree, va_gc> *exprlist;
10494 vec<tree, va_gc> *origtypes = NULL;
10495 vec<location_t> arg_loc = vNULL;
10496 location_t start;
10497 location_t finish;
10498
10499 while (true)
10500 {
10501 location_t op_loc = c_parser_peek_token (parser)->location;
10502 switch (c_parser_peek_token (parser)->type)
10503 {
10504 case CPP_OPEN_SQUARE:
10505 /* Array reference. */
10506 c_parser_consume_token (parser);
10507 idx = c_parser_expression (parser).value;
10508 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
10509 "expected %<]%>");
10510 start = expr.get_start ();
10511 finish = parser->tokens_buf[0].location;
10512 expr.value = build_array_ref (op_loc, expr.value, idx);
10513 set_c_expr_source_range (&expr, start, finish);
10514 expr.original_code = ERROR_MARK;
10515 expr.original_type = NULL;
10516 break;
10517 case CPP_OPEN_PAREN:
10518 /* Function call. */
10519 {
10520 matching_parens parens;
10521 parens.consume_open (parser);
10522 for (i = 0; i < 3; i++)
10523 {
10524 sizeof_arg[i] = NULL_TREE;
10525 sizeof_arg_loc[i] = UNKNOWN_LOCATION;
10526 }
10527 literal_zero_mask = 0;
10528 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10529 exprlist = NULL;
10530 else
10531 exprlist = c_parser_expr_list (parser, true, false, &origtypes,
10532 sizeof_arg_loc, sizeof_arg,
10533 &arg_loc, &literal_zero_mask);
10534 parens.skip_until_found_close (parser);
10535 }
10536 orig_expr = expr;
10537 mark_exp_read (expr.value);
10538 if (warn_sizeof_pointer_memaccess)
10539 sizeof_pointer_memaccess_warning (sizeof_arg_loc,
10540 expr.value, exprlist,
10541 sizeof_arg,
10542 sizeof_ptr_memacc_comptypes);
10543 if (TREE_CODE (expr.value) == FUNCTION_DECL)
10544 {
10545 if (fndecl_built_in_p (expr.value, BUILT_IN_MEMSET)
10546 && vec_safe_length (exprlist) == 3)
10547 {
10548 tree arg0 = (*exprlist)[0];
10549 tree arg2 = (*exprlist)[2];
10550 warn_for_memset (expr_loc, arg0, arg2, literal_zero_mask);
10551 }
10552 if (warn_absolute_value
10553 && fndecl_built_in_p (expr.value, BUILT_IN_NORMAL)
10554 && vec_safe_length (exprlist) == 1)
10555 warn_for_abs (expr_loc, expr.value, (*exprlist)[0]);
10556 }
10557
10558 start = expr.get_start ();
10559 finish = parser->tokens_buf[0].get_finish ();
10560 expr.value
10561 = c_build_function_call_vec (expr_loc, arg_loc, expr.value,
10562 exprlist, origtypes);
10563 set_c_expr_source_range (&expr, start, finish);
10564
10565 expr.original_code = ERROR_MARK;
10566 if (TREE_CODE (expr.value) == INTEGER_CST
10567 && TREE_CODE (orig_expr.value) == FUNCTION_DECL
10568 && fndecl_built_in_p (orig_expr.value, BUILT_IN_CONSTANT_P))
10569 expr.original_code = C_MAYBE_CONST_EXPR;
10570 expr.original_type = NULL;
10571 if (exprlist)
10572 {
10573 release_tree_vector (exprlist);
10574 release_tree_vector (origtypes);
10575 }
10576 arg_loc.release ();
10577 break;
10578 case CPP_DOT:
10579 /* Structure element reference. */
10580 c_parser_consume_token (parser);
10581 expr = default_function_array_conversion (expr_loc, expr);
10582 if (c_parser_next_token_is (parser, CPP_NAME))
10583 {
10584 c_token *comp_tok = c_parser_peek_token (parser);
10585 ident = comp_tok->value;
10586 comp_loc = comp_tok->location;
10587 }
10588 else
10589 {
10590 c_parser_error (parser, "expected identifier");
10591 expr.set_error ();
10592 expr.original_code = ERROR_MARK;
10593 expr.original_type = NULL;
10594 return expr;
10595 }
10596 start = expr.get_start ();
10597 finish = c_parser_peek_token (parser)->get_finish ();
10598 c_parser_consume_token (parser);
10599 expr.value = build_component_ref (op_loc, expr.value, ident,
10600 comp_loc);
10601 set_c_expr_source_range (&expr, start, finish);
10602 expr.original_code = ERROR_MARK;
10603 if (TREE_CODE (expr.value) != COMPONENT_REF)
10604 expr.original_type = NULL;
10605 else
10606 {
10607 /* Remember the original type of a bitfield. */
10608 tree field = TREE_OPERAND (expr.value, 1);
10609 if (TREE_CODE (field) != FIELD_DECL)
10610 expr.original_type = NULL;
10611 else
10612 expr.original_type = DECL_BIT_FIELD_TYPE (field);
10613 }
10614 break;
10615 case CPP_DEREF:
10616 /* Structure element reference. */
10617 c_parser_consume_token (parser);
10618 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, false);
10619 if (c_parser_next_token_is (parser, CPP_NAME))
10620 {
10621 c_token *comp_tok = c_parser_peek_token (parser);
10622 ident = comp_tok->value;
10623 comp_loc = comp_tok->location;
10624 }
10625 else
10626 {
10627 c_parser_error (parser, "expected identifier");
10628 expr.set_error ();
10629 expr.original_code = ERROR_MARK;
10630 expr.original_type = NULL;
10631 return expr;
10632 }
10633 start = expr.get_start ();
10634 finish = c_parser_peek_token (parser)->get_finish ();
10635 c_parser_consume_token (parser);
10636 expr.value = build_component_ref (op_loc,
10637 build_indirect_ref (op_loc,
10638 expr.value,
10639 RO_ARROW),
10640 ident, comp_loc);
10641 set_c_expr_source_range (&expr, start, finish);
10642 expr.original_code = ERROR_MARK;
10643 if (TREE_CODE (expr.value) != COMPONENT_REF)
10644 expr.original_type = NULL;
10645 else
10646 {
10647 /* Remember the original type of a bitfield. */
10648 tree field = TREE_OPERAND (expr.value, 1);
10649 if (TREE_CODE (field) != FIELD_DECL)
10650 expr.original_type = NULL;
10651 else
10652 expr.original_type = DECL_BIT_FIELD_TYPE (field);
10653 }
10654 break;
10655 case CPP_PLUS_PLUS:
10656 /* Postincrement. */
10657 start = expr.get_start ();
10658 finish = c_parser_peek_token (parser)->get_finish ();
10659 c_parser_consume_token (parser);
10660 expr = default_function_array_read_conversion (expr_loc, expr);
10661 expr.value = build_unary_op (op_loc, POSTINCREMENT_EXPR,
10662 expr.value, false);
10663 set_c_expr_source_range (&expr, start, finish);
10664 expr.original_code = ERROR_MARK;
10665 expr.original_type = NULL;
10666 break;
10667 case CPP_MINUS_MINUS:
10668 /* Postdecrement. */
10669 start = expr.get_start ();
10670 finish = c_parser_peek_token (parser)->get_finish ();
10671 c_parser_consume_token (parser);
10672 expr = default_function_array_read_conversion (expr_loc, expr);
10673 expr.value = build_unary_op (op_loc, POSTDECREMENT_EXPR,
10674 expr.value, false);
10675 set_c_expr_source_range (&expr, start, finish);
10676 expr.original_code = ERROR_MARK;
10677 expr.original_type = NULL;
10678 break;
10679 default:
10680 return expr;
10681 }
10682 }
10683 }
10684
10685 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
10686
10687 expression:
10688 assignment-expression
10689 expression , assignment-expression
10690 */
10691
10692 static struct c_expr
10693 c_parser_expression (c_parser *parser)
10694 {
10695 location_t tloc = c_parser_peek_token (parser)->location;
10696 struct c_expr expr;
10697 expr = c_parser_expr_no_commas (parser, NULL);
10698 if (c_parser_next_token_is (parser, CPP_COMMA))
10699 expr = convert_lvalue_to_rvalue (tloc, expr, true, false);
10700 while (c_parser_next_token_is (parser, CPP_COMMA))
10701 {
10702 struct c_expr next;
10703 tree lhsval;
10704 location_t loc = c_parser_peek_token (parser)->location;
10705 location_t expr_loc;
10706 c_parser_consume_token (parser);
10707 expr_loc = c_parser_peek_token (parser)->location;
10708 lhsval = expr.value;
10709 while (TREE_CODE (lhsval) == COMPOUND_EXPR
10710 || TREE_CODE (lhsval) == NOP_EXPR)
10711 {
10712 if (TREE_CODE (lhsval) == COMPOUND_EXPR)
10713 lhsval = TREE_OPERAND (lhsval, 1);
10714 else
10715 lhsval = TREE_OPERAND (lhsval, 0);
10716 }
10717 if (DECL_P (lhsval) || handled_component_p (lhsval))
10718 mark_exp_read (lhsval);
10719 next = c_parser_expr_no_commas (parser, NULL);
10720 next = convert_lvalue_to_rvalue (expr_loc, next, true, false);
10721 expr.value = build_compound_expr (loc, expr.value, next.value);
10722 expr.original_code = COMPOUND_EXPR;
10723 expr.original_type = next.original_type;
10724 }
10725 return expr;
10726 }
10727
10728 /* Parse an expression and convert functions or arrays to pointers and
10729 lvalues to rvalues. */
10730
10731 static struct c_expr
10732 c_parser_expression_conv (c_parser *parser)
10733 {
10734 struct c_expr expr;
10735 location_t loc = c_parser_peek_token (parser)->location;
10736 expr = c_parser_expression (parser);
10737 expr = convert_lvalue_to_rvalue (loc, expr, true, false);
10738 return expr;
10739 }
10740
10741 /* Helper function of c_parser_expr_list. Check if IDXth (0 based)
10742 argument is a literal zero alone and if so, set it in literal_zero_mask. */
10743
10744 static inline void
10745 c_parser_check_literal_zero (c_parser *parser, unsigned *literal_zero_mask,
10746 unsigned int idx)
10747 {
10748 if (idx >= HOST_BITS_PER_INT)
10749 return;
10750
10751 c_token *tok = c_parser_peek_token (parser);
10752 switch (tok->type)
10753 {
10754 case CPP_NUMBER:
10755 case CPP_CHAR:
10756 case CPP_WCHAR:
10757 case CPP_CHAR16:
10758 case CPP_CHAR32:
10759 case CPP_UTF8CHAR:
10760 /* If a parameter is literal zero alone, remember it
10761 for -Wmemset-transposed-args warning. */
10762 if (integer_zerop (tok->value)
10763 && !TREE_OVERFLOW (tok->value)
10764 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
10765 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
10766 *literal_zero_mask |= 1U << idx;
10767 default:
10768 break;
10769 }
10770 }
10771
10772 /* Parse a non-empty list of expressions. If CONVERT_P, convert
10773 functions and arrays to pointers and lvalues to rvalues. If
10774 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the
10775 locations of function arguments into this vector.
10776
10777 nonempty-expr-list:
10778 assignment-expression
10779 nonempty-expr-list , assignment-expression
10780 */
10781
10782 static vec<tree, va_gc> *
10783 c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
10784 vec<tree, va_gc> **p_orig_types,
10785 location_t *sizeof_arg_loc, tree *sizeof_arg,
10786 vec<location_t> *locations,
10787 unsigned int *literal_zero_mask)
10788 {
10789 vec<tree, va_gc> *ret;
10790 vec<tree, va_gc> *orig_types;
10791 struct c_expr expr;
10792 unsigned int idx = 0;
10793
10794 ret = make_tree_vector ();
10795 if (p_orig_types == NULL)
10796 orig_types = NULL;
10797 else
10798 orig_types = make_tree_vector ();
10799
10800 if (literal_zero_mask)
10801 c_parser_check_literal_zero (parser, literal_zero_mask, 0);
10802 expr = c_parser_expr_no_commas (parser, NULL);
10803 if (convert_p)
10804 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true, true);
10805 if (fold_p)
10806 expr.value = c_fully_fold (expr.value, false, NULL);
10807 ret->quick_push (expr.value);
10808 if (orig_types)
10809 orig_types->quick_push (expr.original_type);
10810 if (locations)
10811 locations->safe_push (expr.get_location ());
10812 if (sizeof_arg != NULL
10813 && (expr.original_code == SIZEOF_EXPR
10814 || expr.original_code == PAREN_SIZEOF_EXPR))
10815 {
10816 sizeof_arg[0] = c_last_sizeof_arg;
10817 sizeof_arg_loc[0] = c_last_sizeof_loc;
10818 }
10819 while (c_parser_next_token_is (parser, CPP_COMMA))
10820 {
10821 c_parser_consume_token (parser);
10822 if (literal_zero_mask)
10823 c_parser_check_literal_zero (parser, literal_zero_mask, idx + 1);
10824 expr = c_parser_expr_no_commas (parser, NULL);
10825 if (convert_p)
10826 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true,
10827 true);
10828 if (fold_p)
10829 expr.value = c_fully_fold (expr.value, false, NULL);
10830 vec_safe_push (ret, expr.value);
10831 if (orig_types)
10832 vec_safe_push (orig_types, expr.original_type);
10833 if (locations)
10834 locations->safe_push (expr.get_location ());
10835 if (++idx < 3
10836 && sizeof_arg != NULL
10837 && (expr.original_code == SIZEOF_EXPR
10838 || expr.original_code == PAREN_SIZEOF_EXPR))
10839 {
10840 sizeof_arg[idx] = c_last_sizeof_arg;
10841 sizeof_arg_loc[idx] = c_last_sizeof_loc;
10842 }
10843 }
10844 if (orig_types)
10845 *p_orig_types = orig_types;
10846 return ret;
10847 }
10848 \f
10849 /* Parse Objective-C-specific constructs. */
10850
10851 /* Parse an objc-class-definition.
10852
10853 objc-class-definition:
10854 @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
10855 objc-class-instance-variables[opt] objc-methodprotolist @end
10856 @implementation identifier objc-superclass[opt]
10857 objc-class-instance-variables[opt]
10858 @interface identifier ( identifier ) objc-protocol-refs[opt]
10859 objc-methodprotolist @end
10860 @interface identifier ( ) objc-protocol-refs[opt]
10861 objc-methodprotolist @end
10862 @implementation identifier ( identifier )
10863
10864 objc-superclass:
10865 : identifier
10866
10867 "@interface identifier (" must start "@interface identifier (
10868 identifier ) ...": objc-methodprotolist in the first production may
10869 not start with a parenthesized identifier as a declarator of a data
10870 definition with no declaration specifiers if the objc-superclass,
10871 objc-protocol-refs and objc-class-instance-variables are omitted. */
10872
10873 static void
10874 c_parser_objc_class_definition (c_parser *parser, tree attributes)
10875 {
10876 bool iface_p;
10877 tree id1;
10878 tree superclass;
10879 if (c_parser_next_token_is_keyword (parser, RID_AT_INTERFACE))
10880 iface_p = true;
10881 else if (c_parser_next_token_is_keyword (parser, RID_AT_IMPLEMENTATION))
10882 iface_p = false;
10883 else
10884 gcc_unreachable ();
10885
10886 c_parser_consume_token (parser);
10887 if (c_parser_next_token_is_not (parser, CPP_NAME))
10888 {
10889 c_parser_error (parser, "expected identifier");
10890 return;
10891 }
10892 id1 = c_parser_peek_token (parser)->value;
10893 location_t loc1 = c_parser_peek_token (parser)->location;
10894 c_parser_consume_token (parser);
10895 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
10896 {
10897 /* We have a category or class extension. */
10898 tree id2;
10899 tree proto = NULL_TREE;
10900 matching_parens parens;
10901 parens.consume_open (parser);
10902 if (c_parser_next_token_is_not (parser, CPP_NAME))
10903 {
10904 if (iface_p && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10905 {
10906 /* We have a class extension. */
10907 id2 = NULL_TREE;
10908 }
10909 else
10910 {
10911 c_parser_error (parser, "expected identifier or %<)%>");
10912 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10913 return;
10914 }
10915 }
10916 else
10917 {
10918 id2 = c_parser_peek_token (parser)->value;
10919 c_parser_consume_token (parser);
10920 }
10921 parens.skip_until_found_close (parser);
10922 if (!iface_p)
10923 {
10924 objc_start_category_implementation (id1, id2);
10925 return;
10926 }
10927 if (c_parser_next_token_is (parser, CPP_LESS))
10928 proto = c_parser_objc_protocol_refs (parser);
10929 objc_start_category_interface (id1, id2, proto, attributes);
10930 c_parser_objc_methodprotolist (parser);
10931 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
10932 objc_finish_interface ();
10933 return;
10934 }
10935 if (c_parser_next_token_is (parser, CPP_COLON))
10936 {
10937 c_parser_consume_token (parser);
10938 if (c_parser_next_token_is_not (parser, CPP_NAME))
10939 {
10940 c_parser_error (parser, "expected identifier");
10941 return;
10942 }
10943 superclass = c_parser_peek_token (parser)->value;
10944 c_parser_consume_token (parser);
10945 }
10946 else
10947 superclass = NULL_TREE;
10948 if (iface_p)
10949 {
10950 tree proto = NULL_TREE;
10951 if (c_parser_next_token_is (parser, CPP_LESS))
10952 proto = c_parser_objc_protocol_refs (parser);
10953 objc_start_class_interface (id1, loc1, superclass, proto, attributes);
10954 }
10955 else
10956 objc_start_class_implementation (id1, superclass);
10957 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
10958 c_parser_objc_class_instance_variables (parser);
10959 if (iface_p)
10960 {
10961 objc_continue_interface ();
10962 c_parser_objc_methodprotolist (parser);
10963 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
10964 objc_finish_interface ();
10965 }
10966 else
10967 {
10968 objc_continue_implementation ();
10969 return;
10970 }
10971 }
10972
10973 /* Parse objc-class-instance-variables.
10974
10975 objc-class-instance-variables:
10976 { objc-instance-variable-decl-list[opt] }
10977
10978 objc-instance-variable-decl-list:
10979 objc-visibility-spec
10980 objc-instance-variable-decl ;
10981 ;
10982 objc-instance-variable-decl-list objc-visibility-spec
10983 objc-instance-variable-decl-list objc-instance-variable-decl ;
10984 objc-instance-variable-decl-list ;
10985
10986 objc-visibility-spec:
10987 @private
10988 @protected
10989 @public
10990
10991 objc-instance-variable-decl:
10992 struct-declaration
10993 */
10994
10995 static void
10996 c_parser_objc_class_instance_variables (c_parser *parser)
10997 {
10998 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
10999 c_parser_consume_token (parser);
11000 while (c_parser_next_token_is_not (parser, CPP_EOF))
11001 {
11002 tree decls;
11003 /* Parse any stray semicolon. */
11004 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
11005 {
11006 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11007 "extra semicolon");
11008 c_parser_consume_token (parser);
11009 continue;
11010 }
11011 /* Stop if at the end of the instance variables. */
11012 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
11013 {
11014 c_parser_consume_token (parser);
11015 break;
11016 }
11017 /* Parse any objc-visibility-spec. */
11018 if (c_parser_next_token_is_keyword (parser, RID_AT_PRIVATE))
11019 {
11020 c_parser_consume_token (parser);
11021 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE);
11022 continue;
11023 }
11024 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROTECTED))
11025 {
11026 c_parser_consume_token (parser);
11027 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED);
11028 continue;
11029 }
11030 else if (c_parser_next_token_is_keyword (parser, RID_AT_PUBLIC))
11031 {
11032 c_parser_consume_token (parser);
11033 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC);
11034 continue;
11035 }
11036 else if (c_parser_next_token_is_keyword (parser, RID_AT_PACKAGE))
11037 {
11038 c_parser_consume_token (parser);
11039 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE);
11040 continue;
11041 }
11042 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
11043 {
11044 c_parser_pragma (parser, pragma_external, NULL);
11045 continue;
11046 }
11047
11048 /* Parse some comma-separated declarations. */
11049 decls = c_parser_struct_declaration (parser);
11050 if (decls == NULL)
11051 {
11052 /* There is a syntax error. We want to skip the offending
11053 tokens up to the next ';' (included) or '}'
11054 (excluded). */
11055
11056 /* First, skip manually a ')' or ']'. This is because they
11057 reduce the nesting level, so c_parser_skip_until_found()
11058 wouldn't be able to skip past them. */
11059 c_token *token = c_parser_peek_token (parser);
11060 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_CLOSE_SQUARE)
11061 c_parser_consume_token (parser);
11062
11063 /* Then, do the standard skipping. */
11064 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11065
11066 /* We hopefully recovered. Start normal parsing again. */
11067 parser->error = false;
11068 continue;
11069 }
11070 else
11071 {
11072 /* Comma-separated instance variables are chained together
11073 in reverse order; add them one by one. */
11074 tree ivar = nreverse (decls);
11075 for (; ivar; ivar = DECL_CHAIN (ivar))
11076 objc_add_instance_variable (copy_node (ivar));
11077 }
11078 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11079 }
11080 }
11081
11082 /* Parse an objc-class-declaration.
11083
11084 objc-class-declaration:
11085 @class identifier-list ;
11086 */
11087
11088 static void
11089 c_parser_objc_class_declaration (c_parser *parser)
11090 {
11091 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_CLASS));
11092 c_parser_consume_token (parser);
11093 /* Any identifiers, including those declared as type names, are OK
11094 here. */
11095 while (true)
11096 {
11097 tree id;
11098 if (c_parser_next_token_is_not (parser, CPP_NAME))
11099 {
11100 c_parser_error (parser, "expected identifier");
11101 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11102 parser->error = false;
11103 return;
11104 }
11105 id = c_parser_peek_token (parser)->value;
11106 objc_declare_class (id);
11107 c_parser_consume_token (parser);
11108 if (c_parser_next_token_is (parser, CPP_COMMA))
11109 c_parser_consume_token (parser);
11110 else
11111 break;
11112 }
11113 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11114 }
11115
11116 /* Parse an objc-alias-declaration.
11117
11118 objc-alias-declaration:
11119 @compatibility_alias identifier identifier ;
11120 */
11121
11122 static void
11123 c_parser_objc_alias_declaration (c_parser *parser)
11124 {
11125 tree id1, id2;
11126 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_ALIAS));
11127 c_parser_consume_token (parser);
11128 if (c_parser_next_token_is_not (parser, CPP_NAME))
11129 {
11130 c_parser_error (parser, "expected identifier");
11131 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11132 return;
11133 }
11134 id1 = c_parser_peek_token (parser)->value;
11135 c_parser_consume_token (parser);
11136 if (c_parser_next_token_is_not (parser, CPP_NAME))
11137 {
11138 c_parser_error (parser, "expected identifier");
11139 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11140 return;
11141 }
11142 id2 = c_parser_peek_token (parser)->value;
11143 c_parser_consume_token (parser);
11144 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11145 objc_declare_alias (id1, id2);
11146 }
11147
11148 /* Parse an objc-protocol-definition.
11149
11150 objc-protocol-definition:
11151 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
11152 @protocol identifier-list ;
11153
11154 "@protocol identifier ;" should be resolved as "@protocol
11155 identifier-list ;": objc-methodprotolist may not start with a
11156 semicolon in the first alternative if objc-protocol-refs are
11157 omitted. */
11158
11159 static void
11160 c_parser_objc_protocol_definition (c_parser *parser, tree attributes)
11161 {
11162 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROTOCOL));
11163
11164 c_parser_consume_token (parser);
11165 if (c_parser_next_token_is_not (parser, CPP_NAME))
11166 {
11167 c_parser_error (parser, "expected identifier");
11168 return;
11169 }
11170 if (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
11171 || c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON)
11172 {
11173 /* Any identifiers, including those declared as type names, are
11174 OK here. */
11175 while (true)
11176 {
11177 tree id;
11178 if (c_parser_next_token_is_not (parser, CPP_NAME))
11179 {
11180 c_parser_error (parser, "expected identifier");
11181 break;
11182 }
11183 id = c_parser_peek_token (parser)->value;
11184 objc_declare_protocol (id, attributes);
11185 c_parser_consume_token (parser);
11186 if (c_parser_next_token_is (parser, CPP_COMMA))
11187 c_parser_consume_token (parser);
11188 else
11189 break;
11190 }
11191 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11192 }
11193 else
11194 {
11195 tree id = c_parser_peek_token (parser)->value;
11196 tree proto = NULL_TREE;
11197 c_parser_consume_token (parser);
11198 if (c_parser_next_token_is (parser, CPP_LESS))
11199 proto = c_parser_objc_protocol_refs (parser);
11200 parser->objc_pq_context = true;
11201 objc_start_protocol (id, proto, attributes);
11202 c_parser_objc_methodprotolist (parser);
11203 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
11204 parser->objc_pq_context = false;
11205 objc_finish_interface ();
11206 }
11207 }
11208
11209 /* Parse an objc-method-type.
11210
11211 objc-method-type:
11212 +
11213 -
11214
11215 Return true if it is a class method (+) and false if it is
11216 an instance method (-).
11217 */
11218 static inline bool
11219 c_parser_objc_method_type (c_parser *parser)
11220 {
11221 switch (c_parser_peek_token (parser)->type)
11222 {
11223 case CPP_PLUS:
11224 c_parser_consume_token (parser);
11225 return true;
11226 case CPP_MINUS:
11227 c_parser_consume_token (parser);
11228 return false;
11229 default:
11230 gcc_unreachable ();
11231 }
11232 }
11233
11234 /* Parse an objc-method-definition.
11235
11236 objc-method-definition:
11237 objc-method-type objc-method-decl ;[opt] compound-statement
11238 */
11239
11240 static void
11241 c_parser_objc_method_definition (c_parser *parser)
11242 {
11243 bool is_class_method = c_parser_objc_method_type (parser);
11244 tree decl, attributes = NULL_TREE, expr = NULL_TREE;
11245 parser->objc_pq_context = true;
11246 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
11247 &expr);
11248 if (decl == error_mark_node)
11249 return; /* Bail here. */
11250
11251 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
11252 {
11253 c_parser_consume_token (parser);
11254 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11255 "extra semicolon in method definition specified");
11256 }
11257
11258 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11259 {
11260 c_parser_error (parser, "expected %<{%>");
11261 return;
11262 }
11263
11264 parser->objc_pq_context = false;
11265 if (objc_start_method_definition (is_class_method, decl, attributes, expr))
11266 {
11267 add_stmt (c_parser_compound_statement (parser));
11268 objc_finish_method_definition (current_function_decl);
11269 }
11270 else
11271 {
11272 /* This code is executed when we find a method definition
11273 outside of an @implementation context (or invalid for other
11274 reasons). Parse the method (to keep going) but do not emit
11275 any code.
11276 */
11277 c_parser_compound_statement (parser);
11278 }
11279 }
11280
11281 /* Parse an objc-methodprotolist.
11282
11283 objc-methodprotolist:
11284 empty
11285 objc-methodprotolist objc-methodproto
11286 objc-methodprotolist declaration
11287 objc-methodprotolist ;
11288 @optional
11289 @required
11290
11291 The declaration is a data definition, which may be missing
11292 declaration specifiers under the same rules and diagnostics as
11293 other data definitions outside functions, and the stray semicolon
11294 is diagnosed the same way as a stray semicolon outside a
11295 function. */
11296
11297 static void
11298 c_parser_objc_methodprotolist (c_parser *parser)
11299 {
11300 while (true)
11301 {
11302 /* The list is terminated by @end. */
11303 switch (c_parser_peek_token (parser)->type)
11304 {
11305 case CPP_SEMICOLON:
11306 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
11307 "ISO C does not allow extra %<;%> outside of a function");
11308 c_parser_consume_token (parser);
11309 break;
11310 case CPP_PLUS:
11311 case CPP_MINUS:
11312 c_parser_objc_methodproto (parser);
11313 break;
11314 case CPP_PRAGMA:
11315 c_parser_pragma (parser, pragma_external, NULL);
11316 break;
11317 case CPP_EOF:
11318 return;
11319 default:
11320 if (c_parser_next_token_is_keyword (parser, RID_AT_END))
11321 return;
11322 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY))
11323 c_parser_objc_at_property_declaration (parser);
11324 else if (c_parser_next_token_is_keyword (parser, RID_AT_OPTIONAL))
11325 {
11326 objc_set_method_opt (true);
11327 c_parser_consume_token (parser);
11328 }
11329 else if (c_parser_next_token_is_keyword (parser, RID_AT_REQUIRED))
11330 {
11331 objc_set_method_opt (false);
11332 c_parser_consume_token (parser);
11333 }
11334 else
11335 c_parser_declaration_or_fndef (parser, false, false, true,
11336 false, true);
11337 break;
11338 }
11339 }
11340 }
11341
11342 /* Parse an objc-methodproto.
11343
11344 objc-methodproto:
11345 objc-method-type objc-method-decl ;
11346 */
11347
11348 static void
11349 c_parser_objc_methodproto (c_parser *parser)
11350 {
11351 bool is_class_method = c_parser_objc_method_type (parser);
11352 tree decl, attributes = NULL_TREE;
11353
11354 /* Remember protocol qualifiers in prototypes. */
11355 parser->objc_pq_context = true;
11356 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
11357 NULL);
11358 /* Forget protocol qualifiers now. */
11359 parser->objc_pq_context = false;
11360
11361 /* Do not allow the presence of attributes to hide an erroneous
11362 method implementation in the interface section. */
11363 if (!c_parser_next_token_is (parser, CPP_SEMICOLON))
11364 {
11365 c_parser_error (parser, "expected %<;%>");
11366 return;
11367 }
11368
11369 if (decl != error_mark_node)
11370 objc_add_method_declaration (is_class_method, decl, attributes);
11371
11372 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11373 }
11374
11375 /* If we are at a position that method attributes may be present, check that
11376 there are not any parsed already (a syntax error) and then collect any
11377 specified at the current location. Finally, if new attributes were present,
11378 check that the next token is legal ( ';' for decls and '{' for defs). */
11379
11380 static bool
11381 c_parser_objc_maybe_method_attributes (c_parser* parser, tree* attributes)
11382 {
11383 bool bad = false;
11384 if (*attributes)
11385 {
11386 c_parser_error (parser,
11387 "method attributes must be specified at the end only");
11388 *attributes = NULL_TREE;
11389 bad = true;
11390 }
11391
11392 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
11393 *attributes = c_parser_gnu_attributes (parser);
11394
11395 /* If there were no attributes here, just report any earlier error. */
11396 if (*attributes == NULL_TREE || bad)
11397 return bad;
11398
11399 /* If the attributes are followed by a ; or {, then just report any earlier
11400 error. */
11401 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
11402 || c_parser_next_token_is (parser, CPP_OPEN_BRACE))
11403 return bad;
11404
11405 /* We've got attributes, but not at the end. */
11406 c_parser_error (parser,
11407 "expected %<;%> or %<{%> after method attribute definition");
11408 return true;
11409 }
11410
11411 /* Parse an objc-method-decl.
11412
11413 objc-method-decl:
11414 ( objc-type-name ) objc-selector
11415 objc-selector
11416 ( objc-type-name ) objc-keyword-selector objc-optparmlist
11417 objc-keyword-selector objc-optparmlist
11418 gnu-attributes
11419
11420 objc-keyword-selector:
11421 objc-keyword-decl
11422 objc-keyword-selector objc-keyword-decl
11423
11424 objc-keyword-decl:
11425 objc-selector : ( objc-type-name ) identifier
11426 objc-selector : identifier
11427 : ( objc-type-name ) identifier
11428 : identifier
11429
11430 objc-optparmlist:
11431 objc-optparms objc-optellipsis
11432
11433 objc-optparms:
11434 empty
11435 objc-opt-parms , parameter-declaration
11436
11437 objc-optellipsis:
11438 empty
11439 , ...
11440 */
11441
11442 static tree
11443 c_parser_objc_method_decl (c_parser *parser, bool is_class_method,
11444 tree *attributes, tree *expr)
11445 {
11446 tree type = NULL_TREE;
11447 tree sel;
11448 tree parms = NULL_TREE;
11449 bool ellipsis = false;
11450 bool attr_err = false;
11451
11452 *attributes = NULL_TREE;
11453 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11454 {
11455 matching_parens parens;
11456 parens.consume_open (parser);
11457 type = c_parser_objc_type_name (parser);
11458 parens.skip_until_found_close (parser);
11459 }
11460 sel = c_parser_objc_selector (parser);
11461 /* If there is no selector, or a colon follows, we have an
11462 objc-keyword-selector. If there is a selector, and a colon does
11463 not follow, that selector ends the objc-method-decl. */
11464 if (!sel || c_parser_next_token_is (parser, CPP_COLON))
11465 {
11466 tree tsel = sel;
11467 tree list = NULL_TREE;
11468 while (true)
11469 {
11470 tree atype = NULL_TREE, id, keyworddecl;
11471 tree param_attr = NULL_TREE;
11472 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11473 break;
11474 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11475 {
11476 c_parser_consume_token (parser);
11477 atype = c_parser_objc_type_name (parser);
11478 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
11479 "expected %<)%>");
11480 }
11481 /* New ObjC allows attributes on method parameters. */
11482 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
11483 param_attr = c_parser_gnu_attributes (parser);
11484 if (c_parser_next_token_is_not (parser, CPP_NAME))
11485 {
11486 c_parser_error (parser, "expected identifier");
11487 return error_mark_node;
11488 }
11489 id = c_parser_peek_token (parser)->value;
11490 c_parser_consume_token (parser);
11491 keyworddecl = objc_build_keyword_decl (tsel, atype, id, param_attr);
11492 list = chainon (list, keyworddecl);
11493 tsel = c_parser_objc_selector (parser);
11494 if (!tsel && c_parser_next_token_is_not (parser, CPP_COLON))
11495 break;
11496 }
11497
11498 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
11499
11500 /* Parse the optional parameter list. Optional Objective-C
11501 method parameters follow the C syntax, and may include '...'
11502 to denote a variable number of arguments. */
11503 parms = make_node (TREE_LIST);
11504 while (c_parser_next_token_is (parser, CPP_COMMA))
11505 {
11506 struct c_parm *parm;
11507 c_parser_consume_token (parser);
11508 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
11509 {
11510 ellipsis = true;
11511 c_parser_consume_token (parser);
11512 attr_err |= c_parser_objc_maybe_method_attributes
11513 (parser, attributes) ;
11514 break;
11515 }
11516 parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
11517 if (parm == NULL)
11518 break;
11519 parms = chainon (parms,
11520 build_tree_list (NULL_TREE, grokparm (parm, expr)));
11521 }
11522 sel = list;
11523 }
11524 else
11525 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
11526
11527 if (sel == NULL)
11528 {
11529 c_parser_error (parser, "objective-c method declaration is expected");
11530 return error_mark_node;
11531 }
11532
11533 if (attr_err)
11534 return error_mark_node;
11535
11536 return objc_build_method_signature (is_class_method, type, sel, parms, ellipsis);
11537 }
11538
11539 /* Parse an objc-type-name.
11540
11541 objc-type-name:
11542 objc-type-qualifiers[opt] type-name
11543 objc-type-qualifiers[opt]
11544
11545 objc-type-qualifiers:
11546 objc-type-qualifier
11547 objc-type-qualifiers objc-type-qualifier
11548
11549 objc-type-qualifier: one of
11550 in out inout bycopy byref oneway
11551 */
11552
11553 static tree
11554 c_parser_objc_type_name (c_parser *parser)
11555 {
11556 tree quals = NULL_TREE;
11557 struct c_type_name *type_name = NULL;
11558 tree type = NULL_TREE;
11559 while (true)
11560 {
11561 c_token *token = c_parser_peek_token (parser);
11562 if (token->type == CPP_KEYWORD
11563 && (token->keyword == RID_IN
11564 || token->keyword == RID_OUT
11565 || token->keyword == RID_INOUT
11566 || token->keyword == RID_BYCOPY
11567 || token->keyword == RID_BYREF
11568 || token->keyword == RID_ONEWAY))
11569 {
11570 quals = chainon (build_tree_list (NULL_TREE, token->value), quals);
11571 c_parser_consume_token (parser);
11572 }
11573 else
11574 break;
11575 }
11576 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
11577 type_name = c_parser_type_name (parser);
11578 if (type_name)
11579 type = groktypename (type_name, NULL, NULL);
11580
11581 /* If the type is unknown, and error has already been produced and
11582 we need to recover from the error. In that case, use NULL_TREE
11583 for the type, as if no type had been specified; this will use the
11584 default type ('id') which is good for error recovery. */
11585 if (type == error_mark_node)
11586 type = NULL_TREE;
11587
11588 return build_tree_list (quals, type);
11589 }
11590
11591 /* Parse objc-protocol-refs.
11592
11593 objc-protocol-refs:
11594 < identifier-list >
11595 */
11596
11597 static tree
11598 c_parser_objc_protocol_refs (c_parser *parser)
11599 {
11600 tree list = NULL_TREE;
11601 gcc_assert (c_parser_next_token_is (parser, CPP_LESS));
11602 c_parser_consume_token (parser);
11603 /* Any identifiers, including those declared as type names, are OK
11604 here. */
11605 while (true)
11606 {
11607 tree id;
11608 if (c_parser_next_token_is_not (parser, CPP_NAME))
11609 {
11610 c_parser_error (parser, "expected identifier");
11611 break;
11612 }
11613 id = c_parser_peek_token (parser)->value;
11614 list = chainon (list, build_tree_list (NULL_TREE, id));
11615 c_parser_consume_token (parser);
11616 if (c_parser_next_token_is (parser, CPP_COMMA))
11617 c_parser_consume_token (parser);
11618 else
11619 break;
11620 }
11621 c_parser_require (parser, CPP_GREATER, "expected %<>%>");
11622 return list;
11623 }
11624
11625 /* Parse an objc-try-catch-finally-statement.
11626
11627 objc-try-catch-finally-statement:
11628 @try compound-statement objc-catch-list[opt]
11629 @try compound-statement objc-catch-list[opt] @finally compound-statement
11630
11631 objc-catch-list:
11632 @catch ( objc-catch-parameter-declaration ) compound-statement
11633 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
11634
11635 objc-catch-parameter-declaration:
11636 parameter-declaration
11637 '...'
11638
11639 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
11640
11641 PS: This function is identical to cp_parser_objc_try_catch_finally_statement
11642 for C++. Keep them in sync. */
11643
11644 static void
11645 c_parser_objc_try_catch_finally_statement (c_parser *parser)
11646 {
11647 location_t location;
11648 tree stmt;
11649
11650 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_TRY));
11651 c_parser_consume_token (parser);
11652 location = c_parser_peek_token (parser)->location;
11653 objc_maybe_warn_exceptions (location);
11654 stmt = c_parser_compound_statement (parser);
11655 objc_begin_try_stmt (location, stmt);
11656
11657 while (c_parser_next_token_is_keyword (parser, RID_AT_CATCH))
11658 {
11659 struct c_parm *parm;
11660 tree parameter_declaration = error_mark_node;
11661 bool seen_open_paren = false;
11662
11663 c_parser_consume_token (parser);
11664 matching_parens parens;
11665 if (!parens.require_open (parser))
11666 seen_open_paren = true;
11667 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
11668 {
11669 /* We have "@catch (...)" (where the '...' are literally
11670 what is in the code). Skip the '...'.
11671 parameter_declaration is set to NULL_TREE, and
11672 objc_being_catch_clauses() knows that that means
11673 '...'. */
11674 c_parser_consume_token (parser);
11675 parameter_declaration = NULL_TREE;
11676 }
11677 else
11678 {
11679 /* We have "@catch (NSException *exception)" or something
11680 like that. Parse the parameter declaration. */
11681 parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
11682 if (parm == NULL)
11683 parameter_declaration = error_mark_node;
11684 else
11685 parameter_declaration = grokparm (parm, NULL);
11686 }
11687 if (seen_open_paren)
11688 parens.require_close (parser);
11689 else
11690 {
11691 /* If there was no open parenthesis, we are recovering from
11692 an error, and we are trying to figure out what mistake
11693 the user has made. */
11694
11695 /* If there is an immediate closing parenthesis, the user
11696 probably forgot the opening one (ie, they typed "@catch
11697 NSException *e)". Parse the closing parenthesis and keep
11698 going. */
11699 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
11700 c_parser_consume_token (parser);
11701
11702 /* If these is no immediate closing parenthesis, the user
11703 probably doesn't know that parenthesis are required at
11704 all (ie, they typed "@catch NSException *e"). So, just
11705 forget about the closing parenthesis and keep going. */
11706 }
11707 objc_begin_catch_clause (parameter_declaration);
11708 if (c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
11709 c_parser_compound_statement_nostart (parser);
11710 objc_finish_catch_clause ();
11711 }
11712 if (c_parser_next_token_is_keyword (parser, RID_AT_FINALLY))
11713 {
11714 c_parser_consume_token (parser);
11715 location = c_parser_peek_token (parser)->location;
11716 stmt = c_parser_compound_statement (parser);
11717 objc_build_finally_clause (location, stmt);
11718 }
11719 objc_finish_try_stmt ();
11720 }
11721
11722 /* Parse an objc-synchronized-statement.
11723
11724 objc-synchronized-statement:
11725 @synchronized ( expression ) compound-statement
11726 */
11727
11728 static void
11729 c_parser_objc_synchronized_statement (c_parser *parser)
11730 {
11731 location_t loc;
11732 tree expr, stmt;
11733 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNCHRONIZED));
11734 c_parser_consume_token (parser);
11735 loc = c_parser_peek_token (parser)->location;
11736 objc_maybe_warn_exceptions (loc);
11737 matching_parens parens;
11738 if (parens.require_open (parser))
11739 {
11740 struct c_expr ce = c_parser_expression (parser);
11741 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
11742 expr = ce.value;
11743 expr = c_fully_fold (expr, false, NULL);
11744 parens.skip_until_found_close (parser);
11745 }
11746 else
11747 expr = error_mark_node;
11748 stmt = c_parser_compound_statement (parser);
11749 objc_build_synchronized (loc, expr, stmt);
11750 }
11751
11752 /* Parse an objc-selector; return NULL_TREE without an error if the
11753 next token is not an objc-selector.
11754
11755 objc-selector:
11756 identifier
11757 one of
11758 enum struct union if else while do for switch case default
11759 break continue return goto asm sizeof typeof __alignof
11760 unsigned long const short volatile signed restrict _Complex
11761 in out inout bycopy byref oneway int char float double void _Bool
11762 _Atomic
11763
11764 ??? Why this selection of keywords but not, for example, storage
11765 class specifiers? */
11766
11767 static tree
11768 c_parser_objc_selector (c_parser *parser)
11769 {
11770 c_token *token = c_parser_peek_token (parser);
11771 tree value = token->value;
11772 if (token->type == CPP_NAME)
11773 {
11774 c_parser_consume_token (parser);
11775 return value;
11776 }
11777 if (token->type != CPP_KEYWORD)
11778 return NULL_TREE;
11779 switch (token->keyword)
11780 {
11781 case RID_ENUM:
11782 case RID_STRUCT:
11783 case RID_UNION:
11784 case RID_IF:
11785 case RID_ELSE:
11786 case RID_WHILE:
11787 case RID_DO:
11788 case RID_FOR:
11789 case RID_SWITCH:
11790 case RID_CASE:
11791 case RID_DEFAULT:
11792 case RID_BREAK:
11793 case RID_CONTINUE:
11794 case RID_RETURN:
11795 case RID_GOTO:
11796 case RID_ASM:
11797 case RID_SIZEOF:
11798 case RID_TYPEOF:
11799 case RID_ALIGNOF:
11800 case RID_UNSIGNED:
11801 case RID_LONG:
11802 case RID_CONST:
11803 case RID_SHORT:
11804 case RID_VOLATILE:
11805 case RID_SIGNED:
11806 case RID_RESTRICT:
11807 case RID_COMPLEX:
11808 case RID_IN:
11809 case RID_OUT:
11810 case RID_INOUT:
11811 case RID_BYCOPY:
11812 case RID_BYREF:
11813 case RID_ONEWAY:
11814 case RID_INT:
11815 case RID_CHAR:
11816 case RID_FLOAT:
11817 case RID_DOUBLE:
11818 CASE_RID_FLOATN_NX:
11819 case RID_VOID:
11820 case RID_BOOL:
11821 case RID_ATOMIC:
11822 case RID_AUTO_TYPE:
11823 case RID_INT_N_0:
11824 case RID_INT_N_1:
11825 case RID_INT_N_2:
11826 case RID_INT_N_3:
11827 c_parser_consume_token (parser);
11828 return value;
11829 default:
11830 return NULL_TREE;
11831 }
11832 }
11833
11834 /* Parse an objc-selector-arg.
11835
11836 objc-selector-arg:
11837 objc-selector
11838 objc-keywordname-list
11839
11840 objc-keywordname-list:
11841 objc-keywordname
11842 objc-keywordname-list objc-keywordname
11843
11844 objc-keywordname:
11845 objc-selector :
11846 :
11847 */
11848
11849 static tree
11850 c_parser_objc_selector_arg (c_parser *parser)
11851 {
11852 tree sel = c_parser_objc_selector (parser);
11853 tree list = NULL_TREE;
11854 if (sel
11855 && c_parser_next_token_is_not (parser, CPP_COLON)
11856 && c_parser_next_token_is_not (parser, CPP_SCOPE))
11857 return sel;
11858 while (true)
11859 {
11860 if (c_parser_next_token_is (parser, CPP_SCOPE))
11861 {
11862 c_parser_consume_token (parser);
11863 list = chainon (list, build_tree_list (sel, NULL_TREE));
11864 list = chainon (list, build_tree_list (NULL_TREE, NULL_TREE));
11865 }
11866 else
11867 {
11868 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11869 return list;
11870 list = chainon (list, build_tree_list (sel, NULL_TREE));
11871 }
11872 sel = c_parser_objc_selector (parser);
11873 if (!sel
11874 && c_parser_next_token_is_not (parser, CPP_COLON)
11875 && c_parser_next_token_is_not (parser, CPP_SCOPE))
11876 break;
11877 }
11878 return list;
11879 }
11880
11881 /* Parse an objc-receiver.
11882
11883 objc-receiver:
11884 expression
11885 class-name
11886 type-name
11887 */
11888
11889 static tree
11890 c_parser_objc_receiver (c_parser *parser)
11891 {
11892 location_t loc = c_parser_peek_token (parser)->location;
11893
11894 if (c_parser_peek_token (parser)->type == CPP_NAME
11895 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
11896 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
11897 {
11898 tree id = c_parser_peek_token (parser)->value;
11899 c_parser_consume_token (parser);
11900 return objc_get_class_reference (id);
11901 }
11902 struct c_expr ce = c_parser_expression (parser);
11903 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
11904 return c_fully_fold (ce.value, false, NULL);
11905 }
11906
11907 /* Parse objc-message-args.
11908
11909 objc-message-args:
11910 objc-selector
11911 objc-keywordarg-list
11912
11913 objc-keywordarg-list:
11914 objc-keywordarg
11915 objc-keywordarg-list objc-keywordarg
11916
11917 objc-keywordarg:
11918 objc-selector : objc-keywordexpr
11919 : objc-keywordexpr
11920 */
11921
11922 static tree
11923 c_parser_objc_message_args (c_parser *parser)
11924 {
11925 tree sel = c_parser_objc_selector (parser);
11926 tree list = NULL_TREE;
11927 if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
11928 return sel;
11929 while (true)
11930 {
11931 tree keywordexpr;
11932 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11933 return error_mark_node;
11934 keywordexpr = c_parser_objc_keywordexpr (parser);
11935 list = chainon (list, build_tree_list (sel, keywordexpr));
11936 sel = c_parser_objc_selector (parser);
11937 if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
11938 break;
11939 }
11940 return list;
11941 }
11942
11943 /* Parse an objc-keywordexpr.
11944
11945 objc-keywordexpr:
11946 nonempty-expr-list
11947 */
11948
11949 static tree
11950 c_parser_objc_keywordexpr (c_parser *parser)
11951 {
11952 tree ret;
11953 vec<tree, va_gc> *expr_list = c_parser_expr_list (parser, true, true,
11954 NULL, NULL, NULL, NULL);
11955 if (vec_safe_length (expr_list) == 1)
11956 {
11957 /* Just return the expression, remove a level of
11958 indirection. */
11959 ret = (*expr_list)[0];
11960 }
11961 else
11962 {
11963 /* We have a comma expression, we will collapse later. */
11964 ret = build_tree_list_vec (expr_list);
11965 }
11966 release_tree_vector (expr_list);
11967 return ret;
11968 }
11969
11970 /* A check, needed in several places, that ObjC interface, implementation or
11971 method definitions are not prefixed by incorrect items. */
11972 static bool
11973 c_parser_objc_diagnose_bad_element_prefix (c_parser *parser,
11974 struct c_declspecs *specs)
11975 {
11976 if (!specs->declspecs_seen_p || specs->non_sc_seen_p
11977 || specs->typespec_kind != ctsk_none)
11978 {
11979 c_parser_error (parser,
11980 "no type or storage class may be specified here,");
11981 c_parser_skip_to_end_of_block_or_statement (parser);
11982 return true;
11983 }
11984 return false;
11985 }
11986
11987 /* Parse an Objective-C @property declaration. The syntax is:
11988
11989 objc-property-declaration:
11990 '@property' objc-property-attributes[opt] struct-declaration ;
11991
11992 objc-property-attributes:
11993 '(' objc-property-attribute-list ')'
11994
11995 objc-property-attribute-list:
11996 objc-property-attribute
11997 objc-property-attribute-list, objc-property-attribute
11998
11999 objc-property-attribute
12000 'getter' = identifier
12001 'setter' = identifier
12002 'readonly'
12003 'readwrite'
12004 'assign'
12005 'retain'
12006 'copy'
12007 'nonatomic'
12008
12009 For example:
12010 @property NSString *name;
12011 @property (readonly) id object;
12012 @property (retain, nonatomic, getter=getTheName) id name;
12013 @property int a, b, c;
12014
12015 PS: This function is identical to cp_parser_objc_at_propery_declaration
12016 for C++. Keep them in sync. */
12017 static void
12018 c_parser_objc_at_property_declaration (c_parser *parser)
12019 {
12020 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY));
12021 location_t loc = c_parser_peek_token (parser)->location;
12022 c_parser_consume_token (parser); /* Eat '@property'. */
12023
12024 /* Parse the optional attribute list.
12025
12026 A list of parsed, but not verified, attributes. */
12027 vec<property_attribute_info *> prop_attr_list = vNULL;
12028
12029 bool syntax_error = false;
12030 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
12031 {
12032 matching_parens parens;
12033
12034 location_t attr_start = c_parser_peek_token (parser)->location;
12035 /* Eat the '(' */
12036 parens.consume_open (parser);
12037
12038 /* Property attribute keywords are valid now. */
12039 parser->objc_property_attr_context = true;
12040
12041 /* Allow @property (), with a warning. */
12042 location_t attr_end = c_parser_peek_token (parser)->location;
12043
12044 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
12045 {
12046 location_t attr_comb = make_location (attr_end, attr_start, attr_end);
12047 warning_at (attr_comb, OPT_Wattributes,
12048 "empty property attribute list");
12049 }
12050 else
12051 while (true)
12052 {
12053 c_token *token = c_parser_peek_token (parser);
12054 attr_start = token->location;
12055 attr_end = get_finish (token->location);
12056 location_t attr_comb = make_location (attr_start, attr_start,
12057 attr_end);
12058
12059 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_COMMA)
12060 {
12061 warning_at (attr_comb, OPT_Wattributes,
12062 "missing property attribute");
12063 if (token->type == CPP_CLOSE_PAREN)
12064 break;
12065 c_parser_consume_token (parser);
12066 continue;
12067 }
12068
12069 tree attr_name = NULL_TREE;
12070 enum rid keyword = RID_MAX; /* Not a valid property attribute. */
12071 bool add_at = false;
12072 if (token->type == CPP_KEYWORD)
12073 {
12074 keyword = token->keyword;
12075 if (OBJC_IS_AT_KEYWORD (keyword))
12076 {
12077 /* For '@' keywords the token value has the keyword,
12078 prepend the '@' for diagnostics. */
12079 attr_name = token->value;
12080 add_at = true;
12081 }
12082 else
12083 attr_name = ridpointers[(int)keyword];
12084 }
12085 else if (token->type == CPP_NAME)
12086 attr_name = token->value;
12087 c_parser_consume_token (parser);
12088
12089 enum objc_property_attribute_kind prop_kind
12090 = objc_prop_attr_kind_for_rid (keyword);
12091 property_attribute_info *prop
12092 = new property_attribute_info (attr_name, attr_comb, prop_kind);
12093 prop_attr_list.safe_push (prop);
12094
12095 tree meth_name;
12096 switch (prop->prop_kind)
12097 {
12098 default: break;
12099 case OBJC_PROPERTY_ATTR_UNKNOWN:
12100 if (attr_name)
12101 error_at (attr_comb, "unknown property attribute %<%s%s%>",
12102 add_at ? "@" : "", IDENTIFIER_POINTER (attr_name));
12103 else
12104 error_at (attr_comb, "unknown property attribute");
12105 prop->parse_error = syntax_error = true;
12106 break;
12107
12108 case OBJC_PROPERTY_ATTR_GETTER:
12109 case OBJC_PROPERTY_ATTR_SETTER:
12110 if (c_parser_next_token_is_not (parser, CPP_EQ))
12111 {
12112 attr_comb = make_location (attr_end, attr_start, attr_end);
12113 error_at (attr_comb, "expected %<=%> after Objective-C %qE",
12114 attr_name);
12115 prop->parse_error = syntax_error = true;
12116 break;
12117 }
12118 token = c_parser_peek_token (parser);
12119 attr_end = token->location;
12120 c_parser_consume_token (parser); /* eat the = */
12121 if (c_parser_next_token_is_not (parser, CPP_NAME))
12122 {
12123 attr_comb = make_location (attr_end, attr_start, attr_end);
12124 error_at (attr_comb, "expected %qE selector name",
12125 attr_name);
12126 prop->parse_error = syntax_error = true;
12127 break;
12128 }
12129 /* Get the end of the method name, and consume the name. */
12130 token = c_parser_peek_token (parser);
12131 attr_end = get_finish (token->location);
12132 meth_name = token->value;
12133 c_parser_consume_token (parser);
12134 if (prop->prop_kind == OBJC_PROPERTY_ATTR_SETTER)
12135 {
12136 if (c_parser_next_token_is_not (parser, CPP_COLON))
12137 {
12138 attr_comb = make_location (attr_end, attr_start,
12139 attr_end);
12140 error_at (attr_comb, "setter method names must"
12141 " terminate with %<:%>");
12142 prop->parse_error = syntax_error = true;
12143 }
12144 else
12145 {
12146 attr_end = get_finish (c_parser_peek_token
12147 (parser)->location);
12148 c_parser_consume_token (parser);
12149 }
12150 attr_comb = make_location (attr_start, attr_start,
12151 attr_end);
12152 }
12153 else
12154 attr_comb = make_location (attr_start, attr_start,
12155 attr_end);
12156 prop->ident = meth_name;
12157 /* Updated location including all that was successfully
12158 parsed. */
12159 prop->prop_loc = attr_comb;
12160 break;
12161 }
12162
12163 /* If we see a comma here, then keep going - even if we already
12164 saw a syntax error. For simple mistakes e.g. (asign, getter=x)
12165 this makes a more useful output and avoid spurious warnings about
12166 missing attributes that are, in fact, specified after the one with
12167 the syntax error. */
12168 if (c_parser_next_token_is (parser, CPP_COMMA))
12169 c_parser_consume_token (parser);
12170 else
12171 break;
12172 }
12173 parser->objc_property_attr_context = false;
12174
12175 if (syntax_error && c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
12176 /* We don't really want to chew the whole of the file looking for a
12177 matching closing parenthesis, so we will try to read the decl and
12178 let the error handling for that close out the statement. */
12179 ;
12180 else
12181 syntax_error = false, parens.skip_until_found_close (parser);
12182 }
12183
12184 /* 'properties' is the list of properties that we read. Usually a
12185 single one, but maybe more (eg, in "@property int a, b, c;" there
12186 are three). */
12187 tree properties = c_parser_struct_declaration (parser);
12188
12189 if (properties == error_mark_node)
12190 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12191 else
12192 {
12193 if (properties == NULL_TREE)
12194 c_parser_error (parser, "expected identifier");
12195 else
12196 {
12197 /* Comma-separated properties are chained together in reverse order;
12198 add them one by one. */
12199 properties = nreverse (properties);
12200 for (; properties; properties = TREE_CHAIN (properties))
12201 objc_add_property_declaration (loc, copy_node (properties),
12202 prop_attr_list);
12203 }
12204 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12205 }
12206
12207 while (!prop_attr_list.is_empty())
12208 delete prop_attr_list.pop ();
12209 prop_attr_list.release ();
12210 parser->error = false;
12211 }
12212
12213 /* Parse an Objective-C @synthesize declaration. The syntax is:
12214
12215 objc-synthesize-declaration:
12216 @synthesize objc-synthesize-identifier-list ;
12217
12218 objc-synthesize-identifier-list:
12219 objc-synthesize-identifier
12220 objc-synthesize-identifier-list, objc-synthesize-identifier
12221
12222 objc-synthesize-identifier
12223 identifier
12224 identifier = identifier
12225
12226 For example:
12227 @synthesize MyProperty;
12228 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
12229
12230 PS: This function is identical to cp_parser_objc_at_synthesize_declaration
12231 for C++. Keep them in sync.
12232 */
12233 static void
12234 c_parser_objc_at_synthesize_declaration (c_parser *parser)
12235 {
12236 tree list = NULL_TREE;
12237 location_t loc;
12238 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNTHESIZE));
12239 loc = c_parser_peek_token (parser)->location;
12240
12241 c_parser_consume_token (parser);
12242 while (true)
12243 {
12244 tree property, ivar;
12245 if (c_parser_next_token_is_not (parser, CPP_NAME))
12246 {
12247 c_parser_error (parser, "expected identifier");
12248 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12249 /* Once we find the semicolon, we can resume normal parsing.
12250 We have to reset parser->error manually because
12251 c_parser_skip_until_found() won't reset it for us if the
12252 next token is precisely a semicolon. */
12253 parser->error = false;
12254 return;
12255 }
12256 property = c_parser_peek_token (parser)->value;
12257 c_parser_consume_token (parser);
12258 if (c_parser_next_token_is (parser, CPP_EQ))
12259 {
12260 c_parser_consume_token (parser);
12261 if (c_parser_next_token_is_not (parser, CPP_NAME))
12262 {
12263 c_parser_error (parser, "expected identifier");
12264 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12265 parser->error = false;
12266 return;
12267 }
12268 ivar = c_parser_peek_token (parser)->value;
12269 c_parser_consume_token (parser);
12270 }
12271 else
12272 ivar = NULL_TREE;
12273 list = chainon (list, build_tree_list (ivar, property));
12274 if (c_parser_next_token_is (parser, CPP_COMMA))
12275 c_parser_consume_token (parser);
12276 else
12277 break;
12278 }
12279 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12280 objc_add_synthesize_declaration (loc, list);
12281 }
12282
12283 /* Parse an Objective-C @dynamic declaration. The syntax is:
12284
12285 objc-dynamic-declaration:
12286 @dynamic identifier-list ;
12287
12288 For example:
12289 @dynamic MyProperty;
12290 @dynamic MyProperty, AnotherProperty;
12291
12292 PS: This function is identical to cp_parser_objc_at_dynamic_declaration
12293 for C++. Keep them in sync.
12294 */
12295 static void
12296 c_parser_objc_at_dynamic_declaration (c_parser *parser)
12297 {
12298 tree list = NULL_TREE;
12299 location_t loc;
12300 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_DYNAMIC));
12301 loc = c_parser_peek_token (parser)->location;
12302
12303 c_parser_consume_token (parser);
12304 while (true)
12305 {
12306 tree property;
12307 if (c_parser_next_token_is_not (parser, CPP_NAME))
12308 {
12309 c_parser_error (parser, "expected identifier");
12310 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
12311 parser->error = false;
12312 return;
12313 }
12314 property = c_parser_peek_token (parser)->value;
12315 list = chainon (list, build_tree_list (NULL_TREE, property));
12316 c_parser_consume_token (parser);
12317 if (c_parser_next_token_is (parser, CPP_COMMA))
12318 c_parser_consume_token (parser);
12319 else
12320 break;
12321 }
12322 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
12323 objc_add_dynamic_declaration (loc, list);
12324 }
12325
12326 \f
12327 /* Parse a pragma GCC ivdep. */
12328
12329 static bool
12330 c_parse_pragma_ivdep (c_parser *parser)
12331 {
12332 c_parser_consume_pragma (parser);
12333 c_parser_skip_to_pragma_eol (parser);
12334 return true;
12335 }
12336
12337 /* Parse a pragma GCC unroll. */
12338
12339 static unsigned short
12340 c_parser_pragma_unroll (c_parser *parser)
12341 {
12342 unsigned short unroll;
12343 c_parser_consume_pragma (parser);
12344 location_t location = c_parser_peek_token (parser)->location;
12345 tree expr = c_parser_expr_no_commas (parser, NULL).value;
12346 mark_exp_read (expr);
12347 expr = c_fully_fold (expr, false, NULL);
12348 HOST_WIDE_INT lunroll = 0;
12349 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
12350 || TREE_CODE (expr) != INTEGER_CST
12351 || (lunroll = tree_to_shwi (expr)) < 0
12352 || lunroll >= USHRT_MAX)
12353 {
12354 error_at (location, "%<#pragma GCC unroll%> requires an"
12355 " assignment-expression that evaluates to a non-negative"
12356 " integral constant less than %u", USHRT_MAX);
12357 unroll = 0;
12358 }
12359 else
12360 {
12361 unroll = (unsigned short)lunroll;
12362 if (unroll == 0)
12363 unroll = 1;
12364 }
12365
12366 c_parser_skip_to_pragma_eol (parser);
12367 return unroll;
12368 }
12369
12370 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
12371 should be considered, statements. ALLOW_STMT is true if we're within
12372 the context of a function and such pragmas are to be allowed. Returns
12373 true if we actually parsed such a pragma. */
12374
12375 static bool
12376 c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p)
12377 {
12378 unsigned int id;
12379 const char *construct = NULL;
12380
12381 input_location = c_parser_peek_token (parser)->location;
12382 id = c_parser_peek_token (parser)->pragma_kind;
12383 gcc_assert (id != PRAGMA_NONE);
12384
12385 switch (id)
12386 {
12387 case PRAGMA_OACC_DECLARE:
12388 c_parser_oacc_declare (parser);
12389 return false;
12390
12391 case PRAGMA_OACC_ENTER_DATA:
12392 if (context != pragma_compound)
12393 {
12394 construct = "acc enter data";
12395 in_compound:
12396 if (context == pragma_stmt)
12397 {
12398 error_at (c_parser_peek_token (parser)->location,
12399 "%<#pragma %s%> may only be used in compound "
12400 "statements", construct);
12401 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12402 return true;
12403 }
12404 goto bad_stmt;
12405 }
12406 c_parser_oacc_enter_exit_data (parser, true);
12407 return false;
12408
12409 case PRAGMA_OACC_EXIT_DATA:
12410 if (context != pragma_compound)
12411 {
12412 construct = "acc exit data";
12413 goto in_compound;
12414 }
12415 c_parser_oacc_enter_exit_data (parser, false);
12416 return false;
12417
12418 case PRAGMA_OACC_ROUTINE:
12419 if (context != pragma_external)
12420 {
12421 error_at (c_parser_peek_token (parser)->location,
12422 "%<#pragma acc routine%> must be at file scope");
12423 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12424 return false;
12425 }
12426 c_parser_oacc_routine (parser, context);
12427 return false;
12428
12429 case PRAGMA_OACC_UPDATE:
12430 if (context != pragma_compound)
12431 {
12432 construct = "acc update";
12433 goto in_compound;
12434 }
12435 c_parser_oacc_update (parser);
12436 return false;
12437
12438 case PRAGMA_OMP_BARRIER:
12439 if (context != pragma_compound)
12440 {
12441 construct = "omp barrier";
12442 goto in_compound;
12443 }
12444 c_parser_omp_barrier (parser);
12445 return false;
12446
12447 case PRAGMA_OMP_DEPOBJ:
12448 if (context != pragma_compound)
12449 {
12450 construct = "omp depobj";
12451 goto in_compound;
12452 }
12453 c_parser_omp_depobj (parser);
12454 return false;
12455
12456 case PRAGMA_OMP_FLUSH:
12457 if (context != pragma_compound)
12458 {
12459 construct = "omp flush";
12460 goto in_compound;
12461 }
12462 c_parser_omp_flush (parser);
12463 return false;
12464
12465 case PRAGMA_OMP_TASKWAIT:
12466 if (context != pragma_compound)
12467 {
12468 construct = "omp taskwait";
12469 goto in_compound;
12470 }
12471 c_parser_omp_taskwait (parser);
12472 return false;
12473
12474 case PRAGMA_OMP_TASKYIELD:
12475 if (context != pragma_compound)
12476 {
12477 construct = "omp taskyield";
12478 goto in_compound;
12479 }
12480 c_parser_omp_taskyield (parser);
12481 return false;
12482
12483 case PRAGMA_OMP_CANCEL:
12484 if (context != pragma_compound)
12485 {
12486 construct = "omp cancel";
12487 goto in_compound;
12488 }
12489 c_parser_omp_cancel (parser);
12490 return false;
12491
12492 case PRAGMA_OMP_CANCELLATION_POINT:
12493 return c_parser_omp_cancellation_point (parser, context);
12494
12495 case PRAGMA_OMP_THREADPRIVATE:
12496 c_parser_omp_threadprivate (parser);
12497 return false;
12498
12499 case PRAGMA_OMP_TARGET:
12500 return c_parser_omp_target (parser, context, if_p);
12501
12502 case PRAGMA_OMP_END_DECLARE_TARGET:
12503 c_parser_omp_end_declare_target (parser);
12504 return false;
12505
12506 case PRAGMA_OMP_SCAN:
12507 error_at (c_parser_peek_token (parser)->location,
12508 "%<#pragma omp scan%> may only be used in "
12509 "a loop construct with %<inscan%> %<reduction%> clause");
12510 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12511 return false;
12512
12513 case PRAGMA_OMP_SECTION:
12514 error_at (c_parser_peek_token (parser)->location,
12515 "%<#pragma omp section%> may only be used in "
12516 "%<#pragma omp sections%> construct");
12517 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12518 return false;
12519
12520 case PRAGMA_OMP_DECLARE:
12521 return c_parser_omp_declare (parser, context);
12522
12523 case PRAGMA_OMP_REQUIRES:
12524 if (context != pragma_external)
12525 {
12526 error_at (c_parser_peek_token (parser)->location,
12527 "%<#pragma omp requires%> may only be used at file scope");
12528 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12529 return false;
12530 }
12531 c_parser_omp_requires (parser);
12532 return false;
12533
12534 case PRAGMA_OMP_NOTHING:
12535 c_parser_omp_nothing (parser);
12536 return false;
12537
12538 case PRAGMA_OMP_ERROR:
12539 return c_parser_omp_error (parser, context);
12540
12541 case PRAGMA_OMP_ORDERED:
12542 return c_parser_omp_ordered (parser, context, if_p);
12543
12544 case PRAGMA_IVDEP:
12545 {
12546 const bool ivdep = c_parse_pragma_ivdep (parser);
12547 unsigned short unroll;
12548 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_UNROLL)
12549 unroll = c_parser_pragma_unroll (parser);
12550 else
12551 unroll = 0;
12552 if (!c_parser_next_token_is_keyword (parser, RID_FOR)
12553 && !c_parser_next_token_is_keyword (parser, RID_WHILE)
12554 && !c_parser_next_token_is_keyword (parser, RID_DO))
12555 {
12556 c_parser_error (parser, "for, while or do statement expected");
12557 return false;
12558 }
12559 if (c_parser_next_token_is_keyword (parser, RID_FOR))
12560 c_parser_for_statement (parser, ivdep, unroll, if_p);
12561 else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
12562 c_parser_while_statement (parser, ivdep, unroll, if_p);
12563 else
12564 c_parser_do_statement (parser, ivdep, unroll);
12565 }
12566 return true;
12567
12568 case PRAGMA_UNROLL:
12569 {
12570 unsigned short unroll = c_parser_pragma_unroll (parser);
12571 bool ivdep;
12572 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_IVDEP)
12573 ivdep = c_parse_pragma_ivdep (parser);
12574 else
12575 ivdep = false;
12576 if (!c_parser_next_token_is_keyword (parser, RID_FOR)
12577 && !c_parser_next_token_is_keyword (parser, RID_WHILE)
12578 && !c_parser_next_token_is_keyword (parser, RID_DO))
12579 {
12580 c_parser_error (parser, "for, while or do statement expected");
12581 return false;
12582 }
12583 if (c_parser_next_token_is_keyword (parser, RID_FOR))
12584 c_parser_for_statement (parser, ivdep, unroll, if_p);
12585 else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
12586 c_parser_while_statement (parser, ivdep, unroll, if_p);
12587 else
12588 c_parser_do_statement (parser, ivdep, unroll);
12589 }
12590 return true;
12591
12592 case PRAGMA_GCC_PCH_PREPROCESS:
12593 c_parser_error (parser, "%<#pragma GCC pch_preprocess%> must be first");
12594 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12595 return false;
12596
12597 case PRAGMA_OACC_WAIT:
12598 if (context != pragma_compound)
12599 {
12600 construct = "acc wait";
12601 goto in_compound;
12602 }
12603 /* FALL THROUGH. */
12604
12605 default:
12606 if (id < PRAGMA_FIRST_EXTERNAL)
12607 {
12608 if (context != pragma_stmt && context != pragma_compound)
12609 {
12610 bad_stmt:
12611 c_parser_error (parser, "expected declaration specifiers");
12612 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
12613 return false;
12614 }
12615 c_parser_omp_construct (parser, if_p);
12616 return true;
12617 }
12618 break;
12619 }
12620
12621 c_parser_consume_pragma (parser);
12622 c_invoke_pragma_handler (id);
12623
12624 /* Skip to EOL, but suppress any error message. Those will have been
12625 generated by the handler routine through calling error, as opposed
12626 to calling c_parser_error. */
12627 parser->error = true;
12628 c_parser_skip_to_pragma_eol (parser);
12629
12630 return false;
12631 }
12632
12633 /* The interface the pragma parsers have to the lexer. */
12634
12635 enum cpp_ttype
12636 pragma_lex (tree *value, location_t *loc)
12637 {
12638 c_token *tok = c_parser_peek_token (the_parser);
12639 enum cpp_ttype ret = tok->type;
12640
12641 *value = tok->value;
12642 if (loc)
12643 *loc = tok->location;
12644
12645 if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF)
12646 ret = CPP_EOF;
12647 else if (ret == CPP_STRING)
12648 *value = c_parser_string_literal (the_parser, false, false).value;
12649 else
12650 {
12651 if (ret == CPP_KEYWORD)
12652 ret = CPP_NAME;
12653 c_parser_consume_token (the_parser);
12654 }
12655
12656 return ret;
12657 }
12658
12659 static void
12660 c_parser_pragma_pch_preprocess (c_parser *parser)
12661 {
12662 tree name = NULL;
12663
12664 parser->lex_joined_string = true;
12665 c_parser_consume_pragma (parser);
12666 if (c_parser_next_token_is (parser, CPP_STRING))
12667 {
12668 name = c_parser_peek_token (parser)->value;
12669 c_parser_consume_token (parser);
12670 }
12671 else
12672 c_parser_error (parser, "expected string literal");
12673 c_parser_skip_to_pragma_eol (parser);
12674 parser->lex_joined_string = false;
12675
12676 if (name)
12677 c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name));
12678 }
12679 \f
12680 /* OpenACC and OpenMP parsing routines. */
12681
12682 /* Returns name of the next clause.
12683 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
12684 the token is not consumed. Otherwise appropriate pragma_omp_clause is
12685 returned and the token is consumed. */
12686
12687 static pragma_omp_clause
12688 c_parser_omp_clause_name (c_parser *parser)
12689 {
12690 pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;
12691
12692 if (c_parser_next_token_is_keyword (parser, RID_AUTO))
12693 result = PRAGMA_OACC_CLAUSE_AUTO;
12694 else if (c_parser_next_token_is_keyword (parser, RID_IF))
12695 result = PRAGMA_OMP_CLAUSE_IF;
12696 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
12697 result = PRAGMA_OMP_CLAUSE_DEFAULT;
12698 else if (c_parser_next_token_is_keyword (parser, RID_FOR))
12699 result = PRAGMA_OMP_CLAUSE_FOR;
12700 else if (c_parser_next_token_is (parser, CPP_NAME))
12701 {
12702 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
12703
12704 switch (p[0])
12705 {
12706 case 'a':
12707 if (!strcmp ("affinity", p))
12708 result = PRAGMA_OMP_CLAUSE_AFFINITY;
12709 else if (!strcmp ("aligned", p))
12710 result = PRAGMA_OMP_CLAUSE_ALIGNED;
12711 else if (!strcmp ("allocate", p))
12712 result = PRAGMA_OMP_CLAUSE_ALLOCATE;
12713 else if (!strcmp ("async", p))
12714 result = PRAGMA_OACC_CLAUSE_ASYNC;
12715 else if (!strcmp ("attach", p))
12716 result = PRAGMA_OACC_CLAUSE_ATTACH;
12717 break;
12718 case 'b':
12719 if (!strcmp ("bind", p))
12720 result = PRAGMA_OMP_CLAUSE_BIND;
12721 break;
12722 case 'c':
12723 if (!strcmp ("collapse", p))
12724 result = PRAGMA_OMP_CLAUSE_COLLAPSE;
12725 else if (!strcmp ("copy", p))
12726 result = PRAGMA_OACC_CLAUSE_COPY;
12727 else if (!strcmp ("copyin", p))
12728 result = PRAGMA_OMP_CLAUSE_COPYIN;
12729 else if (!strcmp ("copyout", p))
12730 result = PRAGMA_OACC_CLAUSE_COPYOUT;
12731 else if (!strcmp ("copyprivate", p))
12732 result = PRAGMA_OMP_CLAUSE_COPYPRIVATE;
12733 else if (!strcmp ("create", p))
12734 result = PRAGMA_OACC_CLAUSE_CREATE;
12735 break;
12736 case 'd':
12737 if (!strcmp ("defaultmap", p))
12738 result = PRAGMA_OMP_CLAUSE_DEFAULTMAP;
12739 else if (!strcmp ("delete", p))
12740 result = PRAGMA_OACC_CLAUSE_DELETE;
12741 else if (!strcmp ("depend", p))
12742 result = PRAGMA_OMP_CLAUSE_DEPEND;
12743 else if (!strcmp ("detach", p))
12744 result = PRAGMA_OACC_CLAUSE_DETACH;
12745 else if (!strcmp ("device", p))
12746 result = PRAGMA_OMP_CLAUSE_DEVICE;
12747 else if (!strcmp ("deviceptr", p))
12748 result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
12749 else if (!strcmp ("device_resident", p))
12750 result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
12751 else if (!strcmp ("device_type", p))
12752 result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
12753 else if (!strcmp ("dist_schedule", p))
12754 result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
12755 break;
12756 case 'f':
12757 if (!strcmp ("filter", p))
12758 result = PRAGMA_OMP_CLAUSE_FILTER;
12759 else if (!strcmp ("final", p))
12760 result = PRAGMA_OMP_CLAUSE_FINAL;
12761 else if (!strcmp ("finalize", p))
12762 result = PRAGMA_OACC_CLAUSE_FINALIZE;
12763 else if (!strcmp ("firstprivate", p))
12764 result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
12765 else if (!strcmp ("from", p))
12766 result = PRAGMA_OMP_CLAUSE_FROM;
12767 break;
12768 case 'g':
12769 if (!strcmp ("gang", p))
12770 result = PRAGMA_OACC_CLAUSE_GANG;
12771 else if (!strcmp ("grainsize", p))
12772 result = PRAGMA_OMP_CLAUSE_GRAINSIZE;
12773 break;
12774 case 'h':
12775 if (!strcmp ("has_device_addr", p))
12776 result = PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR;
12777 else if (!strcmp ("hint", p))
12778 result = PRAGMA_OMP_CLAUSE_HINT;
12779 else if (!strcmp ("host", p))
12780 result = PRAGMA_OACC_CLAUSE_HOST;
12781 break;
12782 case 'i':
12783 if (!strcmp ("if_present", p))
12784 result = PRAGMA_OACC_CLAUSE_IF_PRESENT;
12785 else if (!strcmp ("in_reduction", p))
12786 result = PRAGMA_OMP_CLAUSE_IN_REDUCTION;
12787 else if (!strcmp ("inbranch", p))
12788 result = PRAGMA_OMP_CLAUSE_INBRANCH;
12789 else if (!strcmp ("independent", p))
12790 result = PRAGMA_OACC_CLAUSE_INDEPENDENT;
12791 else if (!strcmp ("is_device_ptr", p))
12792 result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR;
12793 break;
12794 case 'l':
12795 if (!strcmp ("lastprivate", p))
12796 result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
12797 else if (!strcmp ("linear", p))
12798 result = PRAGMA_OMP_CLAUSE_LINEAR;
12799 else if (!strcmp ("link", p))
12800 result = PRAGMA_OMP_CLAUSE_LINK;
12801 break;
12802 case 'm':
12803 if (!strcmp ("map", p))
12804 result = PRAGMA_OMP_CLAUSE_MAP;
12805 else if (!strcmp ("mergeable", p))
12806 result = PRAGMA_OMP_CLAUSE_MERGEABLE;
12807 break;
12808 case 'n':
12809 if (!strcmp ("no_create", p))
12810 result = PRAGMA_OACC_CLAUSE_NO_CREATE;
12811 else if (!strcmp ("nogroup", p))
12812 result = PRAGMA_OMP_CLAUSE_NOGROUP;
12813 else if (!strcmp ("nohost", p))
12814 result = PRAGMA_OACC_CLAUSE_NOHOST;
12815 else if (!strcmp ("nontemporal", p))
12816 result = PRAGMA_OMP_CLAUSE_NONTEMPORAL;
12817 else if (!strcmp ("notinbranch", p))
12818 result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
12819 else if (!strcmp ("nowait", p))
12820 result = PRAGMA_OMP_CLAUSE_NOWAIT;
12821 else if (!strcmp ("num_gangs", p))
12822 result = PRAGMA_OACC_CLAUSE_NUM_GANGS;
12823 else if (!strcmp ("num_tasks", p))
12824 result = PRAGMA_OMP_CLAUSE_NUM_TASKS;
12825 else if (!strcmp ("num_teams", p))
12826 result = PRAGMA_OMP_CLAUSE_NUM_TEAMS;
12827 else if (!strcmp ("num_threads", p))
12828 result = PRAGMA_OMP_CLAUSE_NUM_THREADS;
12829 else if (!strcmp ("num_workers", p))
12830 result = PRAGMA_OACC_CLAUSE_NUM_WORKERS;
12831 break;
12832 case 'o':
12833 if (!strcmp ("ordered", p))
12834 result = PRAGMA_OMP_CLAUSE_ORDERED;
12835 else if (!strcmp ("order", p))
12836 result = PRAGMA_OMP_CLAUSE_ORDER;
12837 break;
12838 case 'p':
12839 if (!strcmp ("parallel", p))
12840 result = PRAGMA_OMP_CLAUSE_PARALLEL;
12841 else if (!strcmp ("present", p))
12842 result = PRAGMA_OACC_CLAUSE_PRESENT;
12843 /* As of OpenACC 2.5, these are now aliases of the non-present_or
12844 clauses. */
12845 else if (!strcmp ("present_or_copy", p)
12846 || !strcmp ("pcopy", p))
12847 result = PRAGMA_OACC_CLAUSE_COPY;
12848 else if (!strcmp ("present_or_copyin", p)
12849 || !strcmp ("pcopyin", p))
12850 result = PRAGMA_OACC_CLAUSE_COPYIN;
12851 else if (!strcmp ("present_or_copyout", p)
12852 || !strcmp ("pcopyout", p))
12853 result = PRAGMA_OACC_CLAUSE_COPYOUT;
12854 else if (!strcmp ("present_or_create", p)
12855 || !strcmp ("pcreate", p))
12856 result = PRAGMA_OACC_CLAUSE_CREATE;
12857 else if (!strcmp ("priority", p))
12858 result = PRAGMA_OMP_CLAUSE_PRIORITY;
12859 else if (!strcmp ("private", p))
12860 result = PRAGMA_OMP_CLAUSE_PRIVATE;
12861 else if (!strcmp ("proc_bind", p))
12862 result = PRAGMA_OMP_CLAUSE_PROC_BIND;
12863 break;
12864 case 'r':
12865 if (!strcmp ("reduction", p))
12866 result = PRAGMA_OMP_CLAUSE_REDUCTION;
12867 break;
12868 case 's':
12869 if (!strcmp ("safelen", p))
12870 result = PRAGMA_OMP_CLAUSE_SAFELEN;
12871 else if (!strcmp ("schedule", p))
12872 result = PRAGMA_OMP_CLAUSE_SCHEDULE;
12873 else if (!strcmp ("sections", p))
12874 result = PRAGMA_OMP_CLAUSE_SECTIONS;
12875 else if (!strcmp ("self", p)) /* "self" is a synonym for "host". */
12876 result = PRAGMA_OACC_CLAUSE_HOST;
12877 else if (!strcmp ("seq", p))
12878 result = PRAGMA_OACC_CLAUSE_SEQ;
12879 else if (!strcmp ("shared", p))
12880 result = PRAGMA_OMP_CLAUSE_SHARED;
12881 else if (!strcmp ("simd", p))
12882 result = PRAGMA_OMP_CLAUSE_SIMD;
12883 else if (!strcmp ("simdlen", p))
12884 result = PRAGMA_OMP_CLAUSE_SIMDLEN;
12885 break;
12886 case 't':
12887 if (!strcmp ("task_reduction", p))
12888 result = PRAGMA_OMP_CLAUSE_TASK_REDUCTION;
12889 else if (!strcmp ("taskgroup", p))
12890 result = PRAGMA_OMP_CLAUSE_TASKGROUP;
12891 else if (!strcmp ("thread_limit", p))
12892 result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT;
12893 else if (!strcmp ("threads", p))
12894 result = PRAGMA_OMP_CLAUSE_THREADS;
12895 else if (!strcmp ("tile", p))
12896 result = PRAGMA_OACC_CLAUSE_TILE;
12897 else if (!strcmp ("to", p))
12898 result = PRAGMA_OMP_CLAUSE_TO;
12899 break;
12900 case 'u':
12901 if (!strcmp ("uniform", p))
12902 result = PRAGMA_OMP_CLAUSE_UNIFORM;
12903 else if (!strcmp ("untied", p))
12904 result = PRAGMA_OMP_CLAUSE_UNTIED;
12905 else if (!strcmp ("use_device", p))
12906 result = PRAGMA_OACC_CLAUSE_USE_DEVICE;
12907 else if (!strcmp ("use_device_addr", p))
12908 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR;
12909 else if (!strcmp ("use_device_ptr", p))
12910 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR;
12911 break;
12912 case 'v':
12913 if (!strcmp ("vector", p))
12914 result = PRAGMA_OACC_CLAUSE_VECTOR;
12915 else if (!strcmp ("vector_length", p))
12916 result = PRAGMA_OACC_CLAUSE_VECTOR_LENGTH;
12917 break;
12918 case 'w':
12919 if (!strcmp ("wait", p))
12920 result = PRAGMA_OACC_CLAUSE_WAIT;
12921 else if (!strcmp ("worker", p))
12922 result = PRAGMA_OACC_CLAUSE_WORKER;
12923 break;
12924 }
12925 }
12926
12927 if (result != PRAGMA_OMP_CLAUSE_NONE)
12928 c_parser_consume_token (parser);
12929
12930 return result;
12931 }
12932
12933 /* Validate that a clause of the given type does not already exist. */
12934
12935 static void
12936 check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
12937 const char *name)
12938 {
12939 if (tree c = omp_find_clause (clauses, code))
12940 error_at (OMP_CLAUSE_LOCATION (c), "too many %qs clauses", name);
12941 }
12942
12943 /* OpenACC 2.0
12944 Parse wait clause or wait directive parameters. */
12945
12946 static tree
12947 c_parser_oacc_wait_list (c_parser *parser, location_t clause_loc, tree list)
12948 {
12949 vec<tree, va_gc> *args;
12950 tree t, args_tree;
12951
12952 matching_parens parens;
12953 if (!parens.require_open (parser))
12954 return list;
12955
12956 args = c_parser_expr_list (parser, false, true, NULL, NULL, NULL, NULL);
12957 args_tree = build_tree_list_vec (args);
12958
12959 for (t = args_tree; t; t = TREE_CHAIN (t))
12960 {
12961 tree targ = TREE_VALUE (t);
12962
12963 if (targ != error_mark_node)
12964 {
12965 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ)))
12966 {
12967 c_parser_error (parser, "expression must be integral");
12968 targ = error_mark_node;
12969 }
12970 else
12971 {
12972 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
12973
12974 OMP_CLAUSE_DECL (c) = targ;
12975 OMP_CLAUSE_CHAIN (c) = list;
12976 list = c;
12977 }
12978 }
12979 }
12980
12981 release_tree_vector (args);
12982 parens.require_close (parser);
12983 return list;
12984 }
12985
12986 /* OpenACC 2.0, OpenMP 2.5:
12987 variable-list:
12988 identifier
12989 variable-list , identifier
12990
12991 If KIND is nonzero, create the appropriate node and install the
12992 decl in OMP_CLAUSE_DECL and add the node to the head of the list.
12993 If KIND is nonzero, CLAUSE_LOC is the location of the clause.
12994
12995 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
12996 return the list created.
12997
12998 The optional ALLOW_DEREF argument is true if list items can use the deref
12999 (->) operator. */
13000
13001 struct omp_dim
13002 {
13003 tree low_bound, length;
13004 location_t loc;
13005 bool no_colon;
13006 omp_dim (tree lb, tree len, location_t lo, bool nc)
13007 : low_bound (lb), length (len), loc (lo), no_colon (nc) {}
13008 };
13009
13010 static tree
13011 c_parser_omp_variable_list (c_parser *parser,
13012 location_t clause_loc,
13013 enum omp_clause_code kind, tree list,
13014 bool allow_deref = false)
13015 {
13016 auto_vec<omp_dim> dims;
13017 bool array_section_p;
13018 auto_vec<c_token> tokens;
13019 unsigned int tokens_avail = 0;
13020 bool first = true;
13021
13022 while (1)
13023 {
13024 if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
13025 {
13026 if (c_parser_next_token_is_not (parser, CPP_NAME)
13027 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
13028 {
13029 struct c_expr expr = c_parser_expr_no_commas (parser, NULL);
13030 if (expr.value != error_mark_node)
13031 {
13032 tree u = build_omp_clause (clause_loc, kind);
13033 OMP_CLAUSE_DECL (u) = expr.value;
13034 OMP_CLAUSE_CHAIN (u) = list;
13035 list = u;
13036 }
13037
13038 if (c_parser_next_token_is_not (parser, CPP_COMMA))
13039 break;
13040
13041 c_parser_consume_token (parser);
13042 first = false;
13043 continue;
13044 }
13045
13046 tokens.truncate (0);
13047 unsigned int nesting_depth = 0;
13048 while (1)
13049 {
13050 c_token *token = c_parser_peek_token (parser);
13051 switch (token->type)
13052 {
13053 case CPP_EOF:
13054 case CPP_PRAGMA_EOL:
13055 break;
13056 case CPP_OPEN_BRACE:
13057 case CPP_OPEN_PAREN:
13058 case CPP_OPEN_SQUARE:
13059 ++nesting_depth;
13060 goto add;
13061 case CPP_CLOSE_BRACE:
13062 case CPP_CLOSE_PAREN:
13063 case CPP_CLOSE_SQUARE:
13064 if (nesting_depth-- == 0)
13065 break;
13066 goto add;
13067 case CPP_COMMA:
13068 if (nesting_depth == 0)
13069 break;
13070 goto add;
13071 default:
13072 add:
13073 tokens.safe_push (*token);
13074 c_parser_consume_token (parser);
13075 continue;
13076 }
13077 break;
13078 }
13079
13080 /* Make sure nothing tries to read past the end of the tokens. */
13081 c_token eof_token;
13082 memset (&eof_token, 0, sizeof (eof_token));
13083 eof_token.type = CPP_EOF;
13084 tokens.safe_push (eof_token);
13085 tokens.safe_push (eof_token);
13086
13087 tokens_avail = parser->tokens_avail;
13088 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
13089 parser->tokens = tokens.address ();
13090 parser->tokens_avail = tokens.length ();
13091 }
13092
13093 tree t = NULL_TREE;
13094
13095 if (c_parser_next_token_is (parser, CPP_NAME)
13096 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
13097 {
13098 t = lookup_name (c_parser_peek_token (parser)->value);
13099
13100 if (t == NULL_TREE)
13101 {
13102 undeclared_variable (c_parser_peek_token (parser)->location,
13103 c_parser_peek_token (parser)->value);
13104 t = error_mark_node;
13105 }
13106
13107 c_parser_consume_token (parser);
13108 }
13109 else if (c_parser_next_token_is (parser, CPP_KEYWORD)
13110 && (c_parser_peek_token (parser)->keyword == RID_FUNCTION_NAME
13111 || (c_parser_peek_token (parser)->keyword
13112 == RID_PRETTY_FUNCTION_NAME)
13113 || (c_parser_peek_token (parser)->keyword
13114 == RID_C99_FUNCTION_NAME)))
13115 t = c_parser_predefined_identifier (parser).value;
13116 else
13117 {
13118 if (first)
13119 c_parser_error (parser, "expected identifier");
13120 break;
13121 }
13122
13123 if (t == error_mark_node)
13124 ;
13125 else if (kind != 0)
13126 {
13127 switch (kind)
13128 {
13129 case OMP_CLAUSE__CACHE_:
13130 /* The OpenACC cache directive explicitly only allows "array
13131 elements or subarrays". */
13132 if (c_parser_peek_token (parser)->type != CPP_OPEN_SQUARE)
13133 {
13134 c_parser_error (parser, "expected %<[%>");
13135 t = error_mark_node;
13136 break;
13137 }
13138 /* FALLTHROUGH */
13139 case OMP_CLAUSE_MAP:
13140 case OMP_CLAUSE_FROM:
13141 case OMP_CLAUSE_TO:
13142 start_component_ref:
13143 while (c_parser_next_token_is (parser, CPP_DOT)
13144 || (allow_deref
13145 && c_parser_next_token_is (parser, CPP_DEREF)))
13146 {
13147 location_t op_loc = c_parser_peek_token (parser)->location;
13148 if (c_parser_next_token_is (parser, CPP_DEREF))
13149 {
13150 c_expr t_expr;
13151 t_expr.value = t;
13152 t_expr.original_code = ERROR_MARK;
13153 t_expr.original_type = NULL;
13154 set_c_expr_source_range (&t_expr, op_loc, op_loc);
13155 t_expr = convert_lvalue_to_rvalue (op_loc, t_expr,
13156 true, false);
13157 t = build_indirect_ref (op_loc, t_expr.value, RO_ARROW);
13158 }
13159 c_parser_consume_token (parser);
13160 if (!c_parser_next_token_is (parser, CPP_NAME))
13161 {
13162 c_parser_error (parser, "expected identifier");
13163 t = error_mark_node;
13164 break;
13165 }
13166
13167 c_token *comp_tok = c_parser_peek_token (parser);
13168 tree ident = comp_tok->value;
13169 location_t comp_loc = comp_tok->location;
13170 c_parser_consume_token (parser);
13171 t = build_component_ref (op_loc, t, ident, comp_loc);
13172 }
13173 /* FALLTHROUGH */
13174 case OMP_CLAUSE_AFFINITY:
13175 case OMP_CLAUSE_DEPEND:
13176 case OMP_CLAUSE_REDUCTION:
13177 case OMP_CLAUSE_IN_REDUCTION:
13178 case OMP_CLAUSE_TASK_REDUCTION:
13179 case OMP_CLAUSE_HAS_DEVICE_ADDR:
13180 array_section_p = false;
13181 dims.truncate (0);
13182 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
13183 {
13184 location_t loc = UNKNOWN_LOCATION;
13185 tree low_bound = NULL_TREE, length = NULL_TREE;
13186 bool no_colon = false;
13187
13188 c_parser_consume_token (parser);
13189 if (!c_parser_next_token_is (parser, CPP_COLON))
13190 {
13191 location_t expr_loc
13192 = c_parser_peek_token (parser)->location;
13193 c_expr expr = c_parser_expression (parser);
13194 expr = convert_lvalue_to_rvalue (expr_loc, expr,
13195 false, true);
13196 low_bound = expr.value;
13197 loc = expr_loc;
13198 }
13199 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
13200 {
13201 length = integer_one_node;
13202 no_colon = true;
13203 }
13204 else
13205 {
13206 /* Look for `:'. */
13207 if (!c_parser_require (parser, CPP_COLON,
13208 "expected %<:%>"))
13209 {
13210 t = error_mark_node;
13211 break;
13212 }
13213 array_section_p = true;
13214 if (!c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
13215 {
13216 location_t expr_loc
13217 = c_parser_peek_token (parser)->location;
13218 c_expr expr = c_parser_expression (parser);
13219 expr = convert_lvalue_to_rvalue (expr_loc, expr,
13220 false, true);
13221 length = expr.value;
13222 }
13223 }
13224 /* Look for the closing `]'. */
13225 if (!c_parser_require (parser, CPP_CLOSE_SQUARE,
13226 "expected %<]%>"))
13227 {
13228 t = error_mark_node;
13229 break;
13230 }
13231
13232 dims.safe_push (omp_dim (low_bound, length, loc, no_colon));
13233 }
13234
13235 if (t != error_mark_node)
13236 {
13237 if ((kind == OMP_CLAUSE_MAP
13238 || kind == OMP_CLAUSE_FROM
13239 || kind == OMP_CLAUSE_TO)
13240 && !array_section_p
13241 && (c_parser_next_token_is (parser, CPP_DOT)
13242 || (allow_deref
13243 && c_parser_next_token_is (parser,
13244 CPP_DEREF))))
13245 {
13246 for (unsigned i = 0; i < dims.length (); i++)
13247 {
13248 gcc_assert (dims[i].length == integer_one_node);
13249 t = build_array_ref (dims[i].loc,
13250 t, dims[i].low_bound);
13251 }
13252 goto start_component_ref;
13253 }
13254 else
13255 for (unsigned i = 0; i < dims.length (); i++)
13256 t = tree_cons (dims[i].low_bound, dims[i].length, t);
13257 }
13258
13259 if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
13260 && t != error_mark_node
13261 && parser->tokens_avail != 2)
13262 {
13263 if (array_section_p)
13264 {
13265 error_at (c_parser_peek_token (parser)->location,
13266 "expected %<)%> or %<,%>");
13267 t = error_mark_node;
13268 }
13269 else
13270 {
13271 parser->tokens = tokens.address ();
13272 parser->tokens_avail = tokens.length ();
13273
13274 t = c_parser_expr_no_commas (parser, NULL).value;
13275 if (t != error_mark_node && parser->tokens_avail != 2)
13276 {
13277 error_at (c_parser_peek_token (parser)->location,
13278 "expected %<)%> or %<,%>");
13279 t = error_mark_node;
13280 }
13281 }
13282 }
13283 break;
13284 default:
13285 break;
13286 }
13287
13288 if (t != error_mark_node)
13289 {
13290 tree u = build_omp_clause (clause_loc, kind);
13291 OMP_CLAUSE_DECL (u) = t;
13292 OMP_CLAUSE_CHAIN (u) = list;
13293 list = u;
13294 }
13295 }
13296 else
13297 list = tree_cons (t, NULL_TREE, list);
13298
13299 if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
13300 {
13301 parser->tokens = &parser->tokens_buf[0];
13302 parser->tokens_avail = tokens_avail;
13303 }
13304 if (c_parser_next_token_is_not (parser, CPP_COMMA))
13305 break;
13306
13307 c_parser_consume_token (parser);
13308 first = false;
13309 }
13310
13311 return list;
13312 }
13313
13314 /* Similarly, but expect leading and trailing parenthesis. This is a very
13315 common case for OpenACC and OpenMP clauses. The optional ALLOW_DEREF
13316 argument is true if list items can use the deref (->) operator. */
13317
13318 static tree
13319 c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind,
13320 tree list, bool allow_deref = false)
13321 {
13322 /* The clauses location. */
13323 location_t loc = c_parser_peek_token (parser)->location;
13324
13325 matching_parens parens;
13326 if (parens.require_open (parser))
13327 {
13328 list = c_parser_omp_variable_list (parser, loc, kind, list, allow_deref);
13329 parens.skip_until_found_close (parser);
13330 }
13331 return list;
13332 }
13333
13334 /* OpenACC 2.0:
13335 copy ( variable-list )
13336 copyin ( variable-list )
13337 copyout ( variable-list )
13338 create ( variable-list )
13339 delete ( variable-list )
13340 present ( variable-list )
13341
13342 OpenACC 2.6:
13343 no_create ( variable-list )
13344 attach ( variable-list )
13345 detach ( variable-list ) */
13346
13347 static tree
13348 c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind,
13349 tree list)
13350 {
13351 enum gomp_map_kind kind;
13352 switch (c_kind)
13353 {
13354 case PRAGMA_OACC_CLAUSE_ATTACH:
13355 kind = GOMP_MAP_ATTACH;
13356 break;
13357 case PRAGMA_OACC_CLAUSE_COPY:
13358 kind = GOMP_MAP_TOFROM;
13359 break;
13360 case PRAGMA_OACC_CLAUSE_COPYIN:
13361 kind = GOMP_MAP_TO;
13362 break;
13363 case PRAGMA_OACC_CLAUSE_COPYOUT:
13364 kind = GOMP_MAP_FROM;
13365 break;
13366 case PRAGMA_OACC_CLAUSE_CREATE:
13367 kind = GOMP_MAP_ALLOC;
13368 break;
13369 case PRAGMA_OACC_CLAUSE_DELETE:
13370 kind = GOMP_MAP_RELEASE;
13371 break;
13372 case PRAGMA_OACC_CLAUSE_DETACH:
13373 kind = GOMP_MAP_DETACH;
13374 break;
13375 case PRAGMA_OACC_CLAUSE_DEVICE:
13376 kind = GOMP_MAP_FORCE_TO;
13377 break;
13378 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
13379 kind = GOMP_MAP_DEVICE_RESIDENT;
13380 break;
13381 case PRAGMA_OACC_CLAUSE_HOST:
13382 kind = GOMP_MAP_FORCE_FROM;
13383 break;
13384 case PRAGMA_OACC_CLAUSE_LINK:
13385 kind = GOMP_MAP_LINK;
13386 break;
13387 case PRAGMA_OACC_CLAUSE_NO_CREATE:
13388 kind = GOMP_MAP_IF_PRESENT;
13389 break;
13390 case PRAGMA_OACC_CLAUSE_PRESENT:
13391 kind = GOMP_MAP_FORCE_PRESENT;
13392 break;
13393 default:
13394 gcc_unreachable ();
13395 }
13396 tree nl, c;
13397 nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_MAP, list, true);
13398
13399 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
13400 OMP_CLAUSE_SET_MAP_KIND (c, kind);
13401
13402 return nl;
13403 }
13404
13405 /* OpenACC 2.0:
13406 deviceptr ( variable-list ) */
13407
13408 static tree
13409 c_parser_oacc_data_clause_deviceptr (c_parser *parser, tree list)
13410 {
13411 location_t loc = c_parser_peek_token (parser)->location;
13412 tree vars, t;
13413
13414 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
13415 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
13416 variable-list must only allow for pointer variables. */
13417 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
13418 for (t = vars; t && t; t = TREE_CHAIN (t))
13419 {
13420 tree v = TREE_PURPOSE (t);
13421
13422 /* FIXME diagnostics: Ideally we should keep individual
13423 locations for all the variables in the var list to make the
13424 following errors more precise. Perhaps
13425 c_parser_omp_var_list_parens() should construct a list of
13426 locations to go along with the var list. */
13427
13428 if (!VAR_P (v) && TREE_CODE (v) != PARM_DECL)
13429 error_at (loc, "%qD is not a variable", v);
13430 else if (TREE_TYPE (v) == error_mark_node)
13431 ;
13432 else if (!POINTER_TYPE_P (TREE_TYPE (v)))
13433 error_at (loc, "%qD is not a pointer variable", v);
13434
13435 tree u = build_omp_clause (loc, OMP_CLAUSE_MAP);
13436 OMP_CLAUSE_SET_MAP_KIND (u, GOMP_MAP_FORCE_DEVICEPTR);
13437 OMP_CLAUSE_DECL (u) = v;
13438 OMP_CLAUSE_CHAIN (u) = list;
13439 list = u;
13440 }
13441
13442 return list;
13443 }
13444
13445 /* OpenACC 2.0, OpenMP 3.0:
13446 collapse ( constant-expression ) */
13447
13448 static tree
13449 c_parser_omp_clause_collapse (c_parser *parser, tree list)
13450 {
13451 tree c, num = error_mark_node;
13452 HOST_WIDE_INT n;
13453 location_t loc;
13454
13455 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
13456 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
13457
13458 loc = c_parser_peek_token (parser)->location;
13459 matching_parens parens;
13460 if (parens.require_open (parser))
13461 {
13462 num = c_parser_expr_no_commas (parser, NULL).value;
13463 parens.skip_until_found_close (parser);
13464 }
13465 if (num == error_mark_node)
13466 return list;
13467 mark_exp_read (num);
13468 num = c_fully_fold (num, false, NULL);
13469 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
13470 || !tree_fits_shwi_p (num)
13471 || (n = tree_to_shwi (num)) <= 0
13472 || (int) n != n)
13473 {
13474 error_at (loc,
13475 "collapse argument needs positive constant integer expression");
13476 return list;
13477 }
13478 c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE);
13479 OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
13480 OMP_CLAUSE_CHAIN (c) = list;
13481 return c;
13482 }
13483
13484 /* OpenMP 2.5:
13485 copyin ( variable-list ) */
13486
13487 static tree
13488 c_parser_omp_clause_copyin (c_parser *parser, tree list)
13489 {
13490 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYIN, list);
13491 }
13492
13493 /* OpenMP 2.5:
13494 copyprivate ( variable-list ) */
13495
13496 static tree
13497 c_parser_omp_clause_copyprivate (c_parser *parser, tree list)
13498 {
13499 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYPRIVATE, list);
13500 }
13501
13502 /* OpenMP 2.5:
13503 default ( none | shared )
13504
13505 OpenMP 5.1:
13506 default ( private | firstprivate )
13507
13508 OpenACC:
13509 default ( none | present ) */
13510
13511 static tree
13512 c_parser_omp_clause_default (c_parser *parser, tree list, bool is_oacc)
13513 {
13514 enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
13515 location_t loc = c_parser_peek_token (parser)->location;
13516 tree c;
13517
13518 matching_parens parens;
13519 if (!parens.require_open (parser))
13520 return list;
13521 if (c_parser_next_token_is (parser, CPP_NAME))
13522 {
13523 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13524
13525 switch (p[0])
13526 {
13527 case 'n':
13528 if (strcmp ("none", p) != 0)
13529 goto invalid_kind;
13530 kind = OMP_CLAUSE_DEFAULT_NONE;
13531 break;
13532
13533 case 'p':
13534 if (is_oacc)
13535 {
13536 if (strcmp ("present", p) != 0)
13537 goto invalid_kind;
13538 kind = OMP_CLAUSE_DEFAULT_PRESENT;
13539 }
13540 else
13541 {
13542 if (strcmp ("private", p) != 0)
13543 goto invalid_kind;
13544 kind = OMP_CLAUSE_DEFAULT_PRIVATE;
13545 }
13546 break;
13547
13548 case 'f':
13549 if (strcmp ("firstprivate", p) != 0 || is_oacc)
13550 goto invalid_kind;
13551 kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
13552 break;
13553
13554 case 's':
13555 if (strcmp ("shared", p) != 0 || is_oacc)
13556 goto invalid_kind;
13557 kind = OMP_CLAUSE_DEFAULT_SHARED;
13558 break;
13559
13560 default:
13561 goto invalid_kind;
13562 }
13563
13564 c_parser_consume_token (parser);
13565 }
13566 else
13567 {
13568 invalid_kind:
13569 if (is_oacc)
13570 c_parser_error (parser, "expected %<none%> or %<present%>");
13571 else
13572 c_parser_error (parser, "expected %<none%>, %<shared%>, "
13573 "%<private%> or %<firstprivate%>");
13574 }
13575 parens.skip_until_found_close (parser);
13576
13577 if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED)
13578 return list;
13579
13580 check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default");
13581 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULT);
13582 OMP_CLAUSE_CHAIN (c) = list;
13583 OMP_CLAUSE_DEFAULT_KIND (c) = kind;
13584
13585 return c;
13586 }
13587
13588 /* OpenMP 2.5:
13589 firstprivate ( variable-list ) */
13590
13591 static tree
13592 c_parser_omp_clause_firstprivate (c_parser *parser, tree list)
13593 {
13594 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FIRSTPRIVATE, list);
13595 }
13596
13597 /* OpenMP 3.1:
13598 final ( expression ) */
13599
13600 static tree
13601 c_parser_omp_clause_final (c_parser *parser, tree list)
13602 {
13603 location_t loc = c_parser_peek_token (parser)->location;
13604 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
13605 {
13606 matching_parens parens;
13607 tree t, c;
13608 if (!parens.require_open (parser))
13609 t = error_mark_node;
13610 else
13611 {
13612 location_t eloc = c_parser_peek_token (parser)->location;
13613 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13614 t = convert_lvalue_to_rvalue (eloc, expr, true, true).value;
13615 t = c_objc_common_truthvalue_conversion (eloc, t);
13616 t = c_fully_fold (t, false, NULL);
13617 parens.skip_until_found_close (parser);
13618 }
13619
13620 check_no_duplicate_clause (list, OMP_CLAUSE_FINAL, "final");
13621
13622 c = build_omp_clause (loc, OMP_CLAUSE_FINAL);
13623 OMP_CLAUSE_FINAL_EXPR (c) = t;
13624 OMP_CLAUSE_CHAIN (c) = list;
13625 list = c;
13626 }
13627 else
13628 c_parser_error (parser, "expected %<(%>");
13629
13630 return list;
13631 }
13632
13633 /* OpenACC, OpenMP 2.5:
13634 if ( expression )
13635
13636 OpenMP 4.5:
13637 if ( directive-name-modifier : expression )
13638
13639 directive-name-modifier:
13640 parallel | task | taskloop | target data | target | target update
13641 | target enter data | target exit data
13642
13643 OpenMP 5.0:
13644 directive-name-modifier:
13645 ... | simd | cancel */
13646
13647 static tree
13648 c_parser_omp_clause_if (c_parser *parser, tree list, bool is_omp)
13649 {
13650 location_t location = c_parser_peek_token (parser)->location;
13651 enum tree_code if_modifier = ERROR_MARK;
13652
13653 matching_parens parens;
13654 if (!parens.require_open (parser))
13655 return list;
13656
13657 if (is_omp && c_parser_next_token_is (parser, CPP_NAME))
13658 {
13659 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13660 int n = 2;
13661 if (strcmp (p, "cancel") == 0)
13662 if_modifier = VOID_CST;
13663 else if (strcmp (p, "parallel") == 0)
13664 if_modifier = OMP_PARALLEL;
13665 else if (strcmp (p, "simd") == 0)
13666 if_modifier = OMP_SIMD;
13667 else if (strcmp (p, "task") == 0)
13668 if_modifier = OMP_TASK;
13669 else if (strcmp (p, "taskloop") == 0)
13670 if_modifier = OMP_TASKLOOP;
13671 else if (strcmp (p, "target") == 0)
13672 {
13673 if_modifier = OMP_TARGET;
13674 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
13675 {
13676 p = IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser)->value);
13677 if (strcmp ("data", p) == 0)
13678 if_modifier = OMP_TARGET_DATA;
13679 else if (strcmp ("update", p) == 0)
13680 if_modifier = OMP_TARGET_UPDATE;
13681 else if (strcmp ("enter", p) == 0)
13682 if_modifier = OMP_TARGET_ENTER_DATA;
13683 else if (strcmp ("exit", p) == 0)
13684 if_modifier = OMP_TARGET_EXIT_DATA;
13685 if (if_modifier != OMP_TARGET)
13686 {
13687 n = 3;
13688 c_parser_consume_token (parser);
13689 }
13690 else
13691 {
13692 location_t loc = c_parser_peek_2nd_token (parser)->location;
13693 error_at (loc, "expected %<data%>, %<update%>, %<enter%> "
13694 "or %<exit%>");
13695 if_modifier = ERROR_MARK;
13696 }
13697 if (if_modifier == OMP_TARGET_ENTER_DATA
13698 || if_modifier == OMP_TARGET_EXIT_DATA)
13699 {
13700 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
13701 {
13702 p = IDENTIFIER_POINTER
13703 (c_parser_peek_2nd_token (parser)->value);
13704 if (strcmp ("data", p) == 0)
13705 n = 4;
13706 }
13707 if (n == 4)
13708 c_parser_consume_token (parser);
13709 else
13710 {
13711 location_t loc
13712 = c_parser_peek_2nd_token (parser)->location;
13713 error_at (loc, "expected %<data%>");
13714 if_modifier = ERROR_MARK;
13715 }
13716 }
13717 }
13718 }
13719 if (if_modifier != ERROR_MARK)
13720 {
13721 if (c_parser_peek_2nd_token (parser)->type == CPP_COLON)
13722 {
13723 c_parser_consume_token (parser);
13724 c_parser_consume_token (parser);
13725 }
13726 else
13727 {
13728 if (n > 2)
13729 {
13730 location_t loc = c_parser_peek_2nd_token (parser)->location;
13731 error_at (loc, "expected %<:%>");
13732 }
13733 if_modifier = ERROR_MARK;
13734 }
13735 }
13736 }
13737
13738 location_t loc = c_parser_peek_token (parser)->location;
13739 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13740 expr = convert_lvalue_to_rvalue (loc, expr, true, true);
13741 tree t = c_objc_common_truthvalue_conversion (loc, expr.value), c;
13742 t = c_fully_fold (t, false, NULL);
13743 parens.skip_until_found_close (parser);
13744
13745 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
13746 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF)
13747 {
13748 if (if_modifier != ERROR_MARK
13749 && OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
13750 {
13751 const char *p = NULL;
13752 switch (if_modifier)
13753 {
13754 case VOID_CST: p = "cancel"; break;
13755 case OMP_PARALLEL: p = "parallel"; break;
13756 case OMP_SIMD: p = "simd"; break;
13757 case OMP_TASK: p = "task"; break;
13758 case OMP_TASKLOOP: p = "taskloop"; break;
13759 case OMP_TARGET_DATA: p = "target data"; break;
13760 case OMP_TARGET: p = "target"; break;
13761 case OMP_TARGET_UPDATE: p = "target update"; break;
13762 case OMP_TARGET_ENTER_DATA: p = "target enter data"; break;
13763 case OMP_TARGET_EXIT_DATA: p = "target exit data"; break;
13764 default: gcc_unreachable ();
13765 }
13766 error_at (location, "too many %<if%> clauses with %qs modifier",
13767 p);
13768 return list;
13769 }
13770 else if (OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
13771 {
13772 if (!is_omp)
13773 error_at (location, "too many %<if%> clauses");
13774 else
13775 error_at (location, "too many %<if%> clauses without modifier");
13776 return list;
13777 }
13778 else if (if_modifier == ERROR_MARK
13779 || OMP_CLAUSE_IF_MODIFIER (c) == ERROR_MARK)
13780 {
13781 error_at (location, "if any %<if%> clause has modifier, then all "
13782 "%<if%> clauses have to use modifier");
13783 return list;
13784 }
13785 }
13786
13787 c = build_omp_clause (location, OMP_CLAUSE_IF);
13788 OMP_CLAUSE_IF_MODIFIER (c) = if_modifier;
13789 OMP_CLAUSE_IF_EXPR (c) = t;
13790 OMP_CLAUSE_CHAIN (c) = list;
13791 return c;
13792 }
13793
13794 /* OpenMP 2.5:
13795 lastprivate ( variable-list )
13796
13797 OpenMP 5.0:
13798 lastprivate ( [ lastprivate-modifier : ] variable-list ) */
13799
13800 static tree
13801 c_parser_omp_clause_lastprivate (c_parser *parser, tree list)
13802 {
13803 /* The clauses location. */
13804 location_t loc = c_parser_peek_token (parser)->location;
13805
13806 if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
13807 {
13808 bool conditional = false;
13809 if (c_parser_next_token_is (parser, CPP_NAME)
13810 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
13811 {
13812 const char *p
13813 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13814 if (strcmp (p, "conditional") == 0)
13815 {
13816 conditional = true;
13817 c_parser_consume_token (parser);
13818 c_parser_consume_token (parser);
13819 }
13820 }
13821 tree nlist = c_parser_omp_variable_list (parser, loc,
13822 OMP_CLAUSE_LASTPRIVATE, list);
13823 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
13824 if (conditional)
13825 for (tree c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
13826 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 1;
13827 return nlist;
13828 }
13829 return list;
13830 }
13831
13832 /* OpenMP 3.1:
13833 mergeable */
13834
13835 static tree
13836 c_parser_omp_clause_mergeable (c_parser *parser ATTRIBUTE_UNUSED, tree list)
13837 {
13838 tree c;
13839
13840 /* FIXME: Should we allow duplicates? */
13841 check_no_duplicate_clause (list, OMP_CLAUSE_MERGEABLE, "mergeable");
13842
13843 c = build_omp_clause (c_parser_peek_token (parser)->location,
13844 OMP_CLAUSE_MERGEABLE);
13845 OMP_CLAUSE_CHAIN (c) = list;
13846
13847 return c;
13848 }
13849
13850 /* OpenMP 2.5:
13851 nowait */
13852
13853 static tree
13854 c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list)
13855 {
13856 tree c;
13857 location_t loc = c_parser_peek_token (parser)->location;
13858
13859 check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait");
13860
13861 c = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
13862 OMP_CLAUSE_CHAIN (c) = list;
13863 return c;
13864 }
13865
13866 /* OpenMP 2.5:
13867 num_threads ( expression ) */
13868
13869 static tree
13870 c_parser_omp_clause_num_threads (c_parser *parser, tree list)
13871 {
13872 location_t num_threads_loc = c_parser_peek_token (parser)->location;
13873 matching_parens parens;
13874 if (parens.require_open (parser))
13875 {
13876 location_t expr_loc = c_parser_peek_token (parser)->location;
13877 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13878 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13879 tree c, t = expr.value;
13880 t = c_fully_fold (t, false, NULL);
13881
13882 parens.skip_until_found_close (parser);
13883
13884 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13885 {
13886 c_parser_error (parser, "expected integer expression");
13887 return list;
13888 }
13889
13890 /* Attempt to statically determine when the number isn't positive. */
13891 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13892 build_int_cst (TREE_TYPE (t), 0));
13893 protected_set_expr_location (c, expr_loc);
13894 if (c == boolean_true_node)
13895 {
13896 warning_at (expr_loc, 0,
13897 "%<num_threads%> value must be positive");
13898 t = integer_one_node;
13899 }
13900
13901 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads");
13902
13903 c = build_omp_clause (num_threads_loc, OMP_CLAUSE_NUM_THREADS);
13904 OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
13905 OMP_CLAUSE_CHAIN (c) = list;
13906 list = c;
13907 }
13908
13909 return list;
13910 }
13911
13912 /* OpenMP 4.5:
13913 num_tasks ( expression )
13914
13915 OpenMP 5.1:
13916 num_tasks ( strict : expression ) */
13917
13918 static tree
13919 c_parser_omp_clause_num_tasks (c_parser *parser, tree list)
13920 {
13921 location_t num_tasks_loc = c_parser_peek_token (parser)->location;
13922 matching_parens parens;
13923 if (parens.require_open (parser))
13924 {
13925 bool strict = false;
13926 if (c_parser_next_token_is (parser, CPP_NAME)
13927 && c_parser_peek_2nd_token (parser)->type == CPP_COLON
13928 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
13929 "strict") == 0)
13930 {
13931 strict = true;
13932 c_parser_consume_token (parser);
13933 c_parser_consume_token (parser);
13934 }
13935
13936 location_t expr_loc = c_parser_peek_token (parser)->location;
13937 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13938 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13939 tree c, t = expr.value;
13940 t = c_fully_fold (t, false, NULL);
13941
13942 parens.skip_until_found_close (parser);
13943
13944 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13945 {
13946 c_parser_error (parser, "expected integer expression");
13947 return list;
13948 }
13949
13950 /* Attempt to statically determine when the number isn't positive. */
13951 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13952 build_int_cst (TREE_TYPE (t), 0));
13953 if (CAN_HAVE_LOCATION_P (c))
13954 SET_EXPR_LOCATION (c, expr_loc);
13955 if (c == boolean_true_node)
13956 {
13957 warning_at (expr_loc, 0, "%<num_tasks%> value must be positive");
13958 t = integer_one_node;
13959 }
13960
13961 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TASKS, "num_tasks");
13962
13963 c = build_omp_clause (num_tasks_loc, OMP_CLAUSE_NUM_TASKS);
13964 OMP_CLAUSE_NUM_TASKS_EXPR (c) = t;
13965 OMP_CLAUSE_NUM_TASKS_STRICT (c) = strict;
13966 OMP_CLAUSE_CHAIN (c) = list;
13967 list = c;
13968 }
13969
13970 return list;
13971 }
13972
13973 /* OpenMP 4.5:
13974 grainsize ( expression )
13975
13976 OpenMP 5.1:
13977 grainsize ( strict : expression ) */
13978
13979 static tree
13980 c_parser_omp_clause_grainsize (c_parser *parser, tree list)
13981 {
13982 location_t grainsize_loc = c_parser_peek_token (parser)->location;
13983 matching_parens parens;
13984 if (parens.require_open (parser))
13985 {
13986 bool strict = false;
13987 if (c_parser_next_token_is (parser, CPP_NAME)
13988 && c_parser_peek_2nd_token (parser)->type == CPP_COLON
13989 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
13990 "strict") == 0)
13991 {
13992 strict = true;
13993 c_parser_consume_token (parser);
13994 c_parser_consume_token (parser);
13995 }
13996
13997 location_t expr_loc = c_parser_peek_token (parser)->location;
13998 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13999 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14000 tree c, t = expr.value;
14001 t = c_fully_fold (t, false, NULL);
14002
14003 parens.skip_until_found_close (parser);
14004
14005 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14006 {
14007 c_parser_error (parser, "expected integer expression");
14008 return list;
14009 }
14010
14011 /* Attempt to statically determine when the number isn't positive. */
14012 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14013 build_int_cst (TREE_TYPE (t), 0));
14014 if (CAN_HAVE_LOCATION_P (c))
14015 SET_EXPR_LOCATION (c, expr_loc);
14016 if (c == boolean_true_node)
14017 {
14018 warning_at (expr_loc, 0, "%<grainsize%> value must be positive");
14019 t = integer_one_node;
14020 }
14021
14022 check_no_duplicate_clause (list, OMP_CLAUSE_GRAINSIZE, "grainsize");
14023
14024 c = build_omp_clause (grainsize_loc, OMP_CLAUSE_GRAINSIZE);
14025 OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
14026 OMP_CLAUSE_GRAINSIZE_STRICT (c) = strict;
14027 OMP_CLAUSE_CHAIN (c) = list;
14028 list = c;
14029 }
14030
14031 return list;
14032 }
14033
14034 /* OpenMP 4.5:
14035 priority ( expression ) */
14036
14037 static tree
14038 c_parser_omp_clause_priority (c_parser *parser, tree list)
14039 {
14040 location_t priority_loc = c_parser_peek_token (parser)->location;
14041 matching_parens parens;
14042 if (parens.require_open (parser))
14043 {
14044 location_t expr_loc = c_parser_peek_token (parser)->location;
14045 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14046 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14047 tree c, t = expr.value;
14048 t = c_fully_fold (t, false, NULL);
14049
14050 parens.skip_until_found_close (parser);
14051
14052 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14053 {
14054 c_parser_error (parser, "expected integer expression");
14055 return list;
14056 }
14057
14058 /* Attempt to statically determine when the number isn't
14059 non-negative. */
14060 c = fold_build2_loc (expr_loc, LT_EXPR, boolean_type_node, t,
14061 build_int_cst (TREE_TYPE (t), 0));
14062 if (CAN_HAVE_LOCATION_P (c))
14063 SET_EXPR_LOCATION (c, expr_loc);
14064 if (c == boolean_true_node)
14065 {
14066 warning_at (expr_loc, 0, "%<priority%> value must be non-negative");
14067 t = integer_one_node;
14068 }
14069
14070 check_no_duplicate_clause (list, OMP_CLAUSE_PRIORITY, "priority");
14071
14072 c = build_omp_clause (priority_loc, OMP_CLAUSE_PRIORITY);
14073 OMP_CLAUSE_PRIORITY_EXPR (c) = t;
14074 OMP_CLAUSE_CHAIN (c) = list;
14075 list = c;
14076 }
14077
14078 return list;
14079 }
14080
14081 /* OpenMP 4.5:
14082 hint ( expression ) */
14083
14084 static tree
14085 c_parser_omp_clause_hint (c_parser *parser, tree list)
14086 {
14087 location_t hint_loc = c_parser_peek_token (parser)->location;
14088 matching_parens parens;
14089 if (parens.require_open (parser))
14090 {
14091 location_t expr_loc = c_parser_peek_token (parser)->location;
14092 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14093 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14094 tree c, t = expr.value;
14095 t = c_fully_fold (t, false, NULL);
14096 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
14097 || TREE_CODE (t) != INTEGER_CST
14098 || tree_int_cst_sgn (t) == -1)
14099 {
14100 c_parser_error (parser, "expected constant integer expression "
14101 "with valid sync-hint value");
14102 return list;
14103 }
14104 parens.skip_until_found_close (parser);
14105 check_no_duplicate_clause (list, OMP_CLAUSE_HINT, "hint");
14106
14107 c = build_omp_clause (hint_loc, OMP_CLAUSE_HINT);
14108 OMP_CLAUSE_HINT_EXPR (c) = t;
14109 OMP_CLAUSE_CHAIN (c) = list;
14110 list = c;
14111 }
14112
14113 return list;
14114 }
14115
14116 /* OpenMP 5.1:
14117 filter ( integer-expression ) */
14118
14119 static tree
14120 c_parser_omp_clause_filter (c_parser *parser, tree list)
14121 {
14122 location_t hint_loc = c_parser_peek_token (parser)->location;
14123 matching_parens parens;
14124 if (parens.require_open (parser))
14125 {
14126 location_t expr_loc = c_parser_peek_token (parser)->location;
14127 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14128 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14129 tree c, t = expr.value;
14130 t = c_fully_fold (t, false, NULL);
14131 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14132 {
14133 c_parser_error (parser, "expected integer expression");
14134 return list;
14135 }
14136 parens.skip_until_found_close (parser);
14137 check_no_duplicate_clause (list, OMP_CLAUSE_FILTER, "filter");
14138
14139 c = build_omp_clause (hint_loc, OMP_CLAUSE_FILTER);
14140 OMP_CLAUSE_FILTER_EXPR (c) = t;
14141 OMP_CLAUSE_CHAIN (c) = list;
14142 list = c;
14143 }
14144
14145 return list;
14146 }
14147
14148 /* OpenMP 4.5:
14149 defaultmap ( tofrom : scalar )
14150
14151 OpenMP 5.0:
14152 defaultmap ( implicit-behavior [ : variable-category ] ) */
14153
14154 static tree
14155 c_parser_omp_clause_defaultmap (c_parser *parser, tree list)
14156 {
14157 location_t loc = c_parser_peek_token (parser)->location;
14158 tree c;
14159 const char *p;
14160 enum omp_clause_defaultmap_kind behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
14161 enum omp_clause_defaultmap_kind category
14162 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
14163
14164 matching_parens parens;
14165 if (!parens.require_open (parser))
14166 return list;
14167 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
14168 p = "default";
14169 else if (!c_parser_next_token_is (parser, CPP_NAME))
14170 {
14171 invalid_behavior:
14172 c_parser_error (parser, "expected %<alloc%>, %<to%>, %<from%>, "
14173 "%<tofrom%>, %<firstprivate%>, %<none%> "
14174 "or %<default%>");
14175 goto out_err;
14176 }
14177 else
14178 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14179
14180 switch (p[0])
14181 {
14182 case 'a':
14183 if (strcmp ("alloc", p) == 0)
14184 behavior = OMP_CLAUSE_DEFAULTMAP_ALLOC;
14185 else
14186 goto invalid_behavior;
14187 break;
14188
14189 case 'd':
14190 if (strcmp ("default", p) == 0)
14191 behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
14192 else
14193 goto invalid_behavior;
14194 break;
14195
14196 case 'f':
14197 if (strcmp ("firstprivate", p) == 0)
14198 behavior = OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
14199 else if (strcmp ("from", p) == 0)
14200 behavior = OMP_CLAUSE_DEFAULTMAP_FROM;
14201 else
14202 goto invalid_behavior;
14203 break;
14204
14205 case 'n':
14206 if (strcmp ("none", p) == 0)
14207 behavior = OMP_CLAUSE_DEFAULTMAP_NONE;
14208 else
14209 goto invalid_behavior;
14210 break;
14211
14212 case 't':
14213 if (strcmp ("tofrom", p) == 0)
14214 behavior = OMP_CLAUSE_DEFAULTMAP_TOFROM;
14215 else if (strcmp ("to", p) == 0)
14216 behavior = OMP_CLAUSE_DEFAULTMAP_TO;
14217 else
14218 goto invalid_behavior;
14219 break;
14220
14221 default:
14222 goto invalid_behavior;
14223 }
14224 c_parser_consume_token (parser);
14225
14226 if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
14227 {
14228 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14229 goto out_err;
14230 if (!c_parser_next_token_is (parser, CPP_NAME))
14231 {
14232 invalid_category:
14233 c_parser_error (parser, "expected %<scalar%>, %<aggregate%> or "
14234 "%<pointer%>");
14235 goto out_err;
14236 }
14237 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14238 switch (p[0])
14239 {
14240 case 'a':
14241 if (strcmp ("aggregate", p) == 0)
14242 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE;
14243 else
14244 goto invalid_category;
14245 break;
14246
14247 case 'p':
14248 if (strcmp ("pointer", p) == 0)
14249 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER;
14250 else
14251 goto invalid_category;
14252 break;
14253
14254 case 's':
14255 if (strcmp ("scalar", p) == 0)
14256 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR;
14257 else
14258 goto invalid_category;
14259 break;
14260
14261 default:
14262 goto invalid_category;
14263 }
14264
14265 c_parser_consume_token (parser);
14266 }
14267 parens.skip_until_found_close (parser);
14268
14269 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
14270 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEFAULTMAP
14271 && (category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
14272 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c) == category
14273 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
14274 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)))
14275 {
14276 enum omp_clause_defaultmap_kind cat = category;
14277 location_t loc = OMP_CLAUSE_LOCATION (c);
14278 if (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
14279 cat = OMP_CLAUSE_DEFAULTMAP_CATEGORY (c);
14280 p = NULL;
14281 switch (cat)
14282 {
14283 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
14284 p = NULL;
14285 break;
14286 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
14287 p = "aggregate";
14288 break;
14289 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
14290 p = "pointer";
14291 break;
14292 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
14293 p = "scalar";
14294 break;
14295 default:
14296 gcc_unreachable ();
14297 }
14298 if (p)
14299 error_at (loc, "too many %<defaultmap%> clauses with %qs category",
14300 p);
14301 else
14302 error_at (loc, "too many %<defaultmap%> clauses with unspecified "
14303 "category");
14304 break;
14305 }
14306
14307 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULTMAP);
14308 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c, behavior, category);
14309 OMP_CLAUSE_CHAIN (c) = list;
14310 return c;
14311
14312 out_err:
14313 parens.skip_until_found_close (parser);
14314 return list;
14315 }
14316
14317 /* OpenACC 2.0:
14318 use_device ( variable-list )
14319
14320 OpenMP 4.5:
14321 use_device_ptr ( variable-list ) */
14322
14323 static tree
14324 c_parser_omp_clause_use_device_ptr (c_parser *parser, tree list)
14325 {
14326 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_PTR,
14327 list);
14328 }
14329
14330 /* OpenMP 5.0:
14331 use_device_addr ( variable-list ) */
14332
14333 static tree
14334 c_parser_omp_clause_use_device_addr (c_parser *parser, tree list)
14335 {
14336 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_ADDR,
14337 list);
14338 }
14339
14340 /* OpenMP 5.1:
14341 has_device_addr ( variable-list ) */
14342
14343 static tree
14344 c_parser_omp_clause_has_device_addr (c_parser *parser, tree list)
14345 {
14346 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_HAS_DEVICE_ADDR,
14347 list);
14348 }
14349
14350 /* OpenMP 4.5:
14351 is_device_ptr ( variable-list ) */
14352
14353 static tree
14354 c_parser_omp_clause_is_device_ptr (c_parser *parser, tree list)
14355 {
14356 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_IS_DEVICE_PTR, list);
14357 }
14358
14359 /* OpenACC:
14360 num_gangs ( expression )
14361 num_workers ( expression )
14362 vector_length ( expression ) */
14363
14364 static tree
14365 c_parser_oacc_single_int_clause (c_parser *parser, omp_clause_code code,
14366 tree list)
14367 {
14368 location_t loc = c_parser_peek_token (parser)->location;
14369
14370 matching_parens parens;
14371 if (!parens.require_open (parser))
14372 return list;
14373
14374 location_t expr_loc = c_parser_peek_token (parser)->location;
14375 c_expr expr = c_parser_expression (parser);
14376 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14377 tree c, t = expr.value;
14378 t = c_fully_fold (t, false, NULL);
14379
14380 parens.skip_until_found_close (parser);
14381
14382 if (t == error_mark_node)
14383 return list;
14384 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14385 {
14386 error_at (expr_loc, "%qs expression must be integral",
14387 omp_clause_code_name[code]);
14388 return list;
14389 }
14390
14391 /* Attempt to statically determine when the number isn't positive. */
14392 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14393 build_int_cst (TREE_TYPE (t), 0));
14394 protected_set_expr_location (c, expr_loc);
14395 if (c == boolean_true_node)
14396 {
14397 warning_at (expr_loc, 0,
14398 "%qs value must be positive",
14399 omp_clause_code_name[code]);
14400 t = integer_one_node;
14401 }
14402
14403 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14404
14405 c = build_omp_clause (loc, code);
14406 OMP_CLAUSE_OPERAND (c, 0) = t;
14407 OMP_CLAUSE_CHAIN (c) = list;
14408 return c;
14409 }
14410
14411 /* OpenACC:
14412
14413 gang [( gang-arg-list )]
14414 worker [( [num:] int-expr )]
14415 vector [( [length:] int-expr )]
14416
14417 where gang-arg is one of:
14418
14419 [num:] int-expr
14420 static: size-expr
14421
14422 and size-expr may be:
14423
14424 *
14425 int-expr
14426 */
14427
14428 static tree
14429 c_parser_oacc_shape_clause (c_parser *parser, location_t loc,
14430 omp_clause_code kind,
14431 const char *str, tree list)
14432 {
14433 const char *id = "num";
14434 tree ops[2] = { NULL_TREE, NULL_TREE }, c;
14435
14436 if (kind == OMP_CLAUSE_VECTOR)
14437 id = "length";
14438
14439 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14440 {
14441 c_parser_consume_token (parser);
14442
14443 do
14444 {
14445 c_token *next = c_parser_peek_token (parser);
14446 int idx = 0;
14447
14448 /* Gang static argument. */
14449 if (kind == OMP_CLAUSE_GANG
14450 && c_parser_next_token_is_keyword (parser, RID_STATIC))
14451 {
14452 c_parser_consume_token (parser);
14453
14454 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14455 goto cleanup_error;
14456
14457 idx = 1;
14458 if (ops[idx] != NULL_TREE)
14459 {
14460 c_parser_error (parser, "too many %<static%> arguments");
14461 goto cleanup_error;
14462 }
14463
14464 /* Check for the '*' argument. */
14465 if (c_parser_next_token_is (parser, CPP_MULT)
14466 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
14467 || c_parser_peek_2nd_token (parser)->type
14468 == CPP_CLOSE_PAREN))
14469 {
14470 c_parser_consume_token (parser);
14471 ops[idx] = integer_minus_one_node;
14472
14473 if (c_parser_next_token_is (parser, CPP_COMMA))
14474 {
14475 c_parser_consume_token (parser);
14476 continue;
14477 }
14478 else
14479 break;
14480 }
14481 }
14482 /* Worker num: argument and vector length: arguments. */
14483 else if (c_parser_next_token_is (parser, CPP_NAME)
14484 && strcmp (id, IDENTIFIER_POINTER (next->value)) == 0
14485 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
14486 {
14487 c_parser_consume_token (parser); /* id */
14488 c_parser_consume_token (parser); /* ':' */
14489 }
14490
14491 /* Now collect the actual argument. */
14492 if (ops[idx] != NULL_TREE)
14493 {
14494 c_parser_error (parser, "unexpected argument");
14495 goto cleanup_error;
14496 }
14497
14498 location_t expr_loc = c_parser_peek_token (parser)->location;
14499 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
14500 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
14501 tree expr = cexpr.value;
14502 if (expr == error_mark_node)
14503 goto cleanup_error;
14504
14505 expr = c_fully_fold (expr, false, NULL);
14506
14507 /* Attempt to statically determine when the number isn't a
14508 positive integer. */
14509
14510 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr)))
14511 {
14512 c_parser_error (parser, "expected integer expression");
14513 return list;
14514 }
14515
14516 tree c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, expr,
14517 build_int_cst (TREE_TYPE (expr), 0));
14518 if (c == boolean_true_node)
14519 {
14520 warning_at (loc, 0,
14521 "%qs value must be positive", str);
14522 expr = integer_one_node;
14523 }
14524
14525 ops[idx] = expr;
14526
14527 if (kind == OMP_CLAUSE_GANG
14528 && c_parser_next_token_is (parser, CPP_COMMA))
14529 {
14530 c_parser_consume_token (parser);
14531 continue;
14532 }
14533 break;
14534 }
14535 while (1);
14536
14537 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
14538 goto cleanup_error;
14539 }
14540
14541 check_no_duplicate_clause (list, kind, str);
14542
14543 c = build_omp_clause (loc, kind);
14544
14545 if (ops[1])
14546 OMP_CLAUSE_OPERAND (c, 1) = ops[1];
14547
14548 OMP_CLAUSE_OPERAND (c, 0) = ops[0];
14549 OMP_CLAUSE_CHAIN (c) = list;
14550
14551 return c;
14552
14553 cleanup_error:
14554 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
14555 return list;
14556 }
14557
14558 /* OpenACC 2.5:
14559 auto
14560 finalize
14561 independent
14562 nohost
14563 seq */
14564
14565 static tree
14566 c_parser_oacc_simple_clause (location_t loc, enum omp_clause_code code,
14567 tree list)
14568 {
14569 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14570
14571 tree c = build_omp_clause (loc, code);
14572 OMP_CLAUSE_CHAIN (c) = list;
14573
14574 return c;
14575 }
14576
14577 /* OpenACC:
14578 async [( int-expr )] */
14579
14580 static tree
14581 c_parser_oacc_clause_async (c_parser *parser, tree list)
14582 {
14583 tree c, t;
14584 location_t loc = c_parser_peek_token (parser)->location;
14585
14586 t = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
14587
14588 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
14589 {
14590 c_parser_consume_token (parser);
14591
14592 t = c_parser_expr_no_commas (parser, NULL).value;
14593 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14594 c_parser_error (parser, "expected integer expression");
14595 else if (t == error_mark_node
14596 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
14597 return list;
14598 }
14599 else
14600 t = c_fully_fold (t, false, NULL);
14601
14602 check_no_duplicate_clause (list, OMP_CLAUSE_ASYNC, "async");
14603
14604 c = build_omp_clause (loc, OMP_CLAUSE_ASYNC);
14605 OMP_CLAUSE_ASYNC_EXPR (c) = t;
14606 OMP_CLAUSE_CHAIN (c) = list;
14607 list = c;
14608
14609 return list;
14610 }
14611
14612 /* OpenACC 2.0:
14613 tile ( size-expr-list ) */
14614
14615 static tree
14616 c_parser_oacc_clause_tile (c_parser *parser, tree list)
14617 {
14618 tree c, expr = error_mark_node;
14619 location_t loc;
14620 tree tile = NULL_TREE;
14621
14622 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
14623 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
14624
14625 loc = c_parser_peek_token (parser)->location;
14626 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
14627 return list;
14628
14629 do
14630 {
14631 if (tile && !c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
14632 return list;
14633
14634 if (c_parser_next_token_is (parser, CPP_MULT)
14635 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
14636 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
14637 {
14638 c_parser_consume_token (parser);
14639 expr = integer_zero_node;
14640 }
14641 else
14642 {
14643 location_t expr_loc = c_parser_peek_token (parser)->location;
14644 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
14645 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
14646 expr = cexpr.value;
14647
14648 if (expr == error_mark_node)
14649 {
14650 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
14651 "expected %<)%>");
14652 return list;
14653 }
14654
14655 expr = c_fully_fold (expr, false, NULL);
14656
14657 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
14658 || !tree_fits_shwi_p (expr)
14659 || tree_to_shwi (expr) <= 0)
14660 {
14661 error_at (expr_loc, "%<tile%> argument needs positive"
14662 " integral constant");
14663 expr = integer_zero_node;
14664 }
14665 }
14666
14667 tile = tree_cons (NULL_TREE, expr, tile);
14668 }
14669 while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN));
14670
14671 /* Consume the trailing ')'. */
14672 c_parser_consume_token (parser);
14673
14674 c = build_omp_clause (loc, OMP_CLAUSE_TILE);
14675 tile = nreverse (tile);
14676 OMP_CLAUSE_TILE_LIST (c) = tile;
14677 OMP_CLAUSE_CHAIN (c) = list;
14678 return c;
14679 }
14680
14681 /* OpenACC:
14682 wait [( int-expr-list )] */
14683
14684 static tree
14685 c_parser_oacc_clause_wait (c_parser *parser, tree list)
14686 {
14687 location_t clause_loc = c_parser_peek_token (parser)->location;
14688
14689 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
14690 list = c_parser_oacc_wait_list (parser, clause_loc, list);
14691 else
14692 {
14693 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
14694
14695 OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
14696 OMP_CLAUSE_CHAIN (c) = list;
14697 list = c;
14698 }
14699
14700 return list;
14701 }
14702
14703
14704 /* OpenMP 5.0:
14705 order ( concurrent )
14706
14707 OpenMP 5.1:
14708 order ( order-modifier : concurrent )
14709
14710 order-modifier:
14711 reproducible
14712 unconstrained */
14713
14714 static tree
14715 c_parser_omp_clause_order (c_parser *parser, tree list)
14716 {
14717 location_t loc = c_parser_peek_token (parser)->location;
14718 tree c;
14719 const char *p;
14720 bool unconstrained = false;
14721 bool reproducible = false;
14722
14723 matching_parens parens;
14724 if (!parens.require_open (parser))
14725 return list;
14726 if (c_parser_next_token_is (parser, CPP_NAME)
14727 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
14728 {
14729 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14730 if (strcmp (p, "unconstrained") == 0)
14731 unconstrained = true;
14732 else if (strcmp (p, "reproducible") == 0)
14733 reproducible = true;
14734 else
14735 {
14736 c_parser_error (parser, "expected %<reproducible%> or "
14737 "%<unconstrained%>");
14738 goto out_err;
14739 }
14740 c_parser_consume_token (parser);
14741 c_parser_consume_token (parser);
14742 }
14743 if (!c_parser_next_token_is (parser, CPP_NAME))
14744 {
14745 c_parser_error (parser, "expected %<concurrent%>");
14746 goto out_err;
14747 }
14748 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14749 if (strcmp (p, "concurrent") != 0)
14750 {
14751 c_parser_error (parser, "expected %<concurrent%>");
14752 goto out_err;
14753 }
14754 c_parser_consume_token (parser);
14755 parens.skip_until_found_close (parser);
14756 check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order");
14757 c = build_omp_clause (loc, OMP_CLAUSE_ORDER);
14758 OMP_CLAUSE_ORDER_UNCONSTRAINED (c) = unconstrained;
14759 OMP_CLAUSE_ORDER_REPRODUCIBLE (c) = reproducible;
14760 OMP_CLAUSE_CHAIN (c) = list;
14761 return c;
14762
14763 out_err:
14764 parens.skip_until_found_close (parser);
14765 return list;
14766 }
14767
14768
14769 /* OpenMP 5.0:
14770 bind ( teams | parallel | thread ) */
14771
14772 static tree
14773 c_parser_omp_clause_bind (c_parser *parser, tree list)
14774 {
14775 location_t loc = c_parser_peek_token (parser)->location;
14776 tree c;
14777 const char *p;
14778 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
14779
14780 matching_parens parens;
14781 if (!parens.require_open (parser))
14782 return list;
14783 if (!c_parser_next_token_is (parser, CPP_NAME))
14784 {
14785 invalid:
14786 c_parser_error (parser,
14787 "expected %<teams%>, %<parallel%> or %<thread%>");
14788 parens.skip_until_found_close (parser);
14789 return list;
14790 }
14791 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14792 if (strcmp (p, "teams") == 0)
14793 kind = OMP_CLAUSE_BIND_TEAMS;
14794 else if (strcmp (p, "parallel") == 0)
14795 kind = OMP_CLAUSE_BIND_PARALLEL;
14796 else if (strcmp (p, "thread") != 0)
14797 goto invalid;
14798 c_parser_consume_token (parser);
14799 parens.skip_until_found_close (parser);
14800 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
14801 c = build_omp_clause (loc, OMP_CLAUSE_BIND);
14802 OMP_CLAUSE_BIND_KIND (c) = kind;
14803 OMP_CLAUSE_CHAIN (c) = list;
14804 return c;
14805 }
14806
14807
14808 /* OpenMP 2.5:
14809 ordered
14810
14811 OpenMP 4.5:
14812 ordered ( constant-expression ) */
14813
14814 static tree
14815 c_parser_omp_clause_ordered (c_parser *parser, tree list)
14816 {
14817 check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered");
14818
14819 tree c, num = NULL_TREE;
14820 HOST_WIDE_INT n;
14821 location_t loc = c_parser_peek_token (parser)->location;
14822 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
14823 {
14824 matching_parens parens;
14825 parens.consume_open (parser);
14826 num = c_parser_expr_no_commas (parser, NULL).value;
14827 parens.skip_until_found_close (parser);
14828 }
14829 if (num == error_mark_node)
14830 return list;
14831 if (num)
14832 {
14833 mark_exp_read (num);
14834 num = c_fully_fold (num, false, NULL);
14835 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
14836 || !tree_fits_shwi_p (num)
14837 || (n = tree_to_shwi (num)) <= 0
14838 || (int) n != n)
14839 {
14840 error_at (loc, "ordered argument needs positive "
14841 "constant integer expression");
14842 return list;
14843 }
14844 }
14845 c = build_omp_clause (loc, OMP_CLAUSE_ORDERED);
14846 OMP_CLAUSE_ORDERED_EXPR (c) = num;
14847 OMP_CLAUSE_CHAIN (c) = list;
14848 return c;
14849 }
14850
14851 /* OpenMP 2.5:
14852 private ( variable-list ) */
14853
14854 static tree
14855 c_parser_omp_clause_private (c_parser *parser, tree list)
14856 {
14857 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_PRIVATE, list);
14858 }
14859
14860 /* OpenMP 2.5:
14861 reduction ( reduction-operator : variable-list )
14862
14863 reduction-operator:
14864 One of: + * - & ^ | && ||
14865
14866 OpenMP 3.1:
14867
14868 reduction-operator:
14869 One of: + * - & ^ | && || max min
14870
14871 OpenMP 4.0:
14872
14873 reduction-operator:
14874 One of: + * - & ^ | && ||
14875 identifier
14876
14877 OpenMP 5.0:
14878 reduction ( reduction-modifier, reduction-operator : variable-list )
14879 in_reduction ( reduction-operator : variable-list )
14880 task_reduction ( reduction-operator : variable-list ) */
14881
14882 static tree
14883 c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind,
14884 bool is_omp, tree list)
14885 {
14886 location_t clause_loc = c_parser_peek_token (parser)->location;
14887 matching_parens parens;
14888 if (parens.require_open (parser))
14889 {
14890 bool task = false;
14891 bool inscan = false;
14892 enum tree_code code = ERROR_MARK;
14893 tree reduc_id = NULL_TREE;
14894
14895 if (kind == OMP_CLAUSE_REDUCTION && is_omp)
14896 {
14897 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)
14898 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
14899 {
14900 c_parser_consume_token (parser);
14901 c_parser_consume_token (parser);
14902 }
14903 else if (c_parser_next_token_is (parser, CPP_NAME)
14904 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
14905 {
14906 const char *p
14907 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14908 if (strcmp (p, "task") == 0)
14909 task = true;
14910 else if (strcmp (p, "inscan") == 0)
14911 inscan = true;
14912 if (task || inscan)
14913 {
14914 c_parser_consume_token (parser);
14915 c_parser_consume_token (parser);
14916 }
14917 }
14918 }
14919
14920 switch (c_parser_peek_token (parser)->type)
14921 {
14922 case CPP_PLUS:
14923 code = PLUS_EXPR;
14924 break;
14925 case CPP_MULT:
14926 code = MULT_EXPR;
14927 break;
14928 case CPP_MINUS:
14929 code = MINUS_EXPR;
14930 break;
14931 case CPP_AND:
14932 code = BIT_AND_EXPR;
14933 break;
14934 case CPP_XOR:
14935 code = BIT_XOR_EXPR;
14936 break;
14937 case CPP_OR:
14938 code = BIT_IOR_EXPR;
14939 break;
14940 case CPP_AND_AND:
14941 code = TRUTH_ANDIF_EXPR;
14942 break;
14943 case CPP_OR_OR:
14944 code = TRUTH_ORIF_EXPR;
14945 break;
14946 case CPP_NAME:
14947 {
14948 const char *p
14949 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14950 if (strcmp (p, "min") == 0)
14951 {
14952 code = MIN_EXPR;
14953 break;
14954 }
14955 if (strcmp (p, "max") == 0)
14956 {
14957 code = MAX_EXPR;
14958 break;
14959 }
14960 reduc_id = c_parser_peek_token (parser)->value;
14961 break;
14962 }
14963 default:
14964 c_parser_error (parser,
14965 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
14966 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
14967 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
14968 return list;
14969 }
14970 c_parser_consume_token (parser);
14971 reduc_id = c_omp_reduction_id (code, reduc_id);
14972 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14973 {
14974 tree nl, c;
14975
14976 nl = c_parser_omp_variable_list (parser, clause_loc, kind, list);
14977 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
14978 {
14979 tree d = OMP_CLAUSE_DECL (c), type;
14980 if (TREE_CODE (d) != TREE_LIST)
14981 type = TREE_TYPE (d);
14982 else
14983 {
14984 int cnt = 0;
14985 tree t;
14986 for (t = d; TREE_CODE (t) == TREE_LIST; t = TREE_CHAIN (t))
14987 cnt++;
14988 type = TREE_TYPE (t);
14989 while (cnt > 0)
14990 {
14991 if (TREE_CODE (type) != POINTER_TYPE
14992 && TREE_CODE (type) != ARRAY_TYPE)
14993 break;
14994 type = TREE_TYPE (type);
14995 cnt--;
14996 }
14997 }
14998 while (TREE_CODE (type) == ARRAY_TYPE)
14999 type = TREE_TYPE (type);
15000 OMP_CLAUSE_REDUCTION_CODE (c) = code;
15001 if (task)
15002 OMP_CLAUSE_REDUCTION_TASK (c) = 1;
15003 else if (inscan)
15004 OMP_CLAUSE_REDUCTION_INSCAN (c) = 1;
15005 if (code == ERROR_MARK
15006 || !(INTEGRAL_TYPE_P (type)
15007 || TREE_CODE (type) == REAL_TYPE
15008 || TREE_CODE (type) == COMPLEX_TYPE))
15009 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
15010 = c_omp_reduction_lookup (reduc_id,
15011 TYPE_MAIN_VARIANT (type));
15012 }
15013
15014 list = nl;
15015 }
15016 parens.skip_until_found_close (parser);
15017 }
15018 return list;
15019 }
15020
15021 /* OpenMP 2.5:
15022 schedule ( schedule-kind )
15023 schedule ( schedule-kind , expression )
15024
15025 schedule-kind:
15026 static | dynamic | guided | runtime | auto
15027
15028 OpenMP 4.5:
15029 schedule ( schedule-modifier : schedule-kind )
15030 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
15031
15032 schedule-modifier:
15033 simd
15034 monotonic
15035 nonmonotonic */
15036
15037 static tree
15038 c_parser_omp_clause_schedule (c_parser *parser, tree list)
15039 {
15040 tree c, t;
15041 location_t loc = c_parser_peek_token (parser)->location;
15042 int modifiers = 0, nmodifiers = 0;
15043
15044 matching_parens parens;
15045 if (!parens.require_open (parser))
15046 return list;
15047
15048 c = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE);
15049
15050 location_t comma = UNKNOWN_LOCATION;
15051 while (c_parser_next_token_is (parser, CPP_NAME))
15052 {
15053 tree kind = c_parser_peek_token (parser)->value;
15054 const char *p = IDENTIFIER_POINTER (kind);
15055 if (strcmp ("simd", p) == 0)
15056 OMP_CLAUSE_SCHEDULE_SIMD (c) = 1;
15057 else if (strcmp ("monotonic", p) == 0)
15058 modifiers |= OMP_CLAUSE_SCHEDULE_MONOTONIC;
15059 else if (strcmp ("nonmonotonic", p) == 0)
15060 modifiers |= OMP_CLAUSE_SCHEDULE_NONMONOTONIC;
15061 else
15062 break;
15063 comma = UNKNOWN_LOCATION;
15064 c_parser_consume_token (parser);
15065 if (nmodifiers++ == 0
15066 && c_parser_next_token_is (parser, CPP_COMMA))
15067 {
15068 comma = c_parser_peek_token (parser)->location;
15069 c_parser_consume_token (parser);
15070 }
15071 else
15072 {
15073 c_parser_require (parser, CPP_COLON, "expected %<:%>");
15074 break;
15075 }
15076 }
15077 if (comma != UNKNOWN_LOCATION)
15078 error_at (comma, "expected %<:%>");
15079
15080 if ((modifiers & (OMP_CLAUSE_SCHEDULE_MONOTONIC
15081 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
15082 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
15083 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
15084 {
15085 error_at (loc, "both %<monotonic%> and %<nonmonotonic%> modifiers "
15086 "specified");
15087 modifiers = 0;
15088 }
15089
15090 if (c_parser_next_token_is (parser, CPP_NAME))
15091 {
15092 tree kind = c_parser_peek_token (parser)->value;
15093 const char *p = IDENTIFIER_POINTER (kind);
15094
15095 switch (p[0])
15096 {
15097 case 'd':
15098 if (strcmp ("dynamic", p) != 0)
15099 goto invalid_kind;
15100 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
15101 break;
15102
15103 case 'g':
15104 if (strcmp ("guided", p) != 0)
15105 goto invalid_kind;
15106 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
15107 break;
15108
15109 case 'r':
15110 if (strcmp ("runtime", p) != 0)
15111 goto invalid_kind;
15112 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
15113 break;
15114
15115 default:
15116 goto invalid_kind;
15117 }
15118 }
15119 else if (c_parser_next_token_is_keyword (parser, RID_STATIC))
15120 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
15121 else if (c_parser_next_token_is_keyword (parser, RID_AUTO))
15122 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
15123 else
15124 goto invalid_kind;
15125
15126 c_parser_consume_token (parser);
15127 if (c_parser_next_token_is (parser, CPP_COMMA))
15128 {
15129 location_t here;
15130 c_parser_consume_token (parser);
15131
15132 here = c_parser_peek_token (parser)->location;
15133 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15134 expr = convert_lvalue_to_rvalue (here, expr, false, true);
15135 t = expr.value;
15136 t = c_fully_fold (t, false, NULL);
15137
15138 if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
15139 error_at (here, "schedule %<runtime%> does not take "
15140 "a %<chunk_size%> parameter");
15141 else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO)
15142 error_at (here,
15143 "schedule %<auto%> does not take "
15144 "a %<chunk_size%> parameter");
15145 else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE)
15146 {
15147 /* Attempt to statically determine when the number isn't
15148 positive. */
15149 tree s = fold_build2_loc (loc, LE_EXPR, boolean_type_node, t,
15150 build_int_cst (TREE_TYPE (t), 0));
15151 protected_set_expr_location (s, loc);
15152 if (s == boolean_true_node)
15153 {
15154 warning_at (loc, 0,
15155 "chunk size value must be positive");
15156 t = integer_one_node;
15157 }
15158 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
15159 }
15160 else
15161 c_parser_error (parser, "expected integer expression");
15162
15163 parens.skip_until_found_close (parser);
15164 }
15165 else
15166 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
15167 "expected %<,%> or %<)%>");
15168
15169 OMP_CLAUSE_SCHEDULE_KIND (c)
15170 = (enum omp_clause_schedule_kind)
15171 (OMP_CLAUSE_SCHEDULE_KIND (c) | modifiers);
15172
15173 check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule");
15174 OMP_CLAUSE_CHAIN (c) = list;
15175 return c;
15176
15177 invalid_kind:
15178 c_parser_error (parser, "invalid schedule kind");
15179 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
15180 return list;
15181 }
15182
15183 /* OpenMP 2.5:
15184 shared ( variable-list ) */
15185
15186 static tree
15187 c_parser_omp_clause_shared (c_parser *parser, tree list)
15188 {
15189 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_SHARED, list);
15190 }
15191
15192 /* OpenMP 3.0:
15193 untied */
15194
15195 static tree
15196 c_parser_omp_clause_untied (c_parser *parser ATTRIBUTE_UNUSED, tree list)
15197 {
15198 tree c;
15199
15200 /* FIXME: Should we allow duplicates? */
15201 check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied");
15202
15203 c = build_omp_clause (c_parser_peek_token (parser)->location,
15204 OMP_CLAUSE_UNTIED);
15205 OMP_CLAUSE_CHAIN (c) = list;
15206
15207 return c;
15208 }
15209
15210 /* OpenMP 4.0:
15211 inbranch
15212 notinbranch */
15213
15214 static tree
15215 c_parser_omp_clause_branch (c_parser *parser ATTRIBUTE_UNUSED,
15216 enum omp_clause_code code, tree list)
15217 {
15218 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
15219
15220 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15221 OMP_CLAUSE_CHAIN (c) = list;
15222
15223 return c;
15224 }
15225
15226 /* OpenMP 4.0:
15227 parallel
15228 for
15229 sections
15230 taskgroup */
15231
15232 static tree
15233 c_parser_omp_clause_cancelkind (c_parser *parser ATTRIBUTE_UNUSED,
15234 enum omp_clause_code code, tree list)
15235 {
15236 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15237 OMP_CLAUSE_CHAIN (c) = list;
15238
15239 return c;
15240 }
15241
15242 /* OpenMP 4.5:
15243 nogroup */
15244
15245 static tree
15246 c_parser_omp_clause_nogroup (c_parser *parser ATTRIBUTE_UNUSED, tree list)
15247 {
15248 check_no_duplicate_clause (list, OMP_CLAUSE_NOGROUP, "nogroup");
15249 tree c = build_omp_clause (c_parser_peek_token (parser)->location,
15250 OMP_CLAUSE_NOGROUP);
15251 OMP_CLAUSE_CHAIN (c) = list;
15252 return c;
15253 }
15254
15255 /* OpenMP 4.5:
15256 simd
15257 threads */
15258
15259 static tree
15260 c_parser_omp_clause_orderedkind (c_parser *parser ATTRIBUTE_UNUSED,
15261 enum omp_clause_code code, tree list)
15262 {
15263 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
15264 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
15265 OMP_CLAUSE_CHAIN (c) = list;
15266 return c;
15267 }
15268
15269 /* OpenMP 4.0:
15270 num_teams ( expression )
15271
15272 OpenMP 5.1:
15273 num_teams ( expression : expression ) */
15274
15275 static tree
15276 c_parser_omp_clause_num_teams (c_parser *parser, tree list)
15277 {
15278 location_t num_teams_loc = c_parser_peek_token (parser)->location;
15279 matching_parens parens;
15280 if (parens.require_open (parser))
15281 {
15282 location_t upper_loc = c_parser_peek_token (parser)->location;
15283 location_t lower_loc = UNKNOWN_LOCATION;
15284 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15285 expr = convert_lvalue_to_rvalue (upper_loc, expr, false, true);
15286 tree c, upper = expr.value, lower = NULL_TREE;
15287 upper = c_fully_fold (upper, false, NULL);
15288
15289 if (c_parser_next_token_is (parser, CPP_COLON))
15290 {
15291 c_parser_consume_token (parser);
15292 lower_loc = upper_loc;
15293 lower = upper;
15294 upper_loc = c_parser_peek_token (parser)->location;
15295 expr = c_parser_expr_no_commas (parser, NULL);
15296 expr = convert_lvalue_to_rvalue (upper_loc, expr, false, true);
15297 upper = expr.value;
15298 upper = c_fully_fold (upper, false, NULL);
15299 }
15300
15301 parens.skip_until_found_close (parser);
15302
15303 if (!INTEGRAL_TYPE_P (TREE_TYPE (upper))
15304 || (lower && !INTEGRAL_TYPE_P (TREE_TYPE (lower))))
15305 {
15306 c_parser_error (parser, "expected integer expression");
15307 return list;
15308 }
15309
15310 /* Attempt to statically determine when the number isn't positive. */
15311 c = fold_build2_loc (upper_loc, LE_EXPR, boolean_type_node, upper,
15312 build_int_cst (TREE_TYPE (upper), 0));
15313 protected_set_expr_location (c, upper_loc);
15314 if (c == boolean_true_node)
15315 {
15316 warning_at (upper_loc, 0, "%<num_teams%> value must be positive");
15317 upper = integer_one_node;
15318 }
15319 if (lower)
15320 {
15321 c = fold_build2_loc (lower_loc, LE_EXPR, boolean_type_node, lower,
15322 build_int_cst (TREE_TYPE (lower), 0));
15323 protected_set_expr_location (c, lower_loc);
15324 if (c == boolean_true_node)
15325 {
15326 warning_at (lower_loc, 0, "%<num_teams%> value must be positive");
15327 lower = NULL_TREE;
15328 }
15329 else if (TREE_CODE (lower) == INTEGER_CST
15330 && TREE_CODE (upper) == INTEGER_CST
15331 && tree_int_cst_lt (upper, lower))
15332 {
15333 warning_at (lower_loc, 0, "%<num_teams%> lower bound %qE bigger "
15334 "than upper bound %qE", lower, upper);
15335 lower = NULL_TREE;
15336 }
15337 }
15338
15339 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TEAMS, "num_teams");
15340
15341 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
15342 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = upper;
15343 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = lower;
15344 OMP_CLAUSE_CHAIN (c) = list;
15345 list = c;
15346 }
15347
15348 return list;
15349 }
15350
15351 /* OpenMP 4.0:
15352 thread_limit ( expression ) */
15353
15354 static tree
15355 c_parser_omp_clause_thread_limit (c_parser *parser, tree list)
15356 {
15357 location_t num_thread_limit_loc = c_parser_peek_token (parser)->location;
15358 matching_parens parens;
15359 if (parens.require_open (parser))
15360 {
15361 location_t expr_loc = c_parser_peek_token (parser)->location;
15362 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15363 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15364 tree c, t = expr.value;
15365 t = c_fully_fold (t, false, NULL);
15366
15367 parens.skip_until_found_close (parser);
15368
15369 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
15370 {
15371 c_parser_error (parser, "expected integer expression");
15372 return list;
15373 }
15374
15375 /* Attempt to statically determine when the number isn't positive. */
15376 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
15377 build_int_cst (TREE_TYPE (t), 0));
15378 protected_set_expr_location (c, expr_loc);
15379 if (c == boolean_true_node)
15380 {
15381 warning_at (expr_loc, 0, "%<thread_limit%> value must be positive");
15382 t = integer_one_node;
15383 }
15384
15385 check_no_duplicate_clause (list, OMP_CLAUSE_THREAD_LIMIT,
15386 "thread_limit");
15387
15388 c = build_omp_clause (num_thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
15389 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
15390 OMP_CLAUSE_CHAIN (c) = list;
15391 list = c;
15392 }
15393
15394 return list;
15395 }
15396
15397 /* OpenMP 4.0:
15398 aligned ( variable-list )
15399 aligned ( variable-list : constant-expression ) */
15400
15401 static tree
15402 c_parser_omp_clause_aligned (c_parser *parser, tree list)
15403 {
15404 location_t clause_loc = c_parser_peek_token (parser)->location;
15405 tree nl, c;
15406
15407 matching_parens parens;
15408 if (!parens.require_open (parser))
15409 return list;
15410
15411 nl = c_parser_omp_variable_list (parser, clause_loc,
15412 OMP_CLAUSE_ALIGNED, list);
15413
15414 if (c_parser_next_token_is (parser, CPP_COLON))
15415 {
15416 c_parser_consume_token (parser);
15417 location_t expr_loc = c_parser_peek_token (parser)->location;
15418 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15419 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15420 tree alignment = expr.value;
15421 alignment = c_fully_fold (alignment, false, NULL);
15422 if (TREE_CODE (alignment) != INTEGER_CST
15423 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment))
15424 || tree_int_cst_sgn (alignment) != 1)
15425 {
15426 error_at (clause_loc, "%<aligned%> clause alignment expression must "
15427 "be positive constant integer expression");
15428 alignment = NULL_TREE;
15429 }
15430
15431 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15432 OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = alignment;
15433 }
15434
15435 parens.skip_until_found_close (parser);
15436 return nl;
15437 }
15438
15439 /* OpenMP 5.0:
15440 allocate ( variable-list )
15441 allocate ( expression : variable-list )
15442
15443 OpenMP 5.1:
15444 allocate ( allocator-modifier : variable-list )
15445 allocate ( allocator-modifier , allocator-modifier : variable-list )
15446
15447 allocator-modifier:
15448 allocator ( expression )
15449 align ( expression ) */
15450
15451 static tree
15452 c_parser_omp_clause_allocate (c_parser *parser, tree list)
15453 {
15454 location_t clause_loc = c_parser_peek_token (parser)->location;
15455 tree nl, c;
15456 tree allocator = NULL_TREE;
15457 tree align = NULL_TREE;
15458
15459 matching_parens parens;
15460 if (!parens.require_open (parser))
15461 return list;
15462
15463 if ((c_parser_next_token_is_not (parser, CPP_NAME)
15464 && c_parser_next_token_is_not (parser, CPP_KEYWORD))
15465 || (c_parser_peek_2nd_token (parser)->type != CPP_COMMA
15466 && c_parser_peek_2nd_token (parser)->type != CPP_CLOSE_PAREN))
15467 {
15468 bool has_modifiers = false;
15469 tree orig_type = NULL_TREE;
15470 if (c_parser_next_token_is (parser, CPP_NAME)
15471 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
15472 {
15473 unsigned int n = 3;
15474 const char *p
15475 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15476 if ((strcmp (p, "allocator") == 0 || strcmp (p, "align") == 0)
15477 && c_parser_check_balanced_raw_token_sequence (parser, &n)
15478 && (c_parser_peek_nth_token_raw (parser, n)->type
15479 == CPP_CLOSE_PAREN))
15480 {
15481 if (c_parser_peek_nth_token_raw (parser, n + 1)->type
15482 == CPP_COLON)
15483 has_modifiers = true;
15484 else if (c_parser_peek_nth_token_raw (parser, n + 1)->type
15485 == CPP_COMMA
15486 && (c_parser_peek_nth_token_raw (parser, n + 2)->type
15487 == CPP_NAME)
15488 && (c_parser_peek_nth_token_raw (parser, n + 3)->type
15489 == CPP_OPEN_PAREN))
15490 {
15491 c_token *tok = c_parser_peek_nth_token_raw (parser, n + 2);
15492 const char *q = IDENTIFIER_POINTER (tok->value);
15493 n += 4;
15494 if ((strcmp (q, "allocator") == 0
15495 || strcmp (q, "align") == 0)
15496 && c_parser_check_balanced_raw_token_sequence (parser,
15497 &n)
15498 && (c_parser_peek_nth_token_raw (parser, n)->type
15499 == CPP_CLOSE_PAREN)
15500 && (c_parser_peek_nth_token_raw (parser, n + 1)->type
15501 == CPP_COLON))
15502 has_modifiers = true;
15503 }
15504 }
15505 if (has_modifiers)
15506 {
15507 c_parser_consume_token (parser);
15508 matching_parens parens2;;
15509 parens2.require_open (parser);
15510 location_t expr_loc = c_parser_peek_token (parser)->location;
15511 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15512 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15513 if (strcmp (p, "allocator") == 0)
15514 {
15515 allocator = expr.value;
15516 allocator = c_fully_fold (allocator, false, NULL);
15517 orig_type = expr.original_type
15518 ? expr.original_type : TREE_TYPE (allocator);
15519 orig_type = TYPE_MAIN_VARIANT (orig_type);
15520 }
15521 else
15522 {
15523 align = expr.value;
15524 align = c_fully_fold (align, false, NULL);
15525 }
15526 parens2.skip_until_found_close (parser);
15527 if (c_parser_next_token_is (parser, CPP_COMMA))
15528 {
15529 c_parser_consume_token (parser);
15530 c_token *tok = c_parser_peek_token (parser);
15531 const char *q = "";
15532 if (c_parser_next_token_is (parser, CPP_NAME))
15533 q = IDENTIFIER_POINTER (tok->value);
15534 if (strcmp (q, "allocator") != 0 && strcmp (q, "align") != 0)
15535 {
15536 c_parser_error (parser, "expected %<allocator%> or "
15537 "%<align%>");
15538 parens.skip_until_found_close (parser);
15539 return list;
15540 }
15541 else if (strcmp (p, q) == 0)
15542 {
15543 error_at (tok->location, "duplicate %qs modifier", p);
15544 parens.skip_until_found_close (parser);
15545 return list;
15546 }
15547 c_parser_consume_token (parser);
15548 if (!parens2.require_open (parser))
15549 {
15550 parens.skip_until_found_close (parser);
15551 return list;
15552 }
15553 expr_loc = c_parser_peek_token (parser)->location;
15554 expr = c_parser_expr_no_commas (parser, NULL);
15555 expr = convert_lvalue_to_rvalue (expr_loc, expr, false,
15556 true);
15557 if (strcmp (q, "allocator") == 0)
15558 {
15559 allocator = expr.value;
15560 allocator = c_fully_fold (allocator, false, NULL);
15561 orig_type = expr.original_type
15562 ? expr.original_type : TREE_TYPE (allocator);
15563 orig_type = TYPE_MAIN_VARIANT (orig_type);
15564 }
15565 else
15566 {
15567 align = expr.value;
15568 align = c_fully_fold (align, false, NULL);
15569 }
15570 parens2.skip_until_found_close (parser);
15571 }
15572 }
15573 }
15574 if (!has_modifiers)
15575 {
15576 location_t expr_loc = c_parser_peek_token (parser)->location;
15577 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15578 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15579 allocator = expr.value;
15580 allocator = c_fully_fold (allocator, false, NULL);
15581 orig_type = expr.original_type
15582 ? expr.original_type : TREE_TYPE (allocator);
15583 orig_type = TYPE_MAIN_VARIANT (orig_type);
15584 }
15585 if (allocator
15586 && (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
15587 || TREE_CODE (orig_type) != ENUMERAL_TYPE
15588 || (TYPE_NAME (orig_type)
15589 != get_identifier ("omp_allocator_handle_t"))))
15590 {
15591 error_at (clause_loc, "%<allocate%> clause allocator expression "
15592 "has type %qT rather than "
15593 "%<omp_allocator_handle_t%>",
15594 TREE_TYPE (allocator));
15595 allocator = NULL_TREE;
15596 }
15597 if (align
15598 && (!INTEGRAL_TYPE_P (TREE_TYPE (align))
15599 || !tree_fits_uhwi_p (align)
15600 || !integer_pow2p (align)))
15601 {
15602 error_at (clause_loc, "%<allocate%> clause %<align%> modifier "
15603 "argument needs to be positive constant "
15604 "power of two integer expression");
15605 align = NULL_TREE;
15606 }
15607 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15608 {
15609 parens.skip_until_found_close (parser);
15610 return list;
15611 }
15612 }
15613
15614 nl = c_parser_omp_variable_list (parser, clause_loc,
15615 OMP_CLAUSE_ALLOCATE, list);
15616
15617 if (allocator || align)
15618 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15619 {
15620 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
15621 OMP_CLAUSE_ALLOCATE_ALIGN (c) = align;
15622 }
15623
15624 parens.skip_until_found_close (parser);
15625 return nl;
15626 }
15627
15628 /* OpenMP 4.0:
15629 linear ( variable-list )
15630 linear ( variable-list : expression )
15631
15632 OpenMP 4.5:
15633 linear ( modifier ( variable-list ) )
15634 linear ( modifier ( variable-list ) : expression ) */
15635
15636 static tree
15637 c_parser_omp_clause_linear (c_parser *parser, tree list)
15638 {
15639 location_t clause_loc = c_parser_peek_token (parser)->location;
15640 tree nl, c, step;
15641 enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
15642
15643 matching_parens parens;
15644 if (!parens.require_open (parser))
15645 return list;
15646
15647 if (c_parser_next_token_is (parser, CPP_NAME))
15648 {
15649 c_token *tok = c_parser_peek_token (parser);
15650 const char *p = IDENTIFIER_POINTER (tok->value);
15651 if (strcmp ("val", p) == 0)
15652 kind = OMP_CLAUSE_LINEAR_VAL;
15653 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN)
15654 kind = OMP_CLAUSE_LINEAR_DEFAULT;
15655 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
15656 {
15657 c_parser_consume_token (parser);
15658 c_parser_consume_token (parser);
15659 }
15660 }
15661
15662 nl = c_parser_omp_variable_list (parser, clause_loc,
15663 OMP_CLAUSE_LINEAR, list);
15664
15665 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
15666 parens.skip_until_found_close (parser);
15667
15668 if (c_parser_next_token_is (parser, CPP_COLON))
15669 {
15670 c_parser_consume_token (parser);
15671 location_t expr_loc = c_parser_peek_token (parser)->location;
15672 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15673 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15674 step = expr.value;
15675 step = c_fully_fold (step, false, NULL);
15676 if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
15677 {
15678 error_at (clause_loc, "%<linear%> clause step expression must "
15679 "be integral");
15680 step = integer_one_node;
15681 }
15682
15683 }
15684 else
15685 step = integer_one_node;
15686
15687 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
15688 {
15689 OMP_CLAUSE_LINEAR_STEP (c) = step;
15690 OMP_CLAUSE_LINEAR_KIND (c) = kind;
15691 }
15692
15693 parens.skip_until_found_close (parser);
15694 return nl;
15695 }
15696
15697 /* OpenMP 5.0:
15698 nontemporal ( variable-list ) */
15699
15700 static tree
15701 c_parser_omp_clause_nontemporal (c_parser *parser, tree list)
15702 {
15703 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_NONTEMPORAL, list);
15704 }
15705
15706 /* OpenMP 4.0:
15707 safelen ( constant-expression ) */
15708
15709 static tree
15710 c_parser_omp_clause_safelen (c_parser *parser, tree list)
15711 {
15712 location_t clause_loc = c_parser_peek_token (parser)->location;
15713 tree c, t;
15714
15715 matching_parens parens;
15716 if (!parens.require_open (parser))
15717 return list;
15718
15719 location_t expr_loc = c_parser_peek_token (parser)->location;
15720 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15721 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15722 t = expr.value;
15723 t = c_fully_fold (t, false, NULL);
15724 if (TREE_CODE (t) != INTEGER_CST
15725 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
15726 || tree_int_cst_sgn (t) != 1)
15727 {
15728 error_at (clause_loc, "%<safelen%> clause expression must "
15729 "be positive constant integer expression");
15730 t = NULL_TREE;
15731 }
15732
15733 parens.skip_until_found_close (parser);
15734 if (t == NULL_TREE || t == error_mark_node)
15735 return list;
15736
15737 check_no_duplicate_clause (list, OMP_CLAUSE_SAFELEN, "safelen");
15738
15739 c = build_omp_clause (clause_loc, OMP_CLAUSE_SAFELEN);
15740 OMP_CLAUSE_SAFELEN_EXPR (c) = t;
15741 OMP_CLAUSE_CHAIN (c) = list;
15742 return c;
15743 }
15744
15745 /* OpenMP 4.0:
15746 simdlen ( constant-expression ) */
15747
15748 static tree
15749 c_parser_omp_clause_simdlen (c_parser *parser, tree list)
15750 {
15751 location_t clause_loc = c_parser_peek_token (parser)->location;
15752 tree c, t;
15753
15754 matching_parens parens;
15755 if (!parens.require_open (parser))
15756 return list;
15757
15758 location_t expr_loc = c_parser_peek_token (parser)->location;
15759 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15760 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15761 t = expr.value;
15762 t = c_fully_fold (t, false, NULL);
15763 if (TREE_CODE (t) != INTEGER_CST
15764 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
15765 || tree_int_cst_sgn (t) != 1)
15766 {
15767 error_at (clause_loc, "%<simdlen%> clause expression must "
15768 "be positive constant integer expression");
15769 t = NULL_TREE;
15770 }
15771
15772 parens.skip_until_found_close (parser);
15773 if (t == NULL_TREE || t == error_mark_node)
15774 return list;
15775
15776 check_no_duplicate_clause (list, OMP_CLAUSE_SIMDLEN, "simdlen");
15777
15778 c = build_omp_clause (clause_loc, OMP_CLAUSE_SIMDLEN);
15779 OMP_CLAUSE_SIMDLEN_EXPR (c) = t;
15780 OMP_CLAUSE_CHAIN (c) = list;
15781 return c;
15782 }
15783
15784 /* OpenMP 4.5:
15785 vec:
15786 identifier [+/- integer]
15787 vec , identifier [+/- integer]
15788 */
15789
15790 static tree
15791 c_parser_omp_clause_depend_sink (c_parser *parser, location_t clause_loc,
15792 tree list)
15793 {
15794 tree vec = NULL;
15795 if (c_parser_next_token_is_not (parser, CPP_NAME)
15796 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
15797 {
15798 c_parser_error (parser, "expected identifier");
15799 return list;
15800 }
15801
15802 while (c_parser_next_token_is (parser, CPP_NAME)
15803 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
15804 {
15805 tree t = lookup_name (c_parser_peek_token (parser)->value);
15806 tree addend = NULL;
15807
15808 if (t == NULL_TREE)
15809 {
15810 undeclared_variable (c_parser_peek_token (parser)->location,
15811 c_parser_peek_token (parser)->value);
15812 t = error_mark_node;
15813 }
15814
15815 c_parser_consume_token (parser);
15816
15817 bool neg = false;
15818 if (c_parser_next_token_is (parser, CPP_MINUS))
15819 neg = true;
15820 else if (!c_parser_next_token_is (parser, CPP_PLUS))
15821 {
15822 addend = integer_zero_node;
15823 neg = false;
15824 goto add_to_vector;
15825 }
15826 c_parser_consume_token (parser);
15827
15828 if (c_parser_next_token_is_not (parser, CPP_NUMBER))
15829 {
15830 c_parser_error (parser, "expected integer");
15831 return list;
15832 }
15833
15834 addend = c_parser_peek_token (parser)->value;
15835 if (TREE_CODE (addend) != INTEGER_CST)
15836 {
15837 c_parser_error (parser, "expected integer");
15838 return list;
15839 }
15840 c_parser_consume_token (parser);
15841
15842 add_to_vector:
15843 if (t != error_mark_node)
15844 {
15845 vec = tree_cons (addend, t, vec);
15846 if (neg)
15847 OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec) = 1;
15848 }
15849
15850 if (c_parser_next_token_is_not (parser, CPP_COMMA)
15851 || c_parser_peek_2nd_token (parser)->type != CPP_NAME
15852 || c_parser_peek_2nd_token (parser)->id_kind != C_ID_ID)
15853 break;
15854
15855 c_parser_consume_token (parser);
15856 }
15857
15858 if (vec == NULL_TREE)
15859 return list;
15860
15861 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
15862 OMP_CLAUSE_DEPEND_KIND (u) = OMP_CLAUSE_DEPEND_SINK;
15863 OMP_CLAUSE_DECL (u) = nreverse (vec);
15864 OMP_CLAUSE_CHAIN (u) = list;
15865 return u;
15866 }
15867
15868 /* OpenMP 5.0:
15869 iterators ( iterators-definition )
15870
15871 iterators-definition:
15872 iterator-specifier
15873 iterator-specifier , iterators-definition
15874
15875 iterator-specifier:
15876 identifier = range-specification
15877 iterator-type identifier = range-specification
15878
15879 range-specification:
15880 begin : end
15881 begin : end : step */
15882
15883 static tree
15884 c_parser_omp_iterators (c_parser *parser)
15885 {
15886 tree ret = NULL_TREE, *last = &ret;
15887 c_parser_consume_token (parser);
15888
15889 push_scope ();
15890
15891 matching_parens parens;
15892 if (!parens.require_open (parser))
15893 return error_mark_node;
15894
15895 do
15896 {
15897 tree iter_type = NULL_TREE, type_expr = NULL_TREE;
15898 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
15899 {
15900 struct c_type_name *type = c_parser_type_name (parser);
15901 if (type != NULL)
15902 iter_type = groktypename (type, &type_expr, NULL);
15903 }
15904 if (iter_type == NULL_TREE)
15905 iter_type = integer_type_node;
15906
15907 location_t loc = c_parser_peek_token (parser)->location;
15908 if (!c_parser_next_token_is (parser, CPP_NAME))
15909 {
15910 c_parser_error (parser, "expected identifier");
15911 break;
15912 }
15913
15914 tree id = c_parser_peek_token (parser)->value;
15915 c_parser_consume_token (parser);
15916
15917 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
15918 break;
15919
15920 location_t eloc = c_parser_peek_token (parser)->location;
15921 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15922 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
15923 tree begin = expr.value;
15924
15925 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
15926 break;
15927
15928 eloc = c_parser_peek_token (parser)->location;
15929 expr = c_parser_expr_no_commas (parser, NULL);
15930 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
15931 tree end = expr.value;
15932
15933 tree step = integer_one_node;
15934 if (c_parser_next_token_is (parser, CPP_COLON))
15935 {
15936 c_parser_consume_token (parser);
15937 eloc = c_parser_peek_token (parser)->location;
15938 expr = c_parser_expr_no_commas (parser, NULL);
15939 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
15940 step = expr.value;
15941 }
15942
15943 tree iter_var = build_decl (loc, VAR_DECL, id, iter_type);
15944 DECL_ARTIFICIAL (iter_var) = 1;
15945 DECL_CONTEXT (iter_var) = current_function_decl;
15946 pushdecl (iter_var);
15947
15948 *last = make_tree_vec (6);
15949 TREE_VEC_ELT (*last, 0) = iter_var;
15950 TREE_VEC_ELT (*last, 1) = begin;
15951 TREE_VEC_ELT (*last, 2) = end;
15952 TREE_VEC_ELT (*last, 3) = step;
15953 last = &TREE_CHAIN (*last);
15954
15955 if (c_parser_next_token_is (parser, CPP_COMMA))
15956 {
15957 c_parser_consume_token (parser);
15958 continue;
15959 }
15960 break;
15961 }
15962 while (1);
15963
15964 parens.skip_until_found_close (parser);
15965 return ret ? ret : error_mark_node;
15966 }
15967
15968 /* OpenMP 5.0:
15969 affinity ( [aff-modifier :] variable-list )
15970 aff-modifier:
15971 iterator ( iterators-definition ) */
15972
15973 static tree
15974 c_parser_omp_clause_affinity (c_parser *parser, tree list)
15975 {
15976 location_t clause_loc = c_parser_peek_token (parser)->location;
15977 tree nl, iterators = NULL_TREE;
15978
15979 matching_parens parens;
15980 if (!parens.require_open (parser))
15981 return list;
15982
15983 if (c_parser_next_token_is (parser, CPP_NAME))
15984 {
15985 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15986 bool parse_iter = ((strcmp ("iterator", p) == 0)
15987 && (c_parser_peek_2nd_token (parser)->type
15988 == CPP_OPEN_PAREN));
15989 if (parse_iter)
15990 {
15991 unsigned n = 3;
15992 parse_iter = (c_parser_check_balanced_raw_token_sequence (parser, &n)
15993 && (c_parser_peek_nth_token_raw (parser, n)->type
15994 == CPP_CLOSE_PAREN)
15995 && (c_parser_peek_nth_token_raw (parser, n + 1)->type
15996 == CPP_COLON));
15997 }
15998 if (parse_iter)
15999 {
16000 iterators = c_parser_omp_iterators (parser);
16001 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16002 {
16003 if (iterators)
16004 pop_scope ();
16005 parens.skip_until_found_close (parser);
16006 return list;
16007 }
16008 }
16009 }
16010 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_AFFINITY,
16011 list);
16012 if (iterators)
16013 {
16014 tree block = pop_scope ();
16015 if (iterators != error_mark_node)
16016 {
16017 TREE_VEC_ELT (iterators, 5) = block;
16018 for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
16019 OMP_CLAUSE_DECL (c) = build_tree_list (iterators,
16020 OMP_CLAUSE_DECL (c));
16021 }
16022 }
16023
16024 parens.skip_until_found_close (parser);
16025 return nl;
16026 }
16027
16028
16029 /* OpenMP 4.0:
16030 depend ( depend-kind: variable-list )
16031
16032 depend-kind:
16033 in | out | inout
16034
16035 OpenMP 4.5:
16036 depend ( source )
16037
16038 depend ( sink : vec )
16039
16040 OpenMP 5.0:
16041 depend ( depend-modifier , depend-kind: variable-list )
16042
16043 depend-kind:
16044 in | out | inout | mutexinoutset | depobj
16045
16046 depend-modifier:
16047 iterator ( iterators-definition ) */
16048
16049 static tree
16050 c_parser_omp_clause_depend (c_parser *parser, tree list)
16051 {
16052 location_t clause_loc = c_parser_peek_token (parser)->location;
16053 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_LAST;
16054 tree nl, c, iterators = NULL_TREE;
16055
16056 matching_parens parens;
16057 if (!parens.require_open (parser))
16058 return list;
16059
16060 do
16061 {
16062 if (c_parser_next_token_is_not (parser, CPP_NAME))
16063 goto invalid_kind;
16064
16065 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16066 if (strcmp ("iterator", p) == 0 && iterators == NULL_TREE)
16067 {
16068 iterators = c_parser_omp_iterators (parser);
16069 c_parser_require (parser, CPP_COMMA, "expected %<,%>");
16070 continue;
16071 }
16072 if (strcmp ("in", p) == 0)
16073 kind = OMP_CLAUSE_DEPEND_IN;
16074 else if (strcmp ("inout", p) == 0)
16075 kind = OMP_CLAUSE_DEPEND_INOUT;
16076 else if (strcmp ("mutexinoutset", p) == 0)
16077 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
16078 else if (strcmp ("out", p) == 0)
16079 kind = OMP_CLAUSE_DEPEND_OUT;
16080 else if (strcmp ("depobj", p) == 0)
16081 kind = OMP_CLAUSE_DEPEND_DEPOBJ;
16082 else if (strcmp ("sink", p) == 0)
16083 kind = OMP_CLAUSE_DEPEND_SINK;
16084 else if (strcmp ("source", p) == 0)
16085 kind = OMP_CLAUSE_DEPEND_SOURCE;
16086 else
16087 goto invalid_kind;
16088 break;
16089 }
16090 while (1);
16091
16092 c_parser_consume_token (parser);
16093
16094 if (iterators
16095 && (kind == OMP_CLAUSE_DEPEND_SOURCE || kind == OMP_CLAUSE_DEPEND_SINK))
16096 {
16097 pop_scope ();
16098 error_at (clause_loc, "%<iterator%> modifier incompatible with %qs",
16099 kind == OMP_CLAUSE_DEPEND_SOURCE ? "source" : "sink");
16100 iterators = NULL_TREE;
16101 }
16102
16103 if (kind == OMP_CLAUSE_DEPEND_SOURCE)
16104 {
16105 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
16106 OMP_CLAUSE_DEPEND_KIND (c) = kind;
16107 OMP_CLAUSE_DECL (c) = NULL_TREE;
16108 OMP_CLAUSE_CHAIN (c) = list;
16109 parens.skip_until_found_close (parser);
16110 return c;
16111 }
16112
16113 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
16114 goto resync_fail;
16115
16116 if (kind == OMP_CLAUSE_DEPEND_SINK)
16117 nl = c_parser_omp_clause_depend_sink (parser, clause_loc, list);
16118 else
16119 {
16120 nl = c_parser_omp_variable_list (parser, clause_loc,
16121 OMP_CLAUSE_DEPEND, list);
16122
16123 if (iterators)
16124 {
16125 tree block = pop_scope ();
16126 if (iterators == error_mark_node)
16127 iterators = NULL_TREE;
16128 else
16129 TREE_VEC_ELT (iterators, 5) = block;
16130 }
16131
16132 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
16133 {
16134 OMP_CLAUSE_DEPEND_KIND (c) = kind;
16135 if (iterators)
16136 OMP_CLAUSE_DECL (c)
16137 = build_tree_list (iterators, OMP_CLAUSE_DECL (c));
16138 }
16139 }
16140
16141 parens.skip_until_found_close (parser);
16142 return nl;
16143
16144 invalid_kind:
16145 c_parser_error (parser, "invalid depend kind");
16146 resync_fail:
16147 parens.skip_until_found_close (parser);
16148 if (iterators)
16149 pop_scope ();
16150 return list;
16151 }
16152
16153 /* OpenMP 4.0:
16154 map ( map-kind: variable-list )
16155 map ( variable-list )
16156
16157 map-kind:
16158 alloc | to | from | tofrom
16159
16160 OpenMP 4.5:
16161 map-kind:
16162 alloc | to | from | tofrom | release | delete
16163
16164 map ( always [,] map-kind: variable-list )
16165
16166 OpenMP 5.0:
16167 map ( [map-type-modifier[,] ...] map-kind: variable-list )
16168
16169 map-type-modifier:
16170 always | close */
16171
16172 static tree
16173 c_parser_omp_clause_map (c_parser *parser, tree list)
16174 {
16175 location_t clause_loc = c_parser_peek_token (parser)->location;
16176 enum gomp_map_kind kind = GOMP_MAP_TOFROM;
16177 tree nl, c;
16178
16179 matching_parens parens;
16180 if (!parens.require_open (parser))
16181 return list;
16182
16183 int pos = 1;
16184 int map_kind_pos = 0;
16185 while (c_parser_peek_nth_token_raw (parser, pos)->type == CPP_NAME)
16186 {
16187 if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COLON)
16188 {
16189 map_kind_pos = pos;
16190 break;
16191 }
16192
16193 if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COMMA)
16194 pos++;
16195 pos++;
16196 }
16197
16198 int always_modifier = 0;
16199 int close_modifier = 0;
16200 for (int pos = 1; pos < map_kind_pos; ++pos)
16201 {
16202 c_token *tok = c_parser_peek_token (parser);
16203
16204 if (tok->type == CPP_COMMA)
16205 {
16206 c_parser_consume_token (parser);
16207 continue;
16208 }
16209
16210 const char *p = IDENTIFIER_POINTER (tok->value);
16211 if (strcmp ("always", p) == 0)
16212 {
16213 if (always_modifier)
16214 {
16215 c_parser_error (parser, "too many %<always%> modifiers");
16216 parens.skip_until_found_close (parser);
16217 return list;
16218 }
16219 always_modifier++;
16220 }
16221 else if (strcmp ("close", p) == 0)
16222 {
16223 if (close_modifier)
16224 {
16225 c_parser_error (parser, "too many %<close%> modifiers");
16226 parens.skip_until_found_close (parser);
16227 return list;
16228 }
16229 close_modifier++;
16230 }
16231 else
16232 {
16233 c_parser_error (parser, "%<#pragma omp target%> with "
16234 "modifier other than %<always%> or "
16235 "%<close%> on %<map%> clause");
16236 parens.skip_until_found_close (parser);
16237 return list;
16238 }
16239
16240 c_parser_consume_token (parser);
16241 }
16242
16243 if (c_parser_next_token_is (parser, CPP_NAME)
16244 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
16245 {
16246 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16247 if (strcmp ("alloc", p) == 0)
16248 kind = GOMP_MAP_ALLOC;
16249 else if (strcmp ("to", p) == 0)
16250 kind = always_modifier ? GOMP_MAP_ALWAYS_TO : GOMP_MAP_TO;
16251 else if (strcmp ("from", p) == 0)
16252 kind = always_modifier ? GOMP_MAP_ALWAYS_FROM : GOMP_MAP_FROM;
16253 else if (strcmp ("tofrom", p) == 0)
16254 kind = always_modifier ? GOMP_MAP_ALWAYS_TOFROM : GOMP_MAP_TOFROM;
16255 else if (strcmp ("release", p) == 0)
16256 kind = GOMP_MAP_RELEASE;
16257 else if (strcmp ("delete", p) == 0)
16258 kind = GOMP_MAP_DELETE;
16259 else
16260 {
16261 c_parser_error (parser, "invalid map kind");
16262 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
16263 "expected %<)%>");
16264 return list;
16265 }
16266 c_parser_consume_token (parser);
16267 c_parser_consume_token (parser);
16268 }
16269
16270 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_MAP, list,
16271 true);
16272
16273 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
16274 OMP_CLAUSE_SET_MAP_KIND (c, kind);
16275
16276 parens.skip_until_found_close (parser);
16277 return nl;
16278 }
16279
16280 /* OpenMP 4.0:
16281 device ( expression )
16282
16283 OpenMP 5.0:
16284 device ( [device-modifier :] integer-expression )
16285
16286 device-modifier:
16287 ancestor | device_num */
16288
16289 static tree
16290 c_parser_omp_clause_device (c_parser *parser, tree list)
16291 {
16292 location_t clause_loc = c_parser_peek_token (parser)->location;
16293 location_t expr_loc;
16294 c_expr expr;
16295 tree c, t;
16296 bool ancestor = false;
16297
16298 matching_parens parens;
16299 if (!parens.require_open (parser))
16300 return list;
16301
16302 if (c_parser_next_token_is (parser, CPP_NAME)
16303 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
16304 {
16305 c_token *tok = c_parser_peek_token (parser);
16306 const char *p = IDENTIFIER_POINTER (tok->value);
16307 if (strcmp ("ancestor", p) == 0)
16308 {
16309 /* A requires directive with the reverse_offload clause must be
16310 specified. */
16311 if ((omp_requires_mask & OMP_REQUIRES_REVERSE_OFFLOAD) == 0)
16312 {
16313 error_at (tok->location, "%<ancestor%> device modifier not "
16314 "preceded by %<requires%> directive "
16315 "with %<reverse_offload%> clause");
16316 parens.skip_until_found_close (parser);
16317 return list;
16318 }
16319 ancestor = true;
16320 }
16321 else if (strcmp ("device_num", p) == 0)
16322 ;
16323 else
16324 {
16325 error_at (tok->location, "expected %<ancestor%> or %<device_num%>");
16326 parens.skip_until_found_close (parser);
16327 return list;
16328 }
16329 c_parser_consume_token (parser);
16330 c_parser_consume_token (parser);
16331 }
16332
16333 expr_loc = c_parser_peek_token (parser)->location;
16334 expr = c_parser_expr_no_commas (parser, NULL);
16335 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16336 t = expr.value;
16337 t = c_fully_fold (t, false, NULL);
16338
16339 parens.skip_until_found_close (parser);
16340
16341 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
16342 {
16343 c_parser_error (parser, "expected integer expression");
16344 return list;
16345 }
16346 if (ancestor && TREE_CODE (t) == INTEGER_CST && !integer_onep (t))
16347 {
16348 error_at (expr_loc, "the %<device%> clause expression must evaluate to "
16349 "%<1%>");
16350 return list;
16351 }
16352
16353 check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE, "device");
16354
16355 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE);
16356
16357 OMP_CLAUSE_DEVICE_ID (c) = t;
16358 OMP_CLAUSE_CHAIN (c) = list;
16359 OMP_CLAUSE_DEVICE_ANCESTOR (c) = ancestor;
16360
16361 list = c;
16362 return list;
16363 }
16364
16365 /* OpenMP 4.0:
16366 dist_schedule ( static )
16367 dist_schedule ( static , expression ) */
16368
16369 static tree
16370 c_parser_omp_clause_dist_schedule (c_parser *parser, tree list)
16371 {
16372 tree c, t = NULL_TREE;
16373 location_t loc = c_parser_peek_token (parser)->location;
16374
16375 matching_parens parens;
16376 if (!parens.require_open (parser))
16377 return list;
16378
16379 if (!c_parser_next_token_is_keyword (parser, RID_STATIC))
16380 {
16381 c_parser_error (parser, "invalid dist_schedule kind");
16382 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
16383 "expected %<)%>");
16384 return list;
16385 }
16386
16387 c_parser_consume_token (parser);
16388 if (c_parser_next_token_is (parser, CPP_COMMA))
16389 {
16390 c_parser_consume_token (parser);
16391
16392 location_t expr_loc = c_parser_peek_token (parser)->location;
16393 c_expr expr = c_parser_expr_no_commas (parser, NULL);
16394 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
16395 t = expr.value;
16396 t = c_fully_fold (t, false, NULL);
16397 parens.skip_until_found_close (parser);
16398 }
16399 else
16400 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
16401 "expected %<,%> or %<)%>");
16402
16403 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
16404 "dist_schedule"); */
16405 if (omp_find_clause (list, OMP_CLAUSE_DIST_SCHEDULE))
16406 warning_at (loc, 0, "too many %qs clauses", "dist_schedule");
16407 if (t == error_mark_node)
16408 return list;
16409
16410 c = build_omp_clause (loc, OMP_CLAUSE_DIST_SCHEDULE);
16411 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t;
16412 OMP_CLAUSE_CHAIN (c) = list;
16413 return c;
16414 }
16415
16416 /* OpenMP 4.0:
16417 proc_bind ( proc-bind-kind )
16418
16419 proc-bind-kind:
16420 primary | master | close | spread
16421 where OpenMP 5.1 added 'primary' and deprecated the alias 'master'. */
16422
16423 static tree
16424 c_parser_omp_clause_proc_bind (c_parser *parser, tree list)
16425 {
16426 location_t clause_loc = c_parser_peek_token (parser)->location;
16427 enum omp_clause_proc_bind_kind kind;
16428 tree c;
16429
16430 matching_parens parens;
16431 if (!parens.require_open (parser))
16432 return list;
16433
16434 if (c_parser_next_token_is (parser, CPP_NAME))
16435 {
16436 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16437 if (strcmp ("primary", p) == 0)
16438 kind = OMP_CLAUSE_PROC_BIND_PRIMARY;
16439 else if (strcmp ("master", p) == 0)
16440 kind = OMP_CLAUSE_PROC_BIND_MASTER;
16441 else if (strcmp ("close", p) == 0)
16442 kind = OMP_CLAUSE_PROC_BIND_CLOSE;
16443 else if (strcmp ("spread", p) == 0)
16444 kind = OMP_CLAUSE_PROC_BIND_SPREAD;
16445 else
16446 goto invalid_kind;
16447 }
16448 else
16449 goto invalid_kind;
16450
16451 check_no_duplicate_clause (list, OMP_CLAUSE_PROC_BIND, "proc_bind");
16452 c_parser_consume_token (parser);
16453 parens.skip_until_found_close (parser);
16454 c = build_omp_clause (clause_loc, OMP_CLAUSE_PROC_BIND);
16455 OMP_CLAUSE_PROC_BIND_KIND (c) = kind;
16456 OMP_CLAUSE_CHAIN (c) = list;
16457 return c;
16458
16459 invalid_kind:
16460 c_parser_error (parser, "invalid proc_bind kind");
16461 parens.skip_until_found_close (parser);
16462 return list;
16463 }
16464
16465 /* OpenMP 5.0:
16466 device_type ( host | nohost | any ) */
16467
16468 static tree
16469 c_parser_omp_clause_device_type (c_parser *parser, tree list)
16470 {
16471 location_t clause_loc = c_parser_peek_token (parser)->location;
16472 enum omp_clause_device_type_kind kind;
16473 tree c;
16474
16475 matching_parens parens;
16476 if (!parens.require_open (parser))
16477 return list;
16478
16479 if (c_parser_next_token_is (parser, CPP_NAME))
16480 {
16481 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16482 if (strcmp ("host", p) == 0)
16483 kind = OMP_CLAUSE_DEVICE_TYPE_HOST;
16484 else if (strcmp ("nohost", p) == 0)
16485 kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
16486 else if (strcmp ("any", p) == 0)
16487 kind = OMP_CLAUSE_DEVICE_TYPE_ANY;
16488 else
16489 goto invalid_kind;
16490 }
16491 else
16492 goto invalid_kind;
16493
16494 /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE,
16495 "device_type"); */
16496 c_parser_consume_token (parser);
16497 parens.skip_until_found_close (parser);
16498 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE_TYPE);
16499 OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind;
16500 OMP_CLAUSE_CHAIN (c) = list;
16501 return c;
16502
16503 invalid_kind:
16504 c_parser_error (parser, "expected %<host%>, %<nohost%> or %<any%>");
16505 parens.skip_until_found_close (parser);
16506 return list;
16507 }
16508
16509 /* OpenMP 4.0:
16510 to ( variable-list ) */
16511
16512 static tree
16513 c_parser_omp_clause_to (c_parser *parser, tree list)
16514 {
16515 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO, list, true);
16516 }
16517
16518 /* OpenMP 4.0:
16519 from ( variable-list ) */
16520
16521 static tree
16522 c_parser_omp_clause_from (c_parser *parser, tree list)
16523 {
16524 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FROM, list, true);
16525 }
16526
16527 /* OpenMP 4.0:
16528 uniform ( variable-list ) */
16529
16530 static tree
16531 c_parser_omp_clause_uniform (c_parser *parser, tree list)
16532 {
16533 /* The clauses location. */
16534 location_t loc = c_parser_peek_token (parser)->location;
16535
16536 matching_parens parens;
16537 if (parens.require_open (parser))
16538 {
16539 list = c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_UNIFORM,
16540 list);
16541 parens.skip_until_found_close (parser);
16542 }
16543 return list;
16544 }
16545
16546 /* OpenMP 5.0:
16547 detach ( event-handle ) */
16548
16549 static tree
16550 c_parser_omp_clause_detach (c_parser *parser, tree list)
16551 {
16552 matching_parens parens;
16553 location_t clause_loc = c_parser_peek_token (parser)->location;
16554
16555 if (!parens.require_open (parser))
16556 return list;
16557
16558 if (c_parser_next_token_is_not (parser, CPP_NAME)
16559 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
16560 {
16561 c_parser_error (parser, "expected identifier");
16562 parens.skip_until_found_close (parser);
16563 return list;
16564 }
16565
16566 tree t = lookup_name (c_parser_peek_token (parser)->value);
16567 if (t == NULL_TREE)
16568 {
16569 undeclared_variable (c_parser_peek_token (parser)->location,
16570 c_parser_peek_token (parser)->value);
16571 parens.skip_until_found_close (parser);
16572 return list;
16573 }
16574 c_parser_consume_token (parser);
16575
16576 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (t));
16577 if (!INTEGRAL_TYPE_P (type)
16578 || TREE_CODE (type) != ENUMERAL_TYPE
16579 || TYPE_NAME (type) != get_identifier ("omp_event_handle_t"))
16580 {
16581 error_at (clause_loc, "%<detach%> clause event handle "
16582 "has type %qT rather than "
16583 "%<omp_event_handle_t%>",
16584 type);
16585 parens.skip_until_found_close (parser);
16586 return list;
16587 }
16588
16589 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DETACH);
16590 OMP_CLAUSE_DECL (u) = t;
16591 OMP_CLAUSE_CHAIN (u) = list;
16592 parens.skip_until_found_close (parser);
16593 return u;
16594 }
16595
16596 /* Parse all OpenACC clauses. The set clauses allowed by the directive
16597 is a bitmask in MASK. Return the list of clauses found. */
16598
16599 static tree
16600 c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask,
16601 const char *where, bool finish_p = true)
16602 {
16603 tree clauses = NULL;
16604 bool first = true;
16605
16606 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
16607 {
16608 location_t here;
16609 pragma_omp_clause c_kind;
16610 const char *c_name;
16611 tree prev = clauses;
16612
16613 if (!first && c_parser_next_token_is (parser, CPP_COMMA))
16614 c_parser_consume_token (parser);
16615
16616 here = c_parser_peek_token (parser)->location;
16617 c_kind = c_parser_omp_clause_name (parser);
16618
16619 switch (c_kind)
16620 {
16621 case PRAGMA_OACC_CLAUSE_ASYNC:
16622 clauses = c_parser_oacc_clause_async (parser, clauses);
16623 c_name = "async";
16624 break;
16625 case PRAGMA_OACC_CLAUSE_AUTO:
16626 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_AUTO,
16627 clauses);
16628 c_name = "auto";
16629 break;
16630 case PRAGMA_OACC_CLAUSE_ATTACH:
16631 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16632 c_name = "attach";
16633 break;
16634 case PRAGMA_OACC_CLAUSE_COLLAPSE:
16635 clauses = c_parser_omp_clause_collapse (parser, clauses);
16636 c_name = "collapse";
16637 break;
16638 case PRAGMA_OACC_CLAUSE_COPY:
16639 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16640 c_name = "copy";
16641 break;
16642 case PRAGMA_OACC_CLAUSE_COPYIN:
16643 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16644 c_name = "copyin";
16645 break;
16646 case PRAGMA_OACC_CLAUSE_COPYOUT:
16647 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16648 c_name = "copyout";
16649 break;
16650 case PRAGMA_OACC_CLAUSE_CREATE:
16651 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16652 c_name = "create";
16653 break;
16654 case PRAGMA_OACC_CLAUSE_DELETE:
16655 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16656 c_name = "delete";
16657 break;
16658 case PRAGMA_OMP_CLAUSE_DEFAULT:
16659 clauses = c_parser_omp_clause_default (parser, clauses, true);
16660 c_name = "default";
16661 break;
16662 case PRAGMA_OACC_CLAUSE_DETACH:
16663 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16664 c_name = "detach";
16665 break;
16666 case PRAGMA_OACC_CLAUSE_DEVICE:
16667 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16668 c_name = "device";
16669 break;
16670 case PRAGMA_OACC_CLAUSE_DEVICEPTR:
16671 clauses = c_parser_oacc_data_clause_deviceptr (parser, clauses);
16672 c_name = "deviceptr";
16673 break;
16674 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
16675 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16676 c_name = "device_resident";
16677 break;
16678 case PRAGMA_OACC_CLAUSE_FINALIZE:
16679 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_FINALIZE,
16680 clauses);
16681 c_name = "finalize";
16682 break;
16683 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE:
16684 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
16685 c_name = "firstprivate";
16686 break;
16687 case PRAGMA_OACC_CLAUSE_GANG:
16688 c_name = "gang";
16689 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_GANG,
16690 c_name, clauses);
16691 break;
16692 case PRAGMA_OACC_CLAUSE_HOST:
16693 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16694 c_name = "host";
16695 break;
16696 case PRAGMA_OACC_CLAUSE_IF:
16697 clauses = c_parser_omp_clause_if (parser, clauses, false);
16698 c_name = "if";
16699 break;
16700 case PRAGMA_OACC_CLAUSE_IF_PRESENT:
16701 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_IF_PRESENT,
16702 clauses);
16703 c_name = "if_present";
16704 break;
16705 case PRAGMA_OACC_CLAUSE_INDEPENDENT:
16706 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_INDEPENDENT,
16707 clauses);
16708 c_name = "independent";
16709 break;
16710 case PRAGMA_OACC_CLAUSE_LINK:
16711 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16712 c_name = "link";
16713 break;
16714 case PRAGMA_OACC_CLAUSE_NO_CREATE:
16715 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16716 c_name = "no_create";
16717 break;
16718 case PRAGMA_OACC_CLAUSE_NOHOST:
16719 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_NOHOST,
16720 clauses);
16721 c_name = "nohost";
16722 break;
16723 case PRAGMA_OACC_CLAUSE_NUM_GANGS:
16724 clauses = c_parser_oacc_single_int_clause (parser,
16725 OMP_CLAUSE_NUM_GANGS,
16726 clauses);
16727 c_name = "num_gangs";
16728 break;
16729 case PRAGMA_OACC_CLAUSE_NUM_WORKERS:
16730 clauses = c_parser_oacc_single_int_clause (parser,
16731 OMP_CLAUSE_NUM_WORKERS,
16732 clauses);
16733 c_name = "num_workers";
16734 break;
16735 case PRAGMA_OACC_CLAUSE_PRESENT:
16736 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
16737 c_name = "present";
16738 break;
16739 case PRAGMA_OACC_CLAUSE_PRIVATE:
16740 clauses = c_parser_omp_clause_private (parser, clauses);
16741 c_name = "private";
16742 break;
16743 case PRAGMA_OACC_CLAUSE_REDUCTION:
16744 clauses
16745 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
16746 false, clauses);
16747 c_name = "reduction";
16748 break;
16749 case PRAGMA_OACC_CLAUSE_SEQ:
16750 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_SEQ,
16751 clauses);
16752 c_name = "seq";
16753 break;
16754 case PRAGMA_OACC_CLAUSE_TILE:
16755 clauses = c_parser_oacc_clause_tile (parser, clauses);
16756 c_name = "tile";
16757 break;
16758 case PRAGMA_OACC_CLAUSE_USE_DEVICE:
16759 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
16760 c_name = "use_device";
16761 break;
16762 case PRAGMA_OACC_CLAUSE_VECTOR:
16763 c_name = "vector";
16764 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_VECTOR,
16765 c_name, clauses);
16766 break;
16767 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH:
16768 clauses = c_parser_oacc_single_int_clause (parser,
16769 OMP_CLAUSE_VECTOR_LENGTH,
16770 clauses);
16771 c_name = "vector_length";
16772 break;
16773 case PRAGMA_OACC_CLAUSE_WAIT:
16774 clauses = c_parser_oacc_clause_wait (parser, clauses);
16775 c_name = "wait";
16776 break;
16777 case PRAGMA_OACC_CLAUSE_WORKER:
16778 c_name = "worker";
16779 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_WORKER,
16780 c_name, clauses);
16781 break;
16782 default:
16783 c_parser_error (parser, "expected %<#pragma acc%> clause");
16784 goto saw_error;
16785 }
16786
16787 first = false;
16788
16789 if (((mask >> c_kind) & 1) == 0)
16790 {
16791 /* Remove the invalid clause(s) from the list to avoid
16792 confusing the rest of the compiler. */
16793 clauses = prev;
16794 error_at (here, "%qs is not valid for %qs", c_name, where);
16795 }
16796 }
16797
16798 saw_error:
16799 c_parser_skip_to_pragma_eol (parser);
16800
16801 if (finish_p)
16802 return c_finish_omp_clauses (clauses, C_ORT_ACC);
16803
16804 return clauses;
16805 }
16806
16807 /* Parse all OpenMP clauses. The set clauses allowed by the directive
16808 is a bitmask in MASK. Return the list of clauses found.
16809 FINISH_P set if c_finish_omp_clauses should be called.
16810 NESTED non-zero if clauses should be terminated by closing paren instead
16811 of end of pragma. If it is 2, additionally commas are required in between
16812 the clauses. */
16813
16814 static tree
16815 c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
16816 const char *where, bool finish_p = true,
16817 int nested = 0)
16818 {
16819 tree clauses = NULL;
16820 bool first = true;
16821
16822 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
16823 {
16824 location_t here;
16825 pragma_omp_clause c_kind;
16826 const char *c_name;
16827 tree prev = clauses;
16828
16829 if (nested && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
16830 break;
16831
16832 if (!first)
16833 {
16834 if (c_parser_next_token_is (parser, CPP_COMMA))
16835 c_parser_consume_token (parser);
16836 else if (nested == 2)
16837 error_at (c_parser_peek_token (parser)->location,
16838 "clauses in %<simd%> trait should be separated "
16839 "by %<,%>");
16840 }
16841
16842 here = c_parser_peek_token (parser)->location;
16843 c_kind = c_parser_omp_clause_name (parser);
16844
16845 switch (c_kind)
16846 {
16847 case PRAGMA_OMP_CLAUSE_BIND:
16848 clauses = c_parser_omp_clause_bind (parser, clauses);
16849 c_name = "bind";
16850 break;
16851 case PRAGMA_OMP_CLAUSE_COLLAPSE:
16852 clauses = c_parser_omp_clause_collapse (parser, clauses);
16853 c_name = "collapse";
16854 break;
16855 case PRAGMA_OMP_CLAUSE_COPYIN:
16856 clauses = c_parser_omp_clause_copyin (parser, clauses);
16857 c_name = "copyin";
16858 break;
16859 case PRAGMA_OMP_CLAUSE_COPYPRIVATE:
16860 clauses = c_parser_omp_clause_copyprivate (parser, clauses);
16861 c_name = "copyprivate";
16862 break;
16863 case PRAGMA_OMP_CLAUSE_DEFAULT:
16864 clauses = c_parser_omp_clause_default (parser, clauses, false);
16865 c_name = "default";
16866 break;
16867 case PRAGMA_OMP_CLAUSE_DETACH:
16868 clauses = c_parser_omp_clause_detach (parser, clauses);
16869 c_name = "detach";
16870 break;
16871 case PRAGMA_OMP_CLAUSE_FILTER:
16872 clauses = c_parser_omp_clause_filter (parser, clauses);
16873 c_name = "filter";
16874 break;
16875 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
16876 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
16877 c_name = "firstprivate";
16878 break;
16879 case PRAGMA_OMP_CLAUSE_FINAL:
16880 clauses = c_parser_omp_clause_final (parser, clauses);
16881 c_name = "final";
16882 break;
16883 case PRAGMA_OMP_CLAUSE_GRAINSIZE:
16884 clauses = c_parser_omp_clause_grainsize (parser, clauses);
16885 c_name = "grainsize";
16886 break;
16887 case PRAGMA_OMP_CLAUSE_HINT:
16888 clauses = c_parser_omp_clause_hint (parser, clauses);
16889 c_name = "hint";
16890 break;
16891 case PRAGMA_OMP_CLAUSE_DEFAULTMAP:
16892 clauses = c_parser_omp_clause_defaultmap (parser, clauses);
16893 c_name = "defaultmap";
16894 break;
16895 case PRAGMA_OMP_CLAUSE_IF:
16896 clauses = c_parser_omp_clause_if (parser, clauses, true);
16897 c_name = "if";
16898 break;
16899 case PRAGMA_OMP_CLAUSE_IN_REDUCTION:
16900 clauses
16901 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION,
16902 true, clauses);
16903 c_name = "in_reduction";
16904 break;
16905 case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
16906 clauses = c_parser_omp_clause_lastprivate (parser, clauses);
16907 c_name = "lastprivate";
16908 break;
16909 case PRAGMA_OMP_CLAUSE_MERGEABLE:
16910 clauses = c_parser_omp_clause_mergeable (parser, clauses);
16911 c_name = "mergeable";
16912 break;
16913 case PRAGMA_OMP_CLAUSE_NOWAIT:
16914 clauses = c_parser_omp_clause_nowait (parser, clauses);
16915 c_name = "nowait";
16916 break;
16917 case PRAGMA_OMP_CLAUSE_NUM_TASKS:
16918 clauses = c_parser_omp_clause_num_tasks (parser, clauses);
16919 c_name = "num_tasks";
16920 break;
16921 case PRAGMA_OMP_CLAUSE_NUM_THREADS:
16922 clauses = c_parser_omp_clause_num_threads (parser, clauses);
16923 c_name = "num_threads";
16924 break;
16925 case PRAGMA_OMP_CLAUSE_ORDER:
16926 clauses = c_parser_omp_clause_order (parser, clauses);
16927 c_name = "order";
16928 break;
16929 case PRAGMA_OMP_CLAUSE_ORDERED:
16930 clauses = c_parser_omp_clause_ordered (parser, clauses);
16931 c_name = "ordered";
16932 break;
16933 case PRAGMA_OMP_CLAUSE_PRIORITY:
16934 clauses = c_parser_omp_clause_priority (parser, clauses);
16935 c_name = "priority";
16936 break;
16937 case PRAGMA_OMP_CLAUSE_PRIVATE:
16938 clauses = c_parser_omp_clause_private (parser, clauses);
16939 c_name = "private";
16940 break;
16941 case PRAGMA_OMP_CLAUSE_REDUCTION:
16942 clauses
16943 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
16944 true, clauses);
16945 c_name = "reduction";
16946 break;
16947 case PRAGMA_OMP_CLAUSE_SCHEDULE:
16948 clauses = c_parser_omp_clause_schedule (parser, clauses);
16949 c_name = "schedule";
16950 break;
16951 case PRAGMA_OMP_CLAUSE_SHARED:
16952 clauses = c_parser_omp_clause_shared (parser, clauses);
16953 c_name = "shared";
16954 break;
16955 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION:
16956 clauses
16957 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_TASK_REDUCTION,
16958 true, clauses);
16959 c_name = "task_reduction";
16960 break;
16961 case PRAGMA_OMP_CLAUSE_UNTIED:
16962 clauses = c_parser_omp_clause_untied (parser, clauses);
16963 c_name = "untied";
16964 break;
16965 case PRAGMA_OMP_CLAUSE_INBRANCH:
16966 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_INBRANCH,
16967 clauses);
16968 c_name = "inbranch";
16969 break;
16970 case PRAGMA_OMP_CLAUSE_NONTEMPORAL:
16971 clauses = c_parser_omp_clause_nontemporal (parser, clauses);
16972 c_name = "nontemporal";
16973 break;
16974 case PRAGMA_OMP_CLAUSE_NOTINBRANCH:
16975 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_NOTINBRANCH,
16976 clauses);
16977 c_name = "notinbranch";
16978 break;
16979 case PRAGMA_OMP_CLAUSE_PARALLEL:
16980 clauses
16981 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_PARALLEL,
16982 clauses);
16983 c_name = "parallel";
16984 if (!first)
16985 {
16986 clause_not_first:
16987 error_at (here, "%qs must be the first clause of %qs",
16988 c_name, where);
16989 clauses = prev;
16990 }
16991 break;
16992 case PRAGMA_OMP_CLAUSE_FOR:
16993 clauses
16994 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_FOR,
16995 clauses);
16996 c_name = "for";
16997 if (!first)
16998 goto clause_not_first;
16999 break;
17000 case PRAGMA_OMP_CLAUSE_SECTIONS:
17001 clauses
17002 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_SECTIONS,
17003 clauses);
17004 c_name = "sections";
17005 if (!first)
17006 goto clause_not_first;
17007 break;
17008 case PRAGMA_OMP_CLAUSE_TASKGROUP:
17009 clauses
17010 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_TASKGROUP,
17011 clauses);
17012 c_name = "taskgroup";
17013 if (!first)
17014 goto clause_not_first;
17015 break;
17016 case PRAGMA_OMP_CLAUSE_LINK:
17017 clauses
17018 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LINK, clauses);
17019 c_name = "link";
17020 break;
17021 case PRAGMA_OMP_CLAUSE_TO:
17022 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0)
17023 clauses
17024 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO_DECLARE,
17025 clauses);
17026 else
17027 clauses = c_parser_omp_clause_to (parser, clauses);
17028 c_name = "to";
17029 break;
17030 case PRAGMA_OMP_CLAUSE_FROM:
17031 clauses = c_parser_omp_clause_from (parser, clauses);
17032 c_name = "from";
17033 break;
17034 case PRAGMA_OMP_CLAUSE_UNIFORM:
17035 clauses = c_parser_omp_clause_uniform (parser, clauses);
17036 c_name = "uniform";
17037 break;
17038 case PRAGMA_OMP_CLAUSE_NUM_TEAMS:
17039 clauses = c_parser_omp_clause_num_teams (parser, clauses);
17040 c_name = "num_teams";
17041 break;
17042 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT:
17043 clauses = c_parser_omp_clause_thread_limit (parser, clauses);
17044 c_name = "thread_limit";
17045 break;
17046 case PRAGMA_OMP_CLAUSE_ALIGNED:
17047 clauses = c_parser_omp_clause_aligned (parser, clauses);
17048 c_name = "aligned";
17049 break;
17050 case PRAGMA_OMP_CLAUSE_ALLOCATE:
17051 clauses = c_parser_omp_clause_allocate (parser, clauses);
17052 c_name = "allocate";
17053 break;
17054 case PRAGMA_OMP_CLAUSE_LINEAR:
17055 clauses = c_parser_omp_clause_linear (parser, clauses);
17056 c_name = "linear";
17057 break;
17058 case PRAGMA_OMP_CLAUSE_AFFINITY:
17059 clauses = c_parser_omp_clause_affinity (parser, clauses);
17060 c_name = "affinity";
17061 break;
17062 case PRAGMA_OMP_CLAUSE_DEPEND:
17063 clauses = c_parser_omp_clause_depend (parser, clauses);
17064 c_name = "depend";
17065 break;
17066 case PRAGMA_OMP_CLAUSE_MAP:
17067 clauses = c_parser_omp_clause_map (parser, clauses);
17068 c_name = "map";
17069 break;
17070 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR:
17071 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
17072 c_name = "use_device_ptr";
17073 break;
17074 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR:
17075 clauses = c_parser_omp_clause_use_device_addr (parser, clauses);
17076 c_name = "use_device_addr";
17077 break;
17078 case PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR:
17079 clauses = c_parser_omp_clause_has_device_addr (parser, clauses);
17080 c_name = "has_device_addr";
17081 break;
17082 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR:
17083 clauses = c_parser_omp_clause_is_device_ptr (parser, clauses);
17084 c_name = "is_device_ptr";
17085 break;
17086 case PRAGMA_OMP_CLAUSE_DEVICE:
17087 clauses = c_parser_omp_clause_device (parser, clauses);
17088 c_name = "device";
17089 break;
17090 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE:
17091 clauses = c_parser_omp_clause_dist_schedule (parser, clauses);
17092 c_name = "dist_schedule";
17093 break;
17094 case PRAGMA_OMP_CLAUSE_PROC_BIND:
17095 clauses = c_parser_omp_clause_proc_bind (parser, clauses);
17096 c_name = "proc_bind";
17097 break;
17098 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE:
17099 clauses = c_parser_omp_clause_device_type (parser, clauses);
17100 c_name = "device_type";
17101 break;
17102 case PRAGMA_OMP_CLAUSE_SAFELEN:
17103 clauses = c_parser_omp_clause_safelen (parser, clauses);
17104 c_name = "safelen";
17105 break;
17106 case PRAGMA_OMP_CLAUSE_SIMDLEN:
17107 clauses = c_parser_omp_clause_simdlen (parser, clauses);
17108 c_name = "simdlen";
17109 break;
17110 case PRAGMA_OMP_CLAUSE_NOGROUP:
17111 clauses = c_parser_omp_clause_nogroup (parser, clauses);
17112 c_name = "nogroup";
17113 break;
17114 case PRAGMA_OMP_CLAUSE_THREADS:
17115 clauses
17116 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_THREADS,
17117 clauses);
17118 c_name = "threads";
17119 break;
17120 case PRAGMA_OMP_CLAUSE_SIMD:
17121 clauses
17122 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_SIMD,
17123 clauses);
17124 c_name = "simd";
17125 break;
17126 default:
17127 c_parser_error (parser, "expected %<#pragma omp%> clause");
17128 goto saw_error;
17129 }
17130
17131 first = false;
17132
17133 if (((mask >> c_kind) & 1) == 0)
17134 {
17135 /* Remove the invalid clause(s) from the list to avoid
17136 confusing the rest of the compiler. */
17137 clauses = prev;
17138 error_at (here, "%qs is not valid for %qs", c_name, where);
17139 }
17140 }
17141
17142 saw_error:
17143 if (!nested)
17144 c_parser_skip_to_pragma_eol (parser);
17145
17146 if (finish_p)
17147 {
17148 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)) != 0)
17149 return c_finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD);
17150 return c_finish_omp_clauses (clauses, C_ORT_OMP);
17151 }
17152
17153 return clauses;
17154 }
17155
17156 /* OpenACC 2.0, OpenMP 2.5:
17157 structured-block:
17158 statement
17159
17160 In practice, we're also interested in adding the statement to an
17161 outer node. So it is convenient if we work around the fact that
17162 c_parser_statement calls add_stmt. */
17163
17164 static tree
17165 c_parser_omp_structured_block (c_parser *parser, bool *if_p)
17166 {
17167 tree stmt = push_stmt_list ();
17168 c_parser_statement (parser, if_p);
17169 return pop_stmt_list (stmt);
17170 }
17171
17172 /* OpenACC 2.0:
17173 # pragma acc cache (variable-list) new-line
17174
17175 LOC is the location of the #pragma token.
17176 */
17177
17178 static tree
17179 c_parser_oacc_cache (location_t loc, c_parser *parser)
17180 {
17181 tree stmt, clauses;
17182
17183 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE__CACHE_, NULL);
17184 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
17185
17186 c_parser_skip_to_pragma_eol (parser);
17187
17188 stmt = make_node (OACC_CACHE);
17189 TREE_TYPE (stmt) = void_type_node;
17190 OACC_CACHE_CLAUSES (stmt) = clauses;
17191 SET_EXPR_LOCATION (stmt, loc);
17192 add_stmt (stmt);
17193
17194 return stmt;
17195 }
17196
17197 /* OpenACC 2.0:
17198 # pragma acc data oacc-data-clause[optseq] new-line
17199 structured-block
17200
17201 LOC is the location of the #pragma token.
17202 */
17203
17204 #define OACC_DATA_CLAUSE_MASK \
17205 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17206 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17207 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17208 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17209 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17210 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17211 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17212 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17213 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
17214
17215 static tree
17216 c_parser_oacc_data (location_t loc, c_parser *parser, bool *if_p)
17217 {
17218 tree stmt, clauses, block;
17219
17220 clauses = c_parser_oacc_all_clauses (parser, OACC_DATA_CLAUSE_MASK,
17221 "#pragma acc data");
17222
17223 block = c_begin_omp_parallel ();
17224 add_stmt (c_parser_omp_structured_block (parser, if_p));
17225
17226 stmt = c_finish_oacc_data (loc, clauses, block);
17227
17228 return stmt;
17229 }
17230
17231 /* OpenACC 2.0:
17232 # pragma acc declare oacc-data-clause[optseq] new-line
17233 */
17234
17235 #define OACC_DECLARE_CLAUSE_MASK \
17236 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17237 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17238 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17239 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17240 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17241 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
17242 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
17243 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
17244
17245 static void
17246 c_parser_oacc_declare (c_parser *parser)
17247 {
17248 location_t pragma_loc = c_parser_peek_token (parser)->location;
17249 tree clauses, stmt, t, decl;
17250
17251 bool error = false;
17252
17253 c_parser_consume_pragma (parser);
17254
17255 clauses = c_parser_oacc_all_clauses (parser, OACC_DECLARE_CLAUSE_MASK,
17256 "#pragma acc declare");
17257 if (!clauses)
17258 {
17259 error_at (pragma_loc,
17260 "no valid clauses specified in %<#pragma acc declare%>");
17261 return;
17262 }
17263
17264 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
17265 {
17266 location_t loc = OMP_CLAUSE_LOCATION (t);
17267 decl = OMP_CLAUSE_DECL (t);
17268 if (!DECL_P (decl))
17269 {
17270 error_at (loc, "array section in %<#pragma acc declare%>");
17271 error = true;
17272 continue;
17273 }
17274
17275 switch (OMP_CLAUSE_MAP_KIND (t))
17276 {
17277 case GOMP_MAP_FIRSTPRIVATE_POINTER:
17278 case GOMP_MAP_ALLOC:
17279 case GOMP_MAP_TO:
17280 case GOMP_MAP_FORCE_DEVICEPTR:
17281 case GOMP_MAP_DEVICE_RESIDENT:
17282 break;
17283
17284 case GOMP_MAP_LINK:
17285 if (!global_bindings_p ()
17286 && (TREE_STATIC (decl)
17287 || !DECL_EXTERNAL (decl)))
17288 {
17289 error_at (loc,
17290 "%qD must be a global variable in "
17291 "%<#pragma acc declare link%>",
17292 decl);
17293 error = true;
17294 continue;
17295 }
17296 break;
17297
17298 default:
17299 if (global_bindings_p ())
17300 {
17301 error_at (loc, "invalid OpenACC clause at file scope");
17302 error = true;
17303 continue;
17304 }
17305 if (DECL_EXTERNAL (decl))
17306 {
17307 error_at (loc,
17308 "invalid use of %<extern%> variable %qD "
17309 "in %<#pragma acc declare%>", decl);
17310 error = true;
17311 continue;
17312 }
17313 else if (TREE_PUBLIC (decl))
17314 {
17315 error_at (loc,
17316 "invalid use of %<global%> variable %qD "
17317 "in %<#pragma acc declare%>", decl);
17318 error = true;
17319 continue;
17320 }
17321 break;
17322 }
17323
17324 if (!c_check_in_current_scope (decl))
17325 {
17326 error_at (loc,
17327 "%qD must be a variable declared in the same scope as "
17328 "%<#pragma acc declare%>", decl);
17329 error = true;
17330 continue;
17331 }
17332
17333 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl))
17334 || lookup_attribute ("omp declare target link",
17335 DECL_ATTRIBUTES (decl)))
17336 {
17337 error_at (loc, "variable %qD used more than once with "
17338 "%<#pragma acc declare%>", decl);
17339 error = true;
17340 continue;
17341 }
17342
17343 if (!error)
17344 {
17345 tree id;
17346
17347 if (OMP_CLAUSE_MAP_KIND (t) == GOMP_MAP_LINK)
17348 id = get_identifier ("omp declare target link");
17349 else
17350 id = get_identifier ("omp declare target");
17351
17352 DECL_ATTRIBUTES (decl)
17353 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
17354
17355 if (global_bindings_p ())
17356 {
17357 symtab_node *node = symtab_node::get (decl);
17358 if (node != NULL)
17359 {
17360 node->offloadable = 1;
17361 if (ENABLE_OFFLOADING)
17362 {
17363 g->have_offload = true;
17364 if (is_a <varpool_node *> (node))
17365 vec_safe_push (offload_vars, decl);
17366 }
17367 }
17368 }
17369 }
17370 }
17371
17372 if (error || global_bindings_p ())
17373 return;
17374
17375 stmt = make_node (OACC_DECLARE);
17376 TREE_TYPE (stmt) = void_type_node;
17377 OACC_DECLARE_CLAUSES (stmt) = clauses;
17378 SET_EXPR_LOCATION (stmt, pragma_loc);
17379
17380 add_stmt (stmt);
17381
17382 return;
17383 }
17384
17385 /* OpenACC 2.0:
17386 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
17387
17388 or
17389
17390 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
17391
17392
17393 LOC is the location of the #pragma token.
17394 */
17395
17396 #define OACC_ENTER_DATA_CLAUSE_MASK \
17397 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17398 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17399 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17400 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17401 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17402 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17403
17404 #define OACC_EXIT_DATA_CLAUSE_MASK \
17405 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17406 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17407 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17408 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
17409 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \
17410 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \
17411 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17412
17413 static void
17414 c_parser_oacc_enter_exit_data (c_parser *parser, bool enter)
17415 {
17416 location_t loc = c_parser_peek_token (parser)->location;
17417 tree clauses, stmt;
17418 const char *p = "";
17419
17420 c_parser_consume_pragma (parser);
17421
17422 if (c_parser_next_token_is (parser, CPP_NAME))
17423 {
17424 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17425 c_parser_consume_token (parser);
17426 }
17427
17428 if (strcmp (p, "data") != 0)
17429 {
17430 error_at (loc, "expected %<data%> after %<#pragma acc %s%>",
17431 enter ? "enter" : "exit");
17432 parser->error = true;
17433 c_parser_skip_to_pragma_eol (parser);
17434 return;
17435 }
17436
17437 if (enter)
17438 clauses = c_parser_oacc_all_clauses (parser, OACC_ENTER_DATA_CLAUSE_MASK,
17439 "#pragma acc enter data");
17440 else
17441 clauses = c_parser_oacc_all_clauses (parser, OACC_EXIT_DATA_CLAUSE_MASK,
17442 "#pragma acc exit data");
17443
17444 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
17445 {
17446 error_at (loc, "%<#pragma acc %s data%> has no data movement clause",
17447 enter ? "enter" : "exit");
17448 return;
17449 }
17450
17451 stmt = enter ? make_node (OACC_ENTER_DATA) : make_node (OACC_EXIT_DATA);
17452 TREE_TYPE (stmt) = void_type_node;
17453 OMP_STANDALONE_CLAUSES (stmt) = clauses;
17454 SET_EXPR_LOCATION (stmt, loc);
17455 add_stmt (stmt);
17456 }
17457
17458
17459 /* OpenACC 2.0:
17460 # pragma acc host_data oacc-data-clause[optseq] new-line
17461 structured-block
17462 */
17463
17464 #define OACC_HOST_DATA_CLAUSE_MASK \
17465 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) \
17466 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17467 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
17468
17469 static tree
17470 c_parser_oacc_host_data (location_t loc, c_parser *parser, bool *if_p)
17471 {
17472 tree stmt, clauses, block;
17473
17474 clauses = c_parser_oacc_all_clauses (parser, OACC_HOST_DATA_CLAUSE_MASK,
17475 "#pragma acc host_data");
17476
17477 block = c_begin_omp_parallel ();
17478 add_stmt (c_parser_omp_structured_block (parser, if_p));
17479 stmt = c_finish_oacc_host_data (loc, clauses, block);
17480 return stmt;
17481 }
17482
17483
17484 /* OpenACC 2.0:
17485
17486 # pragma acc loop oacc-loop-clause[optseq] new-line
17487 structured-block
17488
17489 LOC is the location of the #pragma token.
17490 */
17491
17492 #define OACC_LOOP_CLAUSE_MASK \
17493 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
17494 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17495 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17496 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
17497 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
17498 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
17499 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
17500 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
17501 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
17502 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
17503 static tree
17504 c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name,
17505 omp_clause_mask mask, tree *cclauses, bool *if_p)
17506 {
17507 bool is_parallel = ((mask >> PRAGMA_OACC_CLAUSE_REDUCTION) & 1) == 1;
17508
17509 strcat (p_name, " loop");
17510 mask |= OACC_LOOP_CLAUSE_MASK;
17511
17512 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name,
17513 cclauses == NULL);
17514 if (cclauses)
17515 {
17516 clauses = c_oacc_split_loop_clauses (clauses, cclauses, is_parallel);
17517 if (*cclauses)
17518 *cclauses = c_finish_omp_clauses (*cclauses, C_ORT_ACC);
17519 if (clauses)
17520 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
17521 }
17522
17523 tree block = c_begin_compound_stmt (true);
17524 tree stmt = c_parser_omp_for_loop (loc, parser, OACC_LOOP, clauses, NULL,
17525 if_p);
17526 block = c_end_compound_stmt (loc, block, true);
17527 add_stmt (block);
17528
17529 return stmt;
17530 }
17531
17532 /* OpenACC 2.0:
17533 # pragma acc kernels oacc-kernels-clause[optseq] new-line
17534 structured-block
17535
17536 or
17537
17538 # pragma acc parallel oacc-parallel-clause[optseq] new-line
17539 structured-block
17540
17541 OpenACC 2.6:
17542
17543 # pragma acc serial oacc-serial-clause[optseq] new-line
17544 structured-block
17545
17546 LOC is the location of the #pragma token.
17547 */
17548
17549 #define OACC_KERNELS_CLAUSE_MASK \
17550 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17551 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17552 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17553 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17554 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17555 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17556 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17557 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17558 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17559 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17560 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
17561 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
17562 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17563 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
17564 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17565
17566 #define OACC_PARALLEL_CLAUSE_MASK \
17567 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17568 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17569 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17570 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17571 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17572 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17573 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17574 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17575 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17576 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17577 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17578 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
17579 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
17580 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
17581 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17582 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17583 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
17584 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17585
17586 #define OACC_SERIAL_CLAUSE_MASK \
17587 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17588 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
17589 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
17590 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
17591 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
17592 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
17593 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
17594 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
17595 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17596 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
17597 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
17598 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
17599 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
17600 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
17601 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17602
17603 static tree
17604 c_parser_oacc_compute (location_t loc, c_parser *parser,
17605 enum pragma_kind p_kind, char *p_name, bool *if_p)
17606 {
17607 omp_clause_mask mask;
17608 enum tree_code code;
17609 switch (p_kind)
17610 {
17611 case PRAGMA_OACC_KERNELS:
17612 strcat (p_name, " kernels");
17613 mask = OACC_KERNELS_CLAUSE_MASK;
17614 code = OACC_KERNELS;
17615 break;
17616 case PRAGMA_OACC_PARALLEL:
17617 strcat (p_name, " parallel");
17618 mask = OACC_PARALLEL_CLAUSE_MASK;
17619 code = OACC_PARALLEL;
17620 break;
17621 case PRAGMA_OACC_SERIAL:
17622 strcat (p_name, " serial");
17623 mask = OACC_SERIAL_CLAUSE_MASK;
17624 code = OACC_SERIAL;
17625 break;
17626 default:
17627 gcc_unreachable ();
17628 }
17629
17630 if (c_parser_next_token_is (parser, CPP_NAME))
17631 {
17632 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17633 if (strcmp (p, "loop") == 0)
17634 {
17635 c_parser_consume_token (parser);
17636 tree block = c_begin_omp_parallel ();
17637 tree clauses;
17638 c_parser_oacc_loop (loc, parser, p_name, mask, &clauses, if_p);
17639 return c_finish_omp_construct (loc, code, block, clauses);
17640 }
17641 }
17642
17643 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name);
17644
17645 tree block = c_begin_omp_parallel ();
17646 add_stmt (c_parser_omp_structured_block (parser, if_p));
17647
17648 return c_finish_omp_construct (loc, code, block, clauses);
17649 }
17650
17651 /* OpenACC 2.0:
17652 # pragma acc routine oacc-routine-clause[optseq] new-line
17653 function-definition
17654
17655 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
17656 */
17657
17658 #define OACC_ROUTINE_CLAUSE_MASK \
17659 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
17660 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
17661 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
17662 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
17663 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NOHOST) )
17664
17665 /* Parse an OpenACC routine directive. For named directives, we apply
17666 immediately to the named function. For unnamed ones we then parse
17667 a declaration or definition, which must be for a function. */
17668
17669 static void
17670 c_parser_oacc_routine (c_parser *parser, enum pragma_context context)
17671 {
17672 gcc_checking_assert (context == pragma_external);
17673
17674 oacc_routine_data data;
17675 data.error_seen = false;
17676 data.fndecl_seen = false;
17677 data.loc = c_parser_peek_token (parser)->location;
17678
17679 c_parser_consume_pragma (parser);
17680
17681 /* Look for optional '( name )'. */
17682 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
17683 {
17684 c_parser_consume_token (parser); /* '(' */
17685
17686 tree decl = NULL_TREE;
17687 c_token *name_token = c_parser_peek_token (parser);
17688 location_t name_loc = name_token->location;
17689 if (name_token->type == CPP_NAME
17690 && (name_token->id_kind == C_ID_ID
17691 || name_token->id_kind == C_ID_TYPENAME))
17692 {
17693 decl = lookup_name (name_token->value);
17694 if (!decl)
17695 error_at (name_loc,
17696 "%qE has not been declared", name_token->value);
17697 c_parser_consume_token (parser);
17698 }
17699 else
17700 c_parser_error (parser, "expected function name");
17701
17702 if (!decl
17703 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
17704 {
17705 c_parser_skip_to_pragma_eol (parser, false);
17706 return;
17707 }
17708
17709 data.clauses
17710 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
17711 "#pragma acc routine");
17712 /* The clauses are in reverse order; fix that to make later diagnostic
17713 emission easier. */
17714 data.clauses = nreverse (data.clauses);
17715
17716 if (TREE_CODE (decl) != FUNCTION_DECL)
17717 {
17718 error_at (name_loc, "%qD does not refer to a function", decl);
17719 return;
17720 }
17721
17722 c_finish_oacc_routine (&data, decl, false);
17723 }
17724 else /* No optional '( name )'. */
17725 {
17726 data.clauses
17727 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
17728 "#pragma acc routine");
17729 /* The clauses are in reverse order; fix that to make later diagnostic
17730 emission easier. */
17731 data.clauses = nreverse (data.clauses);
17732
17733 /* Emit a helpful diagnostic if there's another pragma following this
17734 one. Also don't allow a static assertion declaration, as in the
17735 following we'll just parse a *single* "declaration or function
17736 definition", and the static assertion counts an one. */
17737 if (c_parser_next_token_is (parser, CPP_PRAGMA)
17738 || c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
17739 {
17740 error_at (data.loc,
17741 "%<#pragma acc routine%> not immediately followed by"
17742 " function declaration or definition");
17743 /* ..., and then just keep going. */
17744 return;
17745 }
17746
17747 /* We only have to consider the pragma_external case here. */
17748 if (c_parser_next_token_is (parser, CPP_KEYWORD)
17749 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
17750 {
17751 int ext = disable_extension_diagnostics ();
17752 do
17753 c_parser_consume_token (parser);
17754 while (c_parser_next_token_is (parser, CPP_KEYWORD)
17755 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
17756 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
17757 NULL, NULL, false, NULL, &data);
17758 restore_extension_diagnostics (ext);
17759 }
17760 else
17761 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
17762 NULL, NULL, false, NULL, &data);
17763 }
17764 }
17765
17766 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
17767 IS_DEFN is true if we're applying it to the definition. */
17768
17769 static void
17770 c_finish_oacc_routine (struct oacc_routine_data *data, tree fndecl,
17771 bool is_defn)
17772 {
17773 /* Keep going if we're in error reporting mode. */
17774 if (data->error_seen
17775 || fndecl == error_mark_node)
17776 return;
17777
17778 if (data->fndecl_seen)
17779 {
17780 error_at (data->loc,
17781 "%<#pragma acc routine%> not immediately followed by"
17782 " a single function declaration or definition");
17783 data->error_seen = true;
17784 return;
17785 }
17786 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
17787 {
17788 error_at (data->loc,
17789 "%<#pragma acc routine%> not immediately followed by"
17790 " function declaration or definition");
17791 data->error_seen = true;
17792 return;
17793 }
17794
17795 int compatible
17796 = oacc_verify_routine_clauses (fndecl, &data->clauses, data->loc,
17797 "#pragma acc routine");
17798 if (compatible < 0)
17799 {
17800 data->error_seen = true;
17801 return;
17802 }
17803 if (compatible > 0)
17804 {
17805 }
17806 else
17807 {
17808 if (TREE_USED (fndecl) || (!is_defn && DECL_SAVED_TREE (fndecl)))
17809 {
17810 error_at (data->loc,
17811 TREE_USED (fndecl)
17812 ? G_("%<#pragma acc routine%> must be applied before use")
17813 : G_("%<#pragma acc routine%> must be applied before"
17814 " definition"));
17815 data->error_seen = true;
17816 return;
17817 }
17818
17819 /* Set the routine's level of parallelism. */
17820 tree dims = oacc_build_routine_dims (data->clauses);
17821 oacc_replace_fn_attrib (fndecl, dims);
17822
17823 /* Add an "omp declare target" attribute. */
17824 DECL_ATTRIBUTES (fndecl)
17825 = tree_cons (get_identifier ("omp declare target"),
17826 data->clauses, DECL_ATTRIBUTES (fndecl));
17827 }
17828
17829 /* Remember that we've used this "#pragma acc routine". */
17830 data->fndecl_seen = true;
17831 }
17832
17833 /* OpenACC 2.0:
17834 # pragma acc update oacc-update-clause[optseq] new-line
17835 */
17836
17837 #define OACC_UPDATE_CLAUSE_MASK \
17838 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
17839 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
17840 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
17841 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
17842 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
17843 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
17844
17845 static void
17846 c_parser_oacc_update (c_parser *parser)
17847 {
17848 location_t loc = c_parser_peek_token (parser)->location;
17849
17850 c_parser_consume_pragma (parser);
17851
17852 tree clauses = c_parser_oacc_all_clauses (parser, OACC_UPDATE_CLAUSE_MASK,
17853 "#pragma acc update");
17854 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
17855 {
17856 error_at (loc,
17857 "%<#pragma acc update%> must contain at least one "
17858 "%<device%> or %<host%> or %<self%> clause");
17859 return;
17860 }
17861
17862 if (parser->error)
17863 return;
17864
17865 tree stmt = make_node (OACC_UPDATE);
17866 TREE_TYPE (stmt) = void_type_node;
17867 OACC_UPDATE_CLAUSES (stmt) = clauses;
17868 SET_EXPR_LOCATION (stmt, loc);
17869 add_stmt (stmt);
17870 }
17871
17872 /* OpenACC 2.0:
17873 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
17874
17875 LOC is the location of the #pragma token.
17876 */
17877
17878 #define OACC_WAIT_CLAUSE_MASK \
17879 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
17880
17881 static tree
17882 c_parser_oacc_wait (location_t loc, c_parser *parser, char *p_name)
17883 {
17884 tree clauses, list = NULL_TREE, stmt = NULL_TREE;
17885
17886 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
17887 list = c_parser_oacc_wait_list (parser, loc, list);
17888
17889 strcpy (p_name, " wait");
17890 clauses = c_parser_oacc_all_clauses (parser, OACC_WAIT_CLAUSE_MASK, p_name);
17891 stmt = c_finish_oacc_wait (loc, list, clauses);
17892 add_stmt (stmt);
17893
17894 return stmt;
17895 }
17896
17897 /* OpenMP 5.0:
17898 # pragma omp allocate (list) [allocator(allocator)] */
17899
17900 static void
17901 c_parser_omp_allocate (location_t loc, c_parser *parser)
17902 {
17903 tree allocator = NULL_TREE;
17904 tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ALLOCATE, NULL_TREE);
17905 if (c_parser_next_token_is (parser, CPP_NAME))
17906 {
17907 matching_parens parens;
17908 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17909 c_parser_consume_token (parser);
17910 if (strcmp ("allocator", p) != 0)
17911 error_at (c_parser_peek_token (parser)->location,
17912 "expected %<allocator%>");
17913 else if (parens.require_open (parser))
17914 {
17915 location_t expr_loc = c_parser_peek_token (parser)->location;
17916 c_expr expr = c_parser_expr_no_commas (parser, NULL);
17917 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
17918 allocator = expr.value;
17919 allocator = c_fully_fold (allocator, false, NULL);
17920 tree orig_type
17921 = expr.original_type ? expr.original_type : TREE_TYPE (allocator);
17922 orig_type = TYPE_MAIN_VARIANT (orig_type);
17923 if (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
17924 || TREE_CODE (orig_type) != ENUMERAL_TYPE
17925 || TYPE_NAME (orig_type)
17926 != get_identifier ("omp_allocator_handle_t"))
17927 {
17928 error_at (expr_loc, "%<allocator%> clause allocator expression "
17929 "has type %qT rather than "
17930 "%<omp_allocator_handle_t%>",
17931 TREE_TYPE (allocator));
17932 allocator = NULL_TREE;
17933 }
17934 parens.skip_until_found_close (parser);
17935 }
17936 }
17937 c_parser_skip_to_pragma_eol (parser);
17938
17939 if (allocator)
17940 for (tree c = nl; c != NULL_TREE; c = OMP_CLAUSE_CHAIN (c))
17941 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
17942
17943 sorry_at (loc, "%<#pragma omp allocate%> not yet supported");
17944 }
17945
17946 /* OpenMP 2.5:
17947 # pragma omp atomic new-line
17948 expression-stmt
17949
17950 expression-stmt:
17951 x binop= expr | x++ | ++x | x-- | --x
17952 binop:
17953 +, *, -, /, &, ^, |, <<, >>
17954
17955 where x is an lvalue expression with scalar type.
17956
17957 OpenMP 3.1:
17958 # pragma omp atomic new-line
17959 update-stmt
17960
17961 # pragma omp atomic read new-line
17962 read-stmt
17963
17964 # pragma omp atomic write new-line
17965 write-stmt
17966
17967 # pragma omp atomic update new-line
17968 update-stmt
17969
17970 # pragma omp atomic capture new-line
17971 capture-stmt
17972
17973 # pragma omp atomic capture new-line
17974 capture-block
17975
17976 read-stmt:
17977 v = x
17978 write-stmt:
17979 x = expr
17980 update-stmt:
17981 expression-stmt | x = x binop expr
17982 capture-stmt:
17983 v = expression-stmt
17984 capture-block:
17985 { v = x; update-stmt; } | { update-stmt; v = x; }
17986
17987 OpenMP 4.0:
17988 update-stmt:
17989 expression-stmt | x = x binop expr | x = expr binop x
17990 capture-stmt:
17991 v = update-stmt
17992 capture-block:
17993 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
17994
17995 OpenMP 5.1:
17996 # pragma omp atomic compare new-line
17997 conditional-update-atomic
17998
17999 # pragma omp atomic compare capture new-line
18000 conditional-update-capture-atomic
18001
18002 conditional-update-atomic:
18003 cond-expr-stmt | cond-update-stmt
18004 cond-expr-stmt:
18005 x = expr ordop x ? expr : x;
18006 x = x ordop expr ? expr : x;
18007 x = x == e ? d : x;
18008 cond-update-stmt:
18009 if (expr ordop x) { x = expr; }
18010 if (x ordop expr) { x = expr; }
18011 if (x == e) { x = d; }
18012 ordop:
18013 <, >
18014 conditional-update-capture-atomic:
18015 v = cond-expr-stmt
18016 { v = x; cond-expr-stmt }
18017 { cond-expr-stmt v = x; }
18018 { v = x; cond-update-stmt }
18019 { cond-update-stmt v = x; }
18020 if (x == e) { x = d; } else { v = x; }
18021 { r = x == e; if (r) { x = d; } }
18022 { r = x == e; if (r) { x = d; } else { v = x; } }
18023
18024 where x, r and v are lvalue expressions with scalar type,
18025 expr, e and d are expressions with scalar type and e might be
18026 the same as v.
18027
18028 LOC is the location of the #pragma token. */
18029
18030 static void
18031 c_parser_omp_atomic (location_t loc, c_parser *parser, bool openacc)
18032 {
18033 tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE, r = NULL_TREE;
18034 tree lhs1 = NULL_TREE, rhs1 = NULL_TREE;
18035 tree stmt, orig_lhs, unfolded_lhs = NULL_TREE, unfolded_lhs1 = NULL_TREE;
18036 enum tree_code code = ERROR_MARK, opcode = NOP_EXPR;
18037 enum omp_memory_order memory_order = OMP_MEMORY_ORDER_UNSPECIFIED;
18038 struct c_expr expr;
18039 location_t eloc;
18040 bool structured_block = false;
18041 bool swapped = false;
18042 bool non_lvalue_p;
18043 bool first = true;
18044 tree clauses = NULL_TREE;
18045 bool capture = false;
18046 bool compare = false;
18047 bool weak = false;
18048 enum omp_memory_order fail = OMP_MEMORY_ORDER_UNSPECIFIED;
18049 bool no_semicolon = false;
18050 bool extra_scope = false;
18051
18052 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
18053 {
18054 if (!first
18055 && c_parser_next_token_is (parser, CPP_COMMA)
18056 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
18057 c_parser_consume_token (parser);
18058
18059 first = false;
18060
18061 if (c_parser_next_token_is (parser, CPP_NAME))
18062 {
18063 const char *p
18064 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18065 location_t cloc = c_parser_peek_token (parser)->location;
18066 enum tree_code new_code = ERROR_MARK;
18067 enum omp_memory_order new_memory_order
18068 = OMP_MEMORY_ORDER_UNSPECIFIED;
18069 bool new_capture = false;
18070 bool new_compare = false;
18071 bool new_weak = false;
18072 enum omp_memory_order new_fail = OMP_MEMORY_ORDER_UNSPECIFIED;
18073
18074 if (!strcmp (p, "read"))
18075 new_code = OMP_ATOMIC_READ;
18076 else if (!strcmp (p, "write"))
18077 new_code = NOP_EXPR;
18078 else if (!strcmp (p, "update"))
18079 new_code = OMP_ATOMIC;
18080 else if (openacc && !strcmp (p, "capture"))
18081 new_code = OMP_ATOMIC_CAPTURE_NEW;
18082 else if (openacc)
18083 {
18084 p = NULL;
18085 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
18086 "or %<capture%> clause");
18087 }
18088 else if (!strcmp (p, "capture"))
18089 new_capture = true;
18090 else if (!strcmp (p, "compare"))
18091 new_compare = true;
18092 else if (!strcmp (p, "weak"))
18093 new_weak = true;
18094 else if (!strcmp (p, "fail"))
18095 {
18096 matching_parens parens;
18097
18098 c_parser_consume_token (parser);
18099 if (!parens.require_open (parser))
18100 continue;
18101
18102 if (c_parser_next_token_is (parser, CPP_NAME))
18103 {
18104 const char *q
18105 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18106
18107 if (!strcmp (q, "seq_cst"))
18108 new_fail = OMP_MEMORY_ORDER_SEQ_CST;
18109 else if (!strcmp (q, "acquire"))
18110 new_fail = OMP_MEMORY_ORDER_ACQUIRE;
18111 else if (!strcmp (q, "relaxed"))
18112 new_fail = OMP_MEMORY_ORDER_RELAXED;
18113 }
18114
18115 if (new_fail != OMP_MEMORY_ORDER_UNSPECIFIED)
18116 {
18117 c_parser_consume_token (parser);
18118 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
18119 error_at (cloc, "too many %qs clauses", "fail");
18120 else
18121 fail = new_fail;
18122 }
18123 else
18124 c_parser_error (parser, "expected %<seq_cst%>, %<acquire%> "
18125 "or %<relaxed%>");
18126 parens.skip_until_found_close (parser);
18127 continue;
18128 }
18129 else if (!strcmp (p, "seq_cst"))
18130 new_memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18131 else if (!strcmp (p, "acq_rel"))
18132 new_memory_order = OMP_MEMORY_ORDER_ACQ_REL;
18133 else if (!strcmp (p, "release"))
18134 new_memory_order = OMP_MEMORY_ORDER_RELEASE;
18135 else if (!strcmp (p, "acquire"))
18136 new_memory_order = OMP_MEMORY_ORDER_ACQUIRE;
18137 else if (!strcmp (p, "relaxed"))
18138 new_memory_order = OMP_MEMORY_ORDER_RELAXED;
18139 else if (!strcmp (p, "hint"))
18140 {
18141 c_parser_consume_token (parser);
18142 clauses = c_parser_omp_clause_hint (parser, clauses);
18143 continue;
18144 }
18145 else
18146 {
18147 p = NULL;
18148 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
18149 "%<capture%>, %<compare%>, %<weak%>, %<fail%>, "
18150 "%<seq_cst%>, %<acq_rel%>, %<release%>, "
18151 "%<relaxed%> or %<hint%> clause");
18152 }
18153 if (p)
18154 {
18155 if (new_code != ERROR_MARK)
18156 {
18157 /* OpenACC permits 'update capture'. */
18158 if (openacc
18159 && code == OMP_ATOMIC
18160 && new_code == OMP_ATOMIC_CAPTURE_NEW)
18161 code = new_code;
18162 else if (code != ERROR_MARK)
18163 error_at (cloc, "too many atomic clauses");
18164 else
18165 code = new_code;
18166 }
18167 else if (new_memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
18168 {
18169 if (memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
18170 error_at (cloc, "too many memory order clauses");
18171 else
18172 memory_order = new_memory_order;
18173 }
18174 else if (new_capture)
18175 {
18176 if (capture)
18177 error_at (cloc, "too many %qs clauses", "capture");
18178 else
18179 capture = true;
18180 }
18181 else if (new_compare)
18182 {
18183 if (compare)
18184 error_at (cloc, "too many %qs clauses", "compare");
18185 else
18186 compare = true;
18187 }
18188 else if (new_weak)
18189 {
18190 if (weak)
18191 error_at (cloc, "too many %qs clauses", "weak");
18192 else
18193 weak = true;
18194 }
18195 c_parser_consume_token (parser);
18196 continue;
18197 }
18198 }
18199 break;
18200 }
18201 c_parser_skip_to_pragma_eol (parser);
18202
18203 if (code == ERROR_MARK)
18204 code = OMP_ATOMIC;
18205 if (capture)
18206 {
18207 if (code != OMP_ATOMIC)
18208 error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
18209 "clauses", "capture");
18210 else
18211 code = OMP_ATOMIC_CAPTURE_NEW;
18212 }
18213 if (compare && code != OMP_ATOMIC && code != OMP_ATOMIC_CAPTURE_NEW)
18214 {
18215 error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
18216 "clauses", "compare");
18217 compare = false;
18218 }
18219 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED && !compare)
18220 {
18221 error_at (loc, "%qs clause requires %qs clause", "fail", "compare");
18222 fail = OMP_MEMORY_ORDER_UNSPECIFIED;
18223 }
18224 if (weak && !compare)
18225 {
18226 error_at (loc, "%qs clause requires %qs clause", "weak", "compare");
18227 weak = false;
18228 }
18229 if (openacc)
18230 memory_order = OMP_MEMORY_ORDER_RELAXED;
18231 else if (memory_order == OMP_MEMORY_ORDER_UNSPECIFIED)
18232 {
18233 omp_requires_mask
18234 = (enum omp_requires) (omp_requires_mask
18235 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED);
18236 switch ((enum omp_memory_order)
18237 (omp_requires_mask & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER))
18238 {
18239 case OMP_MEMORY_ORDER_UNSPECIFIED:
18240 case OMP_MEMORY_ORDER_RELAXED:
18241 memory_order = OMP_MEMORY_ORDER_RELAXED;
18242 break;
18243 case OMP_MEMORY_ORDER_SEQ_CST:
18244 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18245 break;
18246 case OMP_MEMORY_ORDER_ACQ_REL:
18247 switch (code)
18248 {
18249 case OMP_ATOMIC_READ:
18250 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
18251 break;
18252 case NOP_EXPR: /* atomic write */
18253 memory_order = OMP_MEMORY_ORDER_RELEASE;
18254 break;
18255 default:
18256 memory_order = OMP_MEMORY_ORDER_ACQ_REL;
18257 break;
18258 }
18259 break;
18260 default:
18261 gcc_unreachable ();
18262 }
18263 }
18264 else
18265 switch (code)
18266 {
18267 case OMP_ATOMIC_READ:
18268 if (memory_order == OMP_MEMORY_ORDER_RELEASE)
18269 {
18270 error_at (loc, "%<#pragma omp atomic read%> incompatible with "
18271 "%<release%> clause");
18272 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18273 }
18274 else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
18275 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
18276 break;
18277 case NOP_EXPR: /* atomic write */
18278 if (memory_order == OMP_MEMORY_ORDER_ACQUIRE)
18279 {
18280 error_at (loc, "%<#pragma omp atomic write%> incompatible with "
18281 "%<acquire%> clause");
18282 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
18283 }
18284 else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
18285 memory_order = OMP_MEMORY_ORDER_RELEASE;
18286 break;
18287 default:
18288 break;
18289 }
18290 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
18291 memory_order
18292 = (enum omp_memory_order) (memory_order
18293 | (fail << OMP_FAIL_MEMORY_ORDER_SHIFT));
18294
18295 switch (code)
18296 {
18297 case OMP_ATOMIC_READ:
18298 case NOP_EXPR: /* atomic write */
18299 v = c_parser_cast_expression (parser, NULL).value;
18300 non_lvalue_p = !lvalue_p (v);
18301 v = c_fully_fold (v, false, NULL, true);
18302 if (v == error_mark_node)
18303 goto saw_error;
18304 if (non_lvalue_p)
18305 v = non_lvalue (v);
18306 loc = c_parser_peek_token (parser)->location;
18307 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18308 goto saw_error;
18309 if (code == NOP_EXPR)
18310 {
18311 lhs = c_parser_expression (parser).value;
18312 lhs = c_fully_fold (lhs, false, NULL);
18313 if (lhs == error_mark_node)
18314 goto saw_error;
18315 }
18316 else
18317 {
18318 lhs = c_parser_cast_expression (parser, NULL).value;
18319 non_lvalue_p = !lvalue_p (lhs);
18320 lhs = c_fully_fold (lhs, false, NULL, true);
18321 if (lhs == error_mark_node)
18322 goto saw_error;
18323 if (non_lvalue_p)
18324 lhs = non_lvalue (lhs);
18325 }
18326 if (code == NOP_EXPR)
18327 {
18328 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
18329 opcode. */
18330 code = OMP_ATOMIC;
18331 rhs = lhs;
18332 lhs = v;
18333 v = NULL_TREE;
18334 }
18335 goto done;
18336 case OMP_ATOMIC_CAPTURE_NEW:
18337 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
18338 {
18339 c_parser_consume_token (parser);
18340 structured_block = true;
18341 }
18342 else if (compare
18343 && c_parser_next_token_is_keyword (parser, RID_IF))
18344 break;
18345 else
18346 {
18347 v = c_parser_cast_expression (parser, NULL).value;
18348 non_lvalue_p = !lvalue_p (v);
18349 v = c_fully_fold (v, false, NULL, true);
18350 if (v == error_mark_node)
18351 goto saw_error;
18352 if (non_lvalue_p)
18353 v = non_lvalue (v);
18354 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18355 goto saw_error;
18356 if (compare && c_parser_next_token_is_keyword (parser, RID_IF))
18357 {
18358 eloc = c_parser_peek_token (parser)->location;
18359 error_at (eloc, "expected expression");
18360 goto saw_error;
18361 }
18362 }
18363 break;
18364 default:
18365 break;
18366 }
18367
18368 /* For structured_block case we don't know yet whether
18369 old or new x should be captured. */
18370 restart:
18371 if (compare && c_parser_next_token_is_keyword (parser, RID_IF))
18372 {
18373 c_parser_consume_token (parser);
18374
18375 matching_parens parens;
18376 if (!parens.require_open (parser))
18377 goto saw_error;
18378 eloc = c_parser_peek_token (parser)->location;
18379 c_expr cmp_expr;
18380 if (r)
18381 {
18382 cmp_expr = c_parser_cast_expression (parser, NULL);
18383 cmp_expr = default_function_array_conversion (eloc, cmp_expr);
18384 }
18385 else
18386 cmp_expr = c_parser_binary_expression (parser, NULL, void_list_node);
18387 parens.skip_until_found_close (parser);
18388 if (cmp_expr.value == error_mark_node)
18389 goto saw_error;
18390 if (r)
18391 {
18392 if (!c_tree_equal (cmp_expr.value, unfolded_lhs))
18393 goto bad_if;
18394 cmp_expr.value = rhs1;
18395 rhs1 = NULL_TREE;
18396 gcc_assert (TREE_CODE (cmp_expr.value) == EQ_EXPR);
18397 }
18398 if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
18399 ;
18400 else if (!structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
18401 {
18402 error_at (EXPR_LOC_OR_LOC (cmp_expr.value, eloc),
18403 "expected %<==%> comparison in %<if%> condition");
18404 goto saw_error;
18405 }
18406 else if (TREE_CODE (cmp_expr.value) != GT_EXPR
18407 && TREE_CODE (cmp_expr.value) != LT_EXPR)
18408 {
18409 error_at (EXPR_LOC_OR_LOC (cmp_expr.value, eloc),
18410 "expected %<==%>, %<<%> or %<>%> comparison in %<if%> "
18411 "condition");
18412 goto saw_error;
18413 }
18414 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
18415 goto saw_error;
18416
18417 extra_scope = true;
18418 eloc = c_parser_peek_token (parser)->location;
18419 expr = c_parser_cast_expression (parser, NULL);
18420 lhs = expr.value;
18421 expr = default_function_array_conversion (eloc, expr);
18422 unfolded_lhs = expr.value;
18423 lhs = c_fully_fold (lhs, false, NULL, true);
18424 orig_lhs = lhs;
18425 if (lhs == error_mark_node)
18426 goto saw_error;
18427 if (!lvalue_p (unfolded_lhs))
18428 lhs = non_lvalue (lhs);
18429 if (!c_parser_next_token_is (parser, CPP_EQ))
18430 {
18431 c_parser_error (parser, "expected %<=%>");
18432 goto saw_error;
18433 }
18434 c_parser_consume_token (parser);
18435 eloc = c_parser_peek_token (parser)->location;
18436 expr = c_parser_expr_no_commas (parser, NULL);
18437 rhs1 = expr.value;
18438
18439 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
18440 goto saw_error;
18441
18442 if (!c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
18443 goto saw_error;
18444
18445 extra_scope = false;
18446 no_semicolon = true;
18447
18448 if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 0), unfolded_lhs))
18449 {
18450 if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
18451 {
18452 opcode = COND_EXPR;
18453 rhs = c_fully_fold (TREE_OPERAND (cmp_expr.value, 1),
18454 false, NULL, true);
18455 rhs1 = c_fully_fold (rhs1, false, NULL, true);
18456 }
18457 else if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 1), rhs1))
18458 {
18459 opcode = (TREE_CODE (cmp_expr.value) == GT_EXPR
18460 ? MIN_EXPR : MAX_EXPR);
18461 rhs = c_fully_fold (rhs1, false, NULL, true);
18462 rhs1 = c_fully_fold (TREE_OPERAND (cmp_expr.value, 0),
18463 false, NULL, true);
18464 }
18465 else
18466 goto bad_if;
18467 }
18468 else if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
18469 goto bad_if;
18470 else if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 1), unfolded_lhs)
18471 && c_tree_equal (TREE_OPERAND (cmp_expr.value, 0), rhs1))
18472 {
18473 opcode = (TREE_CODE (cmp_expr.value) == GT_EXPR
18474 ? MAX_EXPR : MIN_EXPR);
18475 rhs = c_fully_fold (rhs1, false, NULL, true);
18476 rhs1 = c_fully_fold (TREE_OPERAND (cmp_expr.value, 1),
18477 false, NULL, true);
18478 }
18479 else
18480 {
18481 bad_if:
18482 c_parser_error (parser,
18483 "invalid form of %<#pragma omp atomic compare%>");
18484 goto saw_error;
18485 }
18486
18487 if (c_parser_next_token_is_keyword (parser, RID_ELSE))
18488 {
18489 if (code != OMP_ATOMIC_CAPTURE_NEW
18490 || (structured_block && r == NULL_TREE)
18491 || TREE_CODE (cmp_expr.value) != EQ_EXPR)
18492 {
18493 eloc = c_parser_peek_token (parser)->location;
18494 error_at (eloc, "unexpected %<else%>");
18495 goto saw_error;
18496 }
18497
18498 c_parser_consume_token (parser);
18499
18500 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
18501 goto saw_error;
18502
18503 extra_scope = true;
18504 v = c_parser_cast_expression (parser, NULL).value;
18505 non_lvalue_p = !lvalue_p (v);
18506 v = c_fully_fold (v, false, NULL, true);
18507 if (v == error_mark_node)
18508 goto saw_error;
18509 if (non_lvalue_p)
18510 v = non_lvalue (v);
18511 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18512 goto saw_error;
18513
18514 expr = c_parser_expr_no_commas (parser, NULL);
18515
18516 if (!c_tree_equal (expr.value, unfolded_lhs))
18517 goto bad_if;
18518
18519 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
18520 goto saw_error;
18521
18522 if (!c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
18523 goto saw_error;
18524
18525 extra_scope = false;
18526 code = OMP_ATOMIC_CAPTURE_OLD;
18527 if (r == NULL_TREE)
18528 /* Signal to c_finish_omp_atomic that in
18529 if (x == e) { x = d; } else { v = x; }
18530 case the store to v should be conditional. */
18531 r = void_list_node;
18532 }
18533 else if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
18534 {
18535 c_parser_require_keyword (parser, RID_ELSE, "expected %<else%>");
18536 goto saw_error;
18537 }
18538 else if (code == OMP_ATOMIC_CAPTURE_NEW
18539 && r != NULL_TREE
18540 && v == NULL_TREE)
18541 code = OMP_ATOMIC;
18542 goto stmt_done;
18543 }
18544 eloc = c_parser_peek_token (parser)->location;
18545 expr = c_parser_cast_expression (parser, NULL);
18546 lhs = expr.value;
18547 expr = default_function_array_conversion (eloc, expr);
18548 unfolded_lhs = expr.value;
18549 lhs = c_fully_fold (lhs, false, NULL, true);
18550 orig_lhs = lhs;
18551 switch (TREE_CODE (lhs))
18552 {
18553 invalid_compare:
18554 error_at (eloc, "invalid form of %<pragma omp atomic compare%>");
18555 /* FALLTHRU */
18556 case ERROR_MARK:
18557 saw_error:
18558 c_parser_skip_to_end_of_block_or_statement (parser);
18559 if (extra_scope && c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18560 c_parser_consume_token (parser);
18561 if (structured_block)
18562 {
18563 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18564 c_parser_consume_token (parser);
18565 else if (code == OMP_ATOMIC_CAPTURE_NEW)
18566 {
18567 c_parser_skip_to_end_of_block_or_statement (parser);
18568 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
18569 c_parser_consume_token (parser);
18570 }
18571 }
18572 return;
18573
18574 case POSTINCREMENT_EXPR:
18575 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
18576 code = OMP_ATOMIC_CAPTURE_OLD;
18577 /* FALLTHROUGH */
18578 case PREINCREMENT_EXPR:
18579 lhs = TREE_OPERAND (lhs, 0);
18580 unfolded_lhs = NULL_TREE;
18581 opcode = PLUS_EXPR;
18582 rhs = integer_one_node;
18583 if (compare)
18584 goto invalid_compare;
18585 break;
18586
18587 case POSTDECREMENT_EXPR:
18588 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
18589 code = OMP_ATOMIC_CAPTURE_OLD;
18590 /* FALLTHROUGH */
18591 case PREDECREMENT_EXPR:
18592 lhs = TREE_OPERAND (lhs, 0);
18593 unfolded_lhs = NULL_TREE;
18594 opcode = MINUS_EXPR;
18595 rhs = integer_one_node;
18596 if (compare)
18597 goto invalid_compare;
18598 break;
18599
18600 case COMPOUND_EXPR:
18601 if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR
18602 && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR
18603 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR
18604 && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0)
18605 && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
18606 (TREE_OPERAND (lhs, 1), 0), 0)))
18607 == BOOLEAN_TYPE)
18608 /* Undo effects of boolean_increment for post {in,de}crement. */
18609 lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
18610 /* FALLTHRU */
18611 case MODIFY_EXPR:
18612 if (TREE_CODE (lhs) == MODIFY_EXPR
18613 && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) == BOOLEAN_TYPE)
18614 {
18615 /* Undo effects of boolean_increment. */
18616 if (integer_onep (TREE_OPERAND (lhs, 1)))
18617 {
18618 /* This is pre or post increment. */
18619 rhs = TREE_OPERAND (lhs, 1);
18620 lhs = TREE_OPERAND (lhs, 0);
18621 unfolded_lhs = NULL_TREE;
18622 opcode = NOP_EXPR;
18623 if (code == OMP_ATOMIC_CAPTURE_NEW
18624 && !structured_block
18625 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
18626 code = OMP_ATOMIC_CAPTURE_OLD;
18627 if (compare)
18628 goto invalid_compare;
18629 break;
18630 }
18631 if (TREE_CODE (TREE_OPERAND (lhs, 1)) == TRUTH_NOT_EXPR
18632 && TREE_OPERAND (lhs, 0)
18633 == TREE_OPERAND (TREE_OPERAND (lhs, 1), 0))
18634 {
18635 /* This is pre or post decrement. */
18636 rhs = TREE_OPERAND (lhs, 1);
18637 lhs = TREE_OPERAND (lhs, 0);
18638 unfolded_lhs = NULL_TREE;
18639 opcode = NOP_EXPR;
18640 if (code == OMP_ATOMIC_CAPTURE_NEW
18641 && !structured_block
18642 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
18643 code = OMP_ATOMIC_CAPTURE_OLD;
18644 if (compare)
18645 goto invalid_compare;
18646 break;
18647 }
18648 }
18649 /* FALLTHRU */
18650 default:
18651 if (!lvalue_p (unfolded_lhs))
18652 lhs = non_lvalue (lhs);
18653 if (compare && !c_parser_next_token_is (parser, CPP_EQ))
18654 {
18655 c_parser_error (parser, "expected %<=%>");
18656 goto saw_error;
18657 }
18658 switch (c_parser_peek_token (parser)->type)
18659 {
18660 case CPP_MULT_EQ:
18661 opcode = MULT_EXPR;
18662 break;
18663 case CPP_DIV_EQ:
18664 opcode = TRUNC_DIV_EXPR;
18665 break;
18666 case CPP_PLUS_EQ:
18667 opcode = PLUS_EXPR;
18668 break;
18669 case CPP_MINUS_EQ:
18670 opcode = MINUS_EXPR;
18671 break;
18672 case CPP_LSHIFT_EQ:
18673 opcode = LSHIFT_EXPR;
18674 break;
18675 case CPP_RSHIFT_EQ:
18676 opcode = RSHIFT_EXPR;
18677 break;
18678 case CPP_AND_EQ:
18679 opcode = BIT_AND_EXPR;
18680 break;
18681 case CPP_OR_EQ:
18682 opcode = BIT_IOR_EXPR;
18683 break;
18684 case CPP_XOR_EQ:
18685 opcode = BIT_XOR_EXPR;
18686 break;
18687 case CPP_EQ:
18688 c_parser_consume_token (parser);
18689 eloc = c_parser_peek_token (parser)->location;
18690 expr = c_parser_expr_no_commas (parser, NULL, unfolded_lhs);
18691 rhs1 = expr.value;
18692 switch (TREE_CODE (rhs1))
18693 {
18694 case MULT_EXPR:
18695 case TRUNC_DIV_EXPR:
18696 case RDIV_EXPR:
18697 case PLUS_EXPR:
18698 case MINUS_EXPR:
18699 case LSHIFT_EXPR:
18700 case RSHIFT_EXPR:
18701 case BIT_AND_EXPR:
18702 case BIT_IOR_EXPR:
18703 case BIT_XOR_EXPR:
18704 if (compare)
18705 break;
18706 if (c_tree_equal (TREE_OPERAND (rhs1, 0), unfolded_lhs))
18707 {
18708 opcode = TREE_CODE (rhs1);
18709 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
18710 true);
18711 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
18712 true);
18713 goto stmt_done;
18714 }
18715 if (c_tree_equal (TREE_OPERAND (rhs1, 1), unfolded_lhs))
18716 {
18717 opcode = TREE_CODE (rhs1);
18718 rhs = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
18719 true);
18720 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
18721 true);
18722 swapped = !commutative_tree_code (opcode);
18723 goto stmt_done;
18724 }
18725 break;
18726 case COND_EXPR:
18727 if (!compare)
18728 break;
18729 if (TREE_CODE (TREE_OPERAND (rhs1, 0)) != GT_EXPR
18730 && TREE_CODE (TREE_OPERAND (rhs1, 0)) != LT_EXPR
18731 && TREE_CODE (TREE_OPERAND (rhs1, 0)) != EQ_EXPR)
18732 break;
18733 if (!TREE_OPERAND (rhs1, 1))
18734 break;
18735 if (!c_tree_equal (TREE_OPERAND (rhs1, 2), unfolded_lhs))
18736 break;
18737 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0),
18738 unfolded_lhs))
18739 {
18740 if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == EQ_EXPR)
18741 {
18742 opcode = COND_EXPR;
18743 rhs = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
18744 0), 1),
18745 false, NULL, true);
18746 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false,
18747 NULL, true);
18748 goto stmt_done;
18749 }
18750 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1),
18751 TREE_OPERAND (rhs1, 1)))
18752 {
18753 opcode = (TREE_CODE (TREE_OPERAND (rhs1, 0)) == GT_EXPR
18754 ? MIN_EXPR : MAX_EXPR);
18755 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
18756 true);
18757 rhs1 = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
18758 0), 0),
18759 false, NULL, true);
18760 goto stmt_done;
18761 }
18762 }
18763 else if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == EQ_EXPR)
18764 break;
18765 else if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1),
18766 unfolded_lhs))
18767 {
18768 if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0),
18769 TREE_OPERAND (rhs1, 1)))
18770 {
18771 opcode = (TREE_CODE (TREE_OPERAND (rhs1, 0)) == GT_EXPR
18772 ? MAX_EXPR : MIN_EXPR);
18773 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
18774 true);
18775 rhs1 = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
18776 0), 1),
18777 false, NULL, true);
18778 goto stmt_done;
18779 }
18780 }
18781 break;
18782 case EQ_EXPR:
18783 if (!compare
18784 || code != OMP_ATOMIC_CAPTURE_NEW
18785 || !structured_block
18786 || v
18787 || r)
18788 break;
18789 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
18790 && c_parser_peek_2nd_token (parser)->keyword == RID_IF)
18791 {
18792 r = lhs;
18793 lhs = NULL_TREE;
18794 c_parser_consume_token (parser);
18795 goto restart;
18796 }
18797 break;
18798 case ERROR_MARK:
18799 goto saw_error;
18800 default:
18801 break;
18802 }
18803 if (c_parser_peek_token (parser)->type == CPP_SEMICOLON)
18804 {
18805 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
18806 {
18807 code = OMP_ATOMIC_CAPTURE_OLD;
18808 v = lhs;
18809 lhs = NULL_TREE;
18810 expr = default_function_array_read_conversion (eloc, expr);
18811 unfolded_lhs1 = expr.value;
18812 lhs1 = c_fully_fold (unfolded_lhs1, false, NULL, true);
18813 rhs1 = NULL_TREE;
18814 c_parser_consume_token (parser);
18815 goto restart;
18816 }
18817 if (structured_block && !compare)
18818 {
18819 opcode = NOP_EXPR;
18820 expr = default_function_array_read_conversion (eloc, expr);
18821 rhs = c_fully_fold (expr.value, false, NULL, true);
18822 rhs1 = NULL_TREE;
18823 goto stmt_done;
18824 }
18825 }
18826 c_parser_error (parser, "invalid form of %<#pragma omp atomic%>");
18827 goto saw_error;
18828 default:
18829 c_parser_error (parser,
18830 "invalid operator for %<#pragma omp atomic%>");
18831 goto saw_error;
18832 }
18833
18834 /* Arrange to pass the location of the assignment operator to
18835 c_finish_omp_atomic. */
18836 loc = c_parser_peek_token (parser)->location;
18837 c_parser_consume_token (parser);
18838 eloc = c_parser_peek_token (parser)->location;
18839 expr = c_parser_expression (parser);
18840 expr = default_function_array_read_conversion (eloc, expr);
18841 rhs = expr.value;
18842 rhs = c_fully_fold (rhs, false, NULL, true);
18843 break;
18844 }
18845 stmt_done:
18846 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW && r == NULL_TREE)
18847 {
18848 if (!no_semicolon
18849 && !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
18850 goto saw_error;
18851 no_semicolon = false;
18852 v = c_parser_cast_expression (parser, NULL).value;
18853 non_lvalue_p = !lvalue_p (v);
18854 v = c_fully_fold (v, false, NULL, true);
18855 if (v == error_mark_node)
18856 goto saw_error;
18857 if (non_lvalue_p)
18858 v = non_lvalue (v);
18859 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
18860 goto saw_error;
18861 eloc = c_parser_peek_token (parser)->location;
18862 expr = c_parser_cast_expression (parser, NULL);
18863 lhs1 = expr.value;
18864 expr = default_function_array_read_conversion (eloc, expr);
18865 unfolded_lhs1 = expr.value;
18866 lhs1 = c_fully_fold (lhs1, false, NULL, true);
18867 if (lhs1 == error_mark_node)
18868 goto saw_error;
18869 if (!lvalue_p (unfolded_lhs1))
18870 lhs1 = non_lvalue (lhs1);
18871 }
18872 if (structured_block)
18873 {
18874 if (!no_semicolon)
18875 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
18876 c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>");
18877 }
18878 done:
18879 if (weak && opcode != COND_EXPR)
18880 {
18881 error_at (loc, "%<weak%> clause requires atomic equality comparison");
18882 weak = false;
18883 }
18884 if (unfolded_lhs && unfolded_lhs1
18885 && !c_tree_equal (unfolded_lhs, unfolded_lhs1))
18886 {
18887 error ("%<#pragma omp atomic capture%> uses two different "
18888 "expressions for memory");
18889 stmt = error_mark_node;
18890 }
18891 else
18892 stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs, v, lhs1, rhs1, r,
18893 swapped, memory_order, weak);
18894 if (stmt != error_mark_node)
18895 add_stmt (stmt);
18896
18897 if (!structured_block && !no_semicolon)
18898 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
18899 }
18900
18901
18902 /* OpenMP 2.5:
18903 # pragma omp barrier new-line
18904 */
18905
18906 static void
18907 c_parser_omp_barrier (c_parser *parser)
18908 {
18909 location_t loc = c_parser_peek_token (parser)->location;
18910 c_parser_consume_pragma (parser);
18911 c_parser_skip_to_pragma_eol (parser);
18912
18913 c_finish_omp_barrier (loc);
18914 }
18915
18916 /* OpenMP 2.5:
18917 # pragma omp critical [(name)] new-line
18918 structured-block
18919
18920 OpenMP 4.5:
18921 # pragma omp critical [(name) [hint(expression)]] new-line
18922
18923 LOC is the location of the #pragma itself. */
18924
18925 #define OMP_CRITICAL_CLAUSE_MASK \
18926 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
18927
18928 static tree
18929 c_parser_omp_critical (location_t loc, c_parser *parser, bool *if_p)
18930 {
18931 tree stmt, name = NULL_TREE, clauses = NULL_TREE;
18932
18933 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
18934 {
18935 c_parser_consume_token (parser);
18936 if (c_parser_next_token_is (parser, CPP_NAME))
18937 {
18938 name = c_parser_peek_token (parser)->value;
18939 c_parser_consume_token (parser);
18940 c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
18941 }
18942 else
18943 c_parser_error (parser, "expected identifier");
18944
18945 if (c_parser_next_token_is (parser, CPP_COMMA)
18946 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
18947 c_parser_consume_token (parser);
18948 }
18949 clauses = c_parser_omp_all_clauses (parser, OMP_CRITICAL_CLAUSE_MASK,
18950 "#pragma omp critical");
18951 stmt = c_parser_omp_structured_block (parser, if_p);
18952 return c_finish_omp_critical (loc, stmt, name, clauses);
18953 }
18954
18955 /* OpenMP 5.0:
18956 # pragma omp depobj ( depobj ) depobj-clause new-line
18957
18958 depobj-clause:
18959 depend (dependence-type : locator)
18960 destroy
18961 update (dependence-type)
18962
18963 dependence-type:
18964 in
18965 out
18966 inout
18967 mutexinout */
18968
18969 static void
18970 c_parser_omp_depobj (c_parser *parser)
18971 {
18972 location_t loc = c_parser_peek_token (parser)->location;
18973 c_parser_consume_pragma (parser);
18974 matching_parens parens;
18975 if (!parens.require_open (parser))
18976 {
18977 c_parser_skip_to_pragma_eol (parser);
18978 return;
18979 }
18980
18981 tree depobj = c_parser_expr_no_commas (parser, NULL).value;
18982 if (depobj != error_mark_node)
18983 {
18984 if (!lvalue_p (depobj))
18985 {
18986 error_at (EXPR_LOC_OR_LOC (depobj, loc),
18987 "%<depobj%> expression is not lvalue expression");
18988 depobj = error_mark_node;
18989 }
18990 else
18991 {
18992 tree addr = build_unary_op (EXPR_LOC_OR_LOC (depobj, loc), ADDR_EXPR,
18993 depobj, false);
18994 if (addr == error_mark_node)
18995 depobj = error_mark_node;
18996 else
18997 depobj = build_indirect_ref (EXPR_LOC_OR_LOC (depobj, loc),
18998 addr, RO_UNARY_STAR);
18999 }
19000 }
19001
19002 parens.skip_until_found_close (parser);
19003 tree clause = NULL_TREE;
19004 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_SOURCE;
19005 location_t c_loc = c_parser_peek_token (parser)->location;
19006 if (c_parser_next_token_is (parser, CPP_NAME))
19007 {
19008 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19009
19010 c_parser_consume_token (parser);
19011 if (!strcmp ("depend", p))
19012 {
19013 clause = c_parser_omp_clause_depend (parser, NULL_TREE);
19014 clause = c_finish_omp_clauses (clause, C_ORT_OMP);
19015 if (!clause)
19016 clause = error_mark_node;
19017 }
19018 else if (!strcmp ("destroy", p))
19019 kind = OMP_CLAUSE_DEPEND_LAST;
19020 else if (!strcmp ("update", p))
19021 {
19022 matching_parens c_parens;
19023 if (c_parens.require_open (parser))
19024 {
19025 location_t c2_loc = c_parser_peek_token (parser)->location;
19026 if (c_parser_next_token_is (parser, CPP_NAME))
19027 {
19028 const char *p2
19029 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19030
19031 c_parser_consume_token (parser);
19032 if (!strcmp ("in", p2))
19033 kind = OMP_CLAUSE_DEPEND_IN;
19034 else if (!strcmp ("out", p2))
19035 kind = OMP_CLAUSE_DEPEND_OUT;
19036 else if (!strcmp ("inout", p2))
19037 kind = OMP_CLAUSE_DEPEND_INOUT;
19038 else if (!strcmp ("mutexinoutset", p2))
19039 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
19040 }
19041 if (kind == OMP_CLAUSE_DEPEND_SOURCE)
19042 {
19043 clause = error_mark_node;
19044 error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%> or "
19045 "%<mutexinoutset%>");
19046 }
19047 c_parens.skip_until_found_close (parser);
19048 }
19049 else
19050 clause = error_mark_node;
19051 }
19052 }
19053 if (!clause && kind == OMP_CLAUSE_DEPEND_SOURCE)
19054 {
19055 clause = error_mark_node;
19056 error_at (c_loc, "expected %<depend%>, %<destroy%> or %<update%> clause");
19057 }
19058 c_parser_skip_to_pragma_eol (parser);
19059
19060 c_finish_omp_depobj (loc, depobj, kind, clause);
19061 }
19062
19063
19064 /* OpenMP 2.5:
19065 # pragma omp flush flush-vars[opt] new-line
19066
19067 flush-vars:
19068 ( variable-list )
19069
19070 OpenMP 5.0:
19071 # pragma omp flush memory-order-clause new-line */
19072
19073 static void
19074 c_parser_omp_flush (c_parser *parser)
19075 {
19076 location_t loc = c_parser_peek_token (parser)->location;
19077 c_parser_consume_pragma (parser);
19078 enum memmodel mo = MEMMODEL_LAST;
19079 if (c_parser_next_token_is (parser, CPP_NAME))
19080 {
19081 const char *p
19082 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19083
19084 if (!strcmp (p, "seq_cst"))
19085 mo = MEMMODEL_SEQ_CST;
19086 else if (!strcmp (p, "acq_rel"))
19087 mo = MEMMODEL_ACQ_REL;
19088 else if (!strcmp (p, "release"))
19089 mo = MEMMODEL_RELEASE;
19090 else if (!strcmp (p, "acquire"))
19091 mo = MEMMODEL_ACQUIRE;
19092 else
19093 error_at (c_parser_peek_token (parser)->location,
19094 "expected %<seq_cst%>, %<acq_rel%>, %<release%> or "
19095 "%<acquire%>");
19096 c_parser_consume_token (parser);
19097 }
19098 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
19099 {
19100 if (mo != MEMMODEL_LAST)
19101 error_at (c_parser_peek_token (parser)->location,
19102 "%<flush%> list specified together with memory order "
19103 "clause");
19104 c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
19105 }
19106 else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
19107 c_parser_error (parser, "expected %<(%> or end of line");
19108 c_parser_skip_to_pragma_eol (parser);
19109
19110 c_finish_omp_flush (loc, mo);
19111 }
19112
19113 /* Parse an OpenMP structured block sequence. KIND is the corresponding
19114 separating directive. */
19115
19116 static tree
19117 c_parser_omp_structured_block_sequence (c_parser *parser,
19118 enum pragma_kind kind)
19119 {
19120 tree stmt = push_stmt_list ();
19121 c_parser_statement (parser, NULL);
19122 do
19123 {
19124 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
19125 break;
19126 if (c_parser_next_token_is (parser, CPP_EOF))
19127 break;
19128
19129 if (kind != PRAGMA_NONE
19130 && c_parser_peek_token (parser)->pragma_kind == kind)
19131 break;
19132 c_parser_statement (parser, NULL);
19133 }
19134 while (1);
19135 return pop_stmt_list (stmt);
19136 }
19137
19138 /* OpenMP 5.0:
19139
19140 scan-loop-body:
19141 { structured-block scan-directive structured-block } */
19142
19143 static void
19144 c_parser_omp_scan_loop_body (c_parser *parser, bool open_brace_parsed)
19145 {
19146 tree substmt;
19147 location_t loc;
19148 tree clauses = NULL_TREE;
19149
19150 loc = c_parser_peek_token (parser)->location;
19151 if (!open_brace_parsed
19152 && !c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
19153 {
19154 /* Avoid skipping until the end of the block. */
19155 parser->error = false;
19156 return;
19157 }
19158
19159 substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_OMP_SCAN);
19160 substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE);
19161 SET_EXPR_LOCATION (substmt, loc);
19162 add_stmt (substmt);
19163
19164 loc = c_parser_peek_token (parser)->location;
19165 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SCAN)
19166 {
19167 enum omp_clause_code clause = OMP_CLAUSE_ERROR;
19168
19169 c_parser_consume_pragma (parser);
19170
19171 if (c_parser_next_token_is (parser, CPP_NAME))
19172 {
19173 const char *p
19174 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19175 if (strcmp (p, "inclusive") == 0)
19176 clause = OMP_CLAUSE_INCLUSIVE;
19177 else if (strcmp (p, "exclusive") == 0)
19178 clause = OMP_CLAUSE_EXCLUSIVE;
19179 }
19180 if (clause != OMP_CLAUSE_ERROR)
19181 {
19182 c_parser_consume_token (parser);
19183 clauses = c_parser_omp_var_list_parens (parser, clause, NULL_TREE);
19184 }
19185 else
19186 c_parser_error (parser, "expected %<inclusive%> or "
19187 "%<exclusive%> clause");
19188 c_parser_skip_to_pragma_eol (parser);
19189 }
19190 else
19191 error ("expected %<#pragma omp scan%>");
19192
19193 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
19194 substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_NONE);
19195 substmt = build2 (OMP_SCAN, void_type_node, substmt, clauses);
19196 SET_EXPR_LOCATION (substmt, loc);
19197 add_stmt (substmt);
19198
19199 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
19200 "expected %<}%>");
19201 }
19202
19203 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
19204 The real trick here is to determine the loop control variable early
19205 so that we can push a new decl if necessary to make it private.
19206 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
19207 respectively. */
19208
19209 static tree
19210 c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
19211 tree clauses, tree *cclauses, bool *if_p)
19212 {
19213 tree decl, cond, incr, body, init, stmt, cl;
19214 unsigned char save_in_statement;
19215 tree declv, condv, incrv, initv, ret = NULL_TREE;
19216 tree pre_body = NULL_TREE, this_pre_body;
19217 tree ordered_cl = NULL_TREE;
19218 bool fail = false, open_brace_parsed = false;
19219 int i, collapse = 1, ordered = 0, count, nbraces = 0;
19220 location_t for_loc;
19221 bool tiling = false;
19222 bool inscan = false;
19223 vec<tree, va_gc> *for_block = make_tree_vector ();
19224
19225 for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
19226 if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
19227 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl));
19228 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_TILE)
19229 {
19230 tiling = true;
19231 collapse = list_length (OMP_CLAUSE_TILE_LIST (cl));
19232 }
19233 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED
19234 && OMP_CLAUSE_ORDERED_EXPR (cl))
19235 {
19236 ordered_cl = cl;
19237 ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
19238 }
19239 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_REDUCTION
19240 && OMP_CLAUSE_REDUCTION_INSCAN (cl)
19241 && (code == OMP_SIMD || code == OMP_FOR))
19242 inscan = true;
19243
19244 if (ordered && ordered < collapse)
19245 {
19246 error_at (OMP_CLAUSE_LOCATION (ordered_cl),
19247 "%<ordered%> clause parameter is less than %<collapse%>");
19248 OMP_CLAUSE_ORDERED_EXPR (ordered_cl)
19249 = build_int_cst (NULL_TREE, collapse);
19250 ordered = collapse;
19251 }
19252 if (ordered)
19253 {
19254 for (tree *pc = &clauses; *pc; )
19255 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LINEAR)
19256 {
19257 error_at (OMP_CLAUSE_LOCATION (*pc),
19258 "%<linear%> clause may not be specified together "
19259 "with %<ordered%> clause with a parameter");
19260 *pc = OMP_CLAUSE_CHAIN (*pc);
19261 }
19262 else
19263 pc = &OMP_CLAUSE_CHAIN (*pc);
19264 }
19265
19266 gcc_assert (tiling || (collapse >= 1 && ordered >= 0));
19267 count = ordered ? ordered : collapse;
19268
19269 declv = make_tree_vec (count);
19270 initv = make_tree_vec (count);
19271 condv = make_tree_vec (count);
19272 incrv = make_tree_vec (count);
19273
19274 if (!c_parser_next_token_is_keyword (parser, RID_FOR))
19275 {
19276 c_parser_error (parser, "for statement expected");
19277 return NULL;
19278 }
19279 for_loc = c_parser_peek_token (parser)->location;
19280 c_parser_consume_token (parser);
19281
19282 /* Forbid break/continue in the loop initializer, condition, and
19283 increment expressions. */
19284 save_in_statement = in_statement;
19285 in_statement = IN_OMP_BLOCK;
19286
19287 for (i = 0; i < count; i++)
19288 {
19289 int bracecount = 0;
19290
19291 matching_parens parens;
19292 if (!parens.require_open (parser))
19293 goto pop_scopes;
19294
19295 /* Parse the initialization declaration or expression. */
19296 if (c_parser_next_tokens_start_declaration (parser))
19297 {
19298 if (i > 0)
19299 vec_safe_push (for_block, c_begin_compound_stmt (true));
19300 this_pre_body = push_stmt_list ();
19301 c_in_omp_for = true;
19302 c_parser_declaration_or_fndef (parser, true, true, true, true, true);
19303 c_in_omp_for = false;
19304 if (this_pre_body)
19305 {
19306 this_pre_body = pop_stmt_list (this_pre_body);
19307 if (pre_body)
19308 {
19309 tree t = pre_body;
19310 pre_body = push_stmt_list ();
19311 add_stmt (t);
19312 add_stmt (this_pre_body);
19313 pre_body = pop_stmt_list (pre_body);
19314 }
19315 else
19316 pre_body = this_pre_body;
19317 }
19318 decl = check_for_loop_decls (for_loc, flag_isoc99);
19319 if (decl == NULL)
19320 goto error_init;
19321 if (DECL_INITIAL (decl) == error_mark_node)
19322 decl = error_mark_node;
19323 init = decl;
19324 }
19325 else if (c_parser_next_token_is (parser, CPP_NAME)
19326 && c_parser_peek_2nd_token (parser)->type == CPP_EQ)
19327 {
19328 struct c_expr decl_exp;
19329 struct c_expr init_exp;
19330 location_t init_loc;
19331
19332 decl_exp = c_parser_postfix_expression (parser);
19333 decl = decl_exp.value;
19334
19335 c_parser_require (parser, CPP_EQ, "expected %<=%>");
19336
19337 init_loc = c_parser_peek_token (parser)->location;
19338 init_exp = c_parser_expr_no_commas (parser, NULL);
19339 init_exp = default_function_array_read_conversion (init_loc,
19340 init_exp);
19341 c_in_omp_for = true;
19342 init = build_modify_expr (init_loc, decl, decl_exp.original_type,
19343 NOP_EXPR, init_loc, init_exp.value,
19344 init_exp.original_type);
19345 c_in_omp_for = false;
19346 init = c_process_expr_stmt (init_loc, init);
19347
19348 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
19349 }
19350 else
19351 {
19352 error_init:
19353 c_parser_error (parser,
19354 "expected iteration declaration or initialization");
19355 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
19356 "expected %<)%>");
19357 fail = true;
19358 goto parse_next;
19359 }
19360
19361 /* Parse the loop condition. */
19362 cond = NULL_TREE;
19363 if (c_parser_next_token_is_not (parser, CPP_SEMICOLON))
19364 {
19365 location_t cond_loc = c_parser_peek_token (parser)->location;
19366 c_in_omp_for = true;
19367 struct c_expr cond_expr
19368 = c_parser_binary_expression (parser, NULL, NULL_TREE);
19369 c_in_omp_for = false;
19370
19371 cond = cond_expr.value;
19372 cond = c_objc_common_truthvalue_conversion (cond_loc, cond);
19373 switch (cond_expr.original_code)
19374 {
19375 case GT_EXPR:
19376 case GE_EXPR:
19377 case LT_EXPR:
19378 case LE_EXPR:
19379 break;
19380 case NE_EXPR:
19381 if (code != OACC_LOOP)
19382 break;
19383 /* FALLTHRU. */
19384 default:
19385 /* Can't be cond = error_mark_node, because we want to preserve
19386 the location until c_finish_omp_for. */
19387 cond = build1 (NOP_EXPR, boolean_type_node, error_mark_node);
19388 break;
19389 }
19390 protected_set_expr_location (cond, cond_loc);
19391 }
19392 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
19393
19394 /* Parse the increment expression. */
19395 incr = NULL_TREE;
19396 if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
19397 {
19398 location_t incr_loc = c_parser_peek_token (parser)->location;
19399
19400 incr = c_process_expr_stmt (incr_loc,
19401 c_parser_expression (parser).value);
19402 }
19403 parens.skip_until_found_close (parser);
19404
19405 if (decl == NULL || decl == error_mark_node || init == error_mark_node)
19406 fail = true;
19407 else
19408 {
19409 TREE_VEC_ELT (declv, i) = decl;
19410 TREE_VEC_ELT (initv, i) = init;
19411 TREE_VEC_ELT (condv, i) = cond;
19412 TREE_VEC_ELT (incrv, i) = incr;
19413 }
19414
19415 parse_next:
19416 if (i == count - 1)
19417 break;
19418
19419 /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
19420 in between the collapsed for loops to be still considered perfectly
19421 nested. Hopefully the final version clarifies this.
19422 For now handle (multiple) {'s and empty statements. */
19423 do
19424 {
19425 if (c_parser_next_token_is_keyword (parser, RID_FOR))
19426 {
19427 c_parser_consume_token (parser);
19428 break;
19429 }
19430 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
19431 {
19432 c_parser_consume_token (parser);
19433 bracecount++;
19434 }
19435 else if (bracecount
19436 && c_parser_next_token_is (parser, CPP_SEMICOLON))
19437 c_parser_consume_token (parser);
19438 else
19439 {
19440 c_parser_error (parser, "not enough perfectly nested loops");
19441 if (bracecount)
19442 {
19443 open_brace_parsed = true;
19444 bracecount--;
19445 }
19446 fail = true;
19447 count = 0;
19448 break;
19449 }
19450 }
19451 while (1);
19452
19453 nbraces += bracecount;
19454 }
19455
19456 if (nbraces)
19457 if_p = NULL;
19458
19459 in_statement = IN_OMP_FOR;
19460 body = push_stmt_list ();
19461
19462 if (inscan)
19463 c_parser_omp_scan_loop_body (parser, open_brace_parsed);
19464 else if (open_brace_parsed)
19465 {
19466 location_t here = c_parser_peek_token (parser)->location;
19467 stmt = c_begin_compound_stmt (true);
19468 c_parser_compound_statement_nostart (parser);
19469 add_stmt (c_end_compound_stmt (here, stmt, true));
19470 }
19471 else
19472 add_stmt (c_parser_c99_block_statement (parser, if_p));
19473
19474 body = pop_stmt_list (body);
19475 in_statement = save_in_statement;
19476
19477 while (nbraces)
19478 {
19479 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
19480 {
19481 c_parser_consume_token (parser);
19482 nbraces--;
19483 }
19484 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
19485 c_parser_consume_token (parser);
19486 else
19487 {
19488 c_parser_error (parser, "collapsed loops not perfectly nested");
19489 while (nbraces)
19490 {
19491 location_t here = c_parser_peek_token (parser)->location;
19492 stmt = c_begin_compound_stmt (true);
19493 add_stmt (body);
19494 c_parser_compound_statement_nostart (parser);
19495 body = c_end_compound_stmt (here, stmt, true);
19496 nbraces--;
19497 }
19498 goto pop_scopes;
19499 }
19500 }
19501
19502 /* Only bother calling c_finish_omp_for if we haven't already generated
19503 an error from the initialization parsing. */
19504 if (!fail)
19505 {
19506 c_in_omp_for = true;
19507 stmt = c_finish_omp_for (loc, code, declv, NULL, initv, condv,
19508 incrv, body, pre_body, true);
19509 c_in_omp_for = false;
19510
19511 /* Check for iterators appearing in lb, b or incr expressions. */
19512 if (stmt && !c_omp_check_loop_iv (stmt, declv, NULL))
19513 stmt = NULL_TREE;
19514
19515 if (stmt)
19516 {
19517 add_stmt (stmt);
19518
19519 for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (stmt)); i++)
19520 {
19521 tree init = TREE_VEC_ELT (OMP_FOR_INIT (stmt), i);
19522 gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
19523 tree decl = TREE_OPERAND (init, 0);
19524 tree cond = TREE_VEC_ELT (OMP_FOR_COND (stmt), i);
19525 gcc_assert (COMPARISON_CLASS_P (cond));
19526 gcc_assert (TREE_OPERAND (cond, 0) == decl);
19527
19528 tree op0 = TREE_OPERAND (init, 1);
19529 if (!OMP_FOR_NON_RECTANGULAR (stmt)
19530 || TREE_CODE (op0) != TREE_VEC)
19531 TREE_OPERAND (init, 1) = c_fully_fold (op0, false, NULL);
19532 else
19533 {
19534 TREE_VEC_ELT (op0, 1)
19535 = c_fully_fold (TREE_VEC_ELT (op0, 1), false, NULL);
19536 TREE_VEC_ELT (op0, 2)
19537 = c_fully_fold (TREE_VEC_ELT (op0, 2), false, NULL);
19538 }
19539
19540 tree op1 = TREE_OPERAND (cond, 1);
19541 if (!OMP_FOR_NON_RECTANGULAR (stmt)
19542 || TREE_CODE (op1) != TREE_VEC)
19543 TREE_OPERAND (cond, 1) = c_fully_fold (op1, false, NULL);
19544 else
19545 {
19546 TREE_VEC_ELT (op1, 1)
19547 = c_fully_fold (TREE_VEC_ELT (op1, 1), false, NULL);
19548 TREE_VEC_ELT (op1, 2)
19549 = c_fully_fold (TREE_VEC_ELT (op1, 2), false, NULL);
19550 }
19551 }
19552
19553 if (cclauses != NULL
19554 && cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL)
19555 {
19556 tree *c;
19557 for (c = &cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; *c ; )
19558 if (OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_FIRSTPRIVATE
19559 && OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_LASTPRIVATE)
19560 c = &OMP_CLAUSE_CHAIN (*c);
19561 else
19562 {
19563 for (i = 0; i < count; i++)
19564 if (TREE_VEC_ELT (declv, i) == OMP_CLAUSE_DECL (*c))
19565 break;
19566 if (i == count)
19567 c = &OMP_CLAUSE_CHAIN (*c);
19568 else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE)
19569 {
19570 error_at (loc,
19571 "iteration variable %qD should not be firstprivate",
19572 OMP_CLAUSE_DECL (*c));
19573 *c = OMP_CLAUSE_CHAIN (*c);
19574 }
19575 else
19576 {
19577 /* Move lastprivate (decl) clause to OMP_FOR_CLAUSES. */
19578 tree l = *c;
19579 *c = OMP_CLAUSE_CHAIN (*c);
19580 if (code == OMP_SIMD)
19581 {
19582 OMP_CLAUSE_CHAIN (l)
19583 = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
19584 cclauses[C_OMP_CLAUSE_SPLIT_FOR] = l;
19585 }
19586 else
19587 {
19588 OMP_CLAUSE_CHAIN (l) = clauses;
19589 clauses = l;
19590 }
19591 }
19592 }
19593 }
19594 OMP_FOR_CLAUSES (stmt) = clauses;
19595 }
19596 ret = stmt;
19597 }
19598 pop_scopes:
19599 while (!for_block->is_empty ())
19600 {
19601 /* FIXME diagnostics: LOC below should be the actual location of
19602 this particular for block. We need to build a list of
19603 locations to go along with FOR_BLOCK. */
19604 stmt = c_end_compound_stmt (loc, for_block->pop (), true);
19605 add_stmt (stmt);
19606 }
19607 release_tree_vector (for_block);
19608 return ret;
19609 }
19610
19611 /* Helper function for OpenMP parsing, split clauses and call
19612 finish_omp_clauses on each of the set of clauses afterwards. */
19613
19614 static void
19615 omp_split_clauses (location_t loc, enum tree_code code,
19616 omp_clause_mask mask, tree clauses, tree *cclauses)
19617 {
19618 int i;
19619 c_omp_split_clauses (loc, code, mask, clauses, cclauses);
19620 for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
19621 if (cclauses[i])
19622 cclauses[i] = c_finish_omp_clauses (cclauses[i],
19623 i == C_OMP_CLAUSE_SPLIT_TARGET
19624 ? C_ORT_OMP_TARGET : C_ORT_OMP);
19625 }
19626
19627 /* OpenMP 5.0:
19628 #pragma omp loop loop-clause[optseq] new-line
19629 for-loop
19630
19631 LOC is the location of the #pragma token.
19632 */
19633
19634 #define OMP_LOOP_CLAUSE_MASK \
19635 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19636 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19637 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19638 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
19639 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
19640 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
19641
19642 static tree
19643 c_parser_omp_loop (location_t loc, c_parser *parser,
19644 char *p_name, omp_clause_mask mask, tree *cclauses,
19645 bool *if_p)
19646 {
19647 tree block, clauses, ret;
19648
19649 strcat (p_name, " loop");
19650 mask |= OMP_LOOP_CLAUSE_MASK;
19651
19652 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19653 if (cclauses)
19654 {
19655 omp_split_clauses (loc, OMP_LOOP, mask, clauses, cclauses);
19656 clauses = cclauses[C_OMP_CLAUSE_SPLIT_LOOP];
19657 }
19658
19659 block = c_begin_compound_stmt (true);
19660 ret = c_parser_omp_for_loop (loc, parser, OMP_LOOP, clauses, cclauses, if_p);
19661 block = c_end_compound_stmt (loc, block, true);
19662 add_stmt (block);
19663
19664 return ret;
19665 }
19666
19667 /* OpenMP 4.0:
19668 #pragma omp simd simd-clause[optseq] new-line
19669 for-loop
19670
19671 LOC is the location of the #pragma token.
19672 */
19673
19674 #define OMP_SIMD_CLAUSE_MASK \
19675 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
19676 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
19677 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
19678 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
19679 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19680 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19681 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19682 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
19683 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
19684 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
19685 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
19686
19687 static tree
19688 c_parser_omp_simd (location_t loc, c_parser *parser,
19689 char *p_name, omp_clause_mask mask, tree *cclauses,
19690 bool *if_p)
19691 {
19692 tree block, clauses, ret;
19693
19694 strcat (p_name, " simd");
19695 mask |= OMP_SIMD_CLAUSE_MASK;
19696
19697 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19698 if (cclauses)
19699 {
19700 omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses);
19701 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
19702 tree c = omp_find_clause (cclauses[C_OMP_CLAUSE_SPLIT_FOR],
19703 OMP_CLAUSE_ORDERED);
19704 if (c && OMP_CLAUSE_ORDERED_EXPR (c))
19705 {
19706 error_at (OMP_CLAUSE_LOCATION (c),
19707 "%<ordered%> clause with parameter may not be specified "
19708 "on %qs construct", p_name);
19709 OMP_CLAUSE_ORDERED_EXPR (c) = NULL_TREE;
19710 }
19711 }
19712
19713 block = c_begin_compound_stmt (true);
19714 ret = c_parser_omp_for_loop (loc, parser, OMP_SIMD, clauses, cclauses, if_p);
19715 block = c_end_compound_stmt (loc, block, true);
19716 add_stmt (block);
19717
19718 return ret;
19719 }
19720
19721 /* OpenMP 2.5:
19722 #pragma omp for for-clause[optseq] new-line
19723 for-loop
19724
19725 OpenMP 4.0:
19726 #pragma omp for simd for-simd-clause[optseq] new-line
19727 for-loop
19728
19729 LOC is the location of the #pragma token.
19730 */
19731
19732 #define OMP_FOR_CLAUSE_MASK \
19733 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
19734 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
19735 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
19736 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
19737 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
19738 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
19739 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
19740 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
19741 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
19742 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
19743 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
19744
19745 static tree
19746 c_parser_omp_for (location_t loc, c_parser *parser,
19747 char *p_name, omp_clause_mask mask, tree *cclauses,
19748 bool *if_p)
19749 {
19750 tree block, clauses, ret;
19751
19752 strcat (p_name, " for");
19753 mask |= OMP_FOR_CLAUSE_MASK;
19754 /* parallel for{, simd} disallows nowait clause, but for
19755 target {teams distribute ,}parallel for{, simd} it should be accepted. */
19756 if (cclauses && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0)
19757 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
19758 /* Composite distribute parallel for{, simd} disallows ordered clause. */
19759 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
19760 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED);
19761
19762 if (c_parser_next_token_is (parser, CPP_NAME))
19763 {
19764 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19765
19766 if (strcmp (p, "simd") == 0)
19767 {
19768 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19769 if (cclauses == NULL)
19770 cclauses = cclauses_buf;
19771
19772 c_parser_consume_token (parser);
19773 if (!flag_openmp) /* flag_openmp_simd */
19774 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
19775 if_p);
19776 block = c_begin_compound_stmt (true);
19777 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
19778 block = c_end_compound_stmt (loc, block, true);
19779 if (ret == NULL_TREE)
19780 return ret;
19781 ret = make_node (OMP_FOR);
19782 TREE_TYPE (ret) = void_type_node;
19783 OMP_FOR_BODY (ret) = block;
19784 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
19785 SET_EXPR_LOCATION (ret, loc);
19786 add_stmt (ret);
19787 return ret;
19788 }
19789 }
19790 if (!flag_openmp) /* flag_openmp_simd */
19791 {
19792 c_parser_skip_to_pragma_eol (parser, false);
19793 return NULL_TREE;
19794 }
19795
19796 /* Composite distribute parallel for disallows linear clause. */
19797 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
19798 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR);
19799
19800 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19801 if (cclauses)
19802 {
19803 omp_split_clauses (loc, OMP_FOR, mask, clauses, cclauses);
19804 clauses = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
19805 }
19806
19807 block = c_begin_compound_stmt (true);
19808 ret = c_parser_omp_for_loop (loc, parser, OMP_FOR, clauses, cclauses, if_p);
19809 block = c_end_compound_stmt (loc, block, true);
19810 add_stmt (block);
19811
19812 return ret;
19813 }
19814
19815 static tree c_parser_omp_taskloop (location_t, c_parser *, char *,
19816 omp_clause_mask, tree *, bool *);
19817
19818 /* OpenMP 2.5:
19819 # pragma omp master new-line
19820 structured-block
19821
19822 LOC is the location of the #pragma token.
19823 */
19824
19825 static tree
19826 c_parser_omp_master (location_t loc, c_parser *parser,
19827 char *p_name, omp_clause_mask mask, tree *cclauses,
19828 bool *if_p)
19829 {
19830 tree block, clauses, ret;
19831
19832 strcat (p_name, " master");
19833
19834 if (c_parser_next_token_is (parser, CPP_NAME))
19835 {
19836 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19837
19838 if (strcmp (p, "taskloop") == 0)
19839 {
19840 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19841 if (cclauses == NULL)
19842 cclauses = cclauses_buf;
19843
19844 c_parser_consume_token (parser);
19845 if (!flag_openmp) /* flag_openmp_simd */
19846 return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
19847 if_p);
19848 block = c_begin_compound_stmt (true);
19849 ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
19850 if_p);
19851 block = c_end_compound_stmt (loc, block, true);
19852 if (ret == NULL_TREE)
19853 return ret;
19854 ret = c_finish_omp_master (loc, block);
19855 OMP_MASTER_COMBINED (ret) = 1;
19856 return ret;
19857 }
19858 }
19859 if (!flag_openmp) /* flag_openmp_simd */
19860 {
19861 c_parser_skip_to_pragma_eol (parser, false);
19862 return NULL_TREE;
19863 }
19864
19865 if (cclauses)
19866 {
19867 clauses = c_parser_omp_all_clauses (parser, mask, p_name, false);
19868 omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses);
19869 }
19870 else
19871 c_parser_skip_to_pragma_eol (parser);
19872
19873 return c_finish_omp_master (loc, c_parser_omp_structured_block (parser,
19874 if_p));
19875 }
19876
19877 /* OpenMP 5.1:
19878 # pragma omp masked masked-clauses new-line
19879 structured-block
19880
19881 LOC is the location of the #pragma token.
19882 */
19883
19884 #define OMP_MASKED_CLAUSE_MASK \
19885 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER)
19886
19887 static tree
19888 c_parser_omp_masked (location_t loc, c_parser *parser,
19889 char *p_name, omp_clause_mask mask, tree *cclauses,
19890 bool *if_p)
19891 {
19892 tree block, clauses, ret;
19893
19894 strcat (p_name, " masked");
19895 mask |= OMP_MASKED_CLAUSE_MASK;
19896
19897 if (c_parser_next_token_is (parser, CPP_NAME))
19898 {
19899 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19900
19901 if (strcmp (p, "taskloop") == 0)
19902 {
19903 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
19904 if (cclauses == NULL)
19905 cclauses = cclauses_buf;
19906
19907 c_parser_consume_token (parser);
19908 if (!flag_openmp) /* flag_openmp_simd */
19909 return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
19910 if_p);
19911 block = c_begin_compound_stmt (true);
19912 ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
19913 if_p);
19914 block = c_end_compound_stmt (loc, block, true);
19915 if (ret == NULL_TREE)
19916 return ret;
19917 ret = c_finish_omp_masked (loc, block,
19918 cclauses[C_OMP_CLAUSE_SPLIT_MASKED]);
19919 OMP_MASKED_COMBINED (ret) = 1;
19920 return ret;
19921 }
19922 }
19923 if (!flag_openmp) /* flag_openmp_simd */
19924 {
19925 c_parser_skip_to_pragma_eol (parser, false);
19926 return NULL_TREE;
19927 }
19928
19929 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
19930 if (cclauses)
19931 {
19932 omp_split_clauses (loc, OMP_MASKED, mask, clauses, cclauses);
19933 clauses = cclauses[C_OMP_CLAUSE_SPLIT_MASKED];
19934 }
19935
19936 return c_finish_omp_masked (loc, c_parser_omp_structured_block (parser,
19937 if_p),
19938 clauses);
19939 }
19940
19941 /* OpenMP 2.5:
19942 # pragma omp ordered new-line
19943 structured-block
19944
19945 OpenMP 4.5:
19946 # pragma omp ordered ordered-clauses new-line
19947 structured-block
19948
19949 # pragma omp ordered depend-clauses new-line */
19950
19951 #define OMP_ORDERED_CLAUSE_MASK \
19952 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
19953 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
19954
19955 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \
19956 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
19957
19958 static bool
19959 c_parser_omp_ordered (c_parser *parser, enum pragma_context context,
19960 bool *if_p)
19961 {
19962 location_t loc = c_parser_peek_token (parser)->location;
19963 c_parser_consume_pragma (parser);
19964
19965 if (context != pragma_stmt && context != pragma_compound)
19966 {
19967 c_parser_error (parser, "expected declaration specifiers");
19968 c_parser_skip_to_pragma_eol (parser, false);
19969 return false;
19970 }
19971
19972 if (c_parser_next_token_is (parser, CPP_NAME))
19973 {
19974 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19975
19976 if (!strcmp ("depend", p))
19977 {
19978 if (!flag_openmp) /* flag_openmp_simd */
19979 {
19980 c_parser_skip_to_pragma_eol (parser, false);
19981 return false;
19982 }
19983 if (context == pragma_stmt)
19984 {
19985 error_at (loc,
19986 "%<#pragma omp ordered%> with %<depend%> clause may "
19987 "only be used in compound statements");
19988 c_parser_skip_to_pragma_eol (parser, false);
19989 return true;
19990 }
19991
19992 tree clauses
19993 = c_parser_omp_all_clauses (parser,
19994 OMP_ORDERED_DEPEND_CLAUSE_MASK,
19995 "#pragma omp ordered");
19996 c_finish_omp_ordered (loc, clauses, NULL_TREE);
19997 return false;
19998 }
19999 }
20000
20001 tree clauses = c_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK,
20002 "#pragma omp ordered");
20003
20004 if (!flag_openmp /* flag_openmp_simd */
20005 && omp_find_clause (clauses, OMP_CLAUSE_SIMD) == NULL_TREE)
20006 return false;
20007
20008 c_finish_omp_ordered (loc, clauses,
20009 c_parser_omp_structured_block (parser, if_p));
20010 return true;
20011 }
20012
20013 /* OpenMP 2.5:
20014
20015 section-scope:
20016 { section-sequence }
20017
20018 section-sequence:
20019 section-directive[opt] structured-block
20020 section-sequence section-directive structured-block
20021
20022 OpenMP 5.1 allows structured-block-sequence instead of structured-block.
20023
20024 SECTIONS_LOC is the location of the #pragma omp sections. */
20025
20026 static tree
20027 c_parser_omp_sections_scope (location_t sections_loc, c_parser *parser)
20028 {
20029 tree stmt, substmt;
20030 bool error_suppress = false;
20031 location_t loc;
20032
20033 loc = c_parser_peek_token (parser)->location;
20034 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
20035 {
20036 /* Avoid skipping until the end of the block. */
20037 parser->error = false;
20038 return NULL_TREE;
20039 }
20040
20041 stmt = push_stmt_list ();
20042
20043 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION)
20044 {
20045 substmt = c_parser_omp_structured_block_sequence (parser,
20046 PRAGMA_OMP_SECTION);
20047 substmt = build1 (OMP_SECTION, void_type_node, substmt);
20048 SET_EXPR_LOCATION (substmt, loc);
20049 add_stmt (substmt);
20050 }
20051
20052 while (1)
20053 {
20054 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
20055 break;
20056 if (c_parser_next_token_is (parser, CPP_EOF))
20057 break;
20058
20059 loc = c_parser_peek_token (parser)->location;
20060 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION)
20061 {
20062 c_parser_consume_pragma (parser);
20063 c_parser_skip_to_pragma_eol (parser);
20064 error_suppress = false;
20065 }
20066 else if (!error_suppress)
20067 {
20068 error_at (loc, "expected %<#pragma omp section%> or %<}%>");
20069 error_suppress = true;
20070 }
20071
20072 substmt = c_parser_omp_structured_block_sequence (parser,
20073 PRAGMA_OMP_SECTION);
20074 substmt = build1 (OMP_SECTION, void_type_node, substmt);
20075 SET_EXPR_LOCATION (substmt, loc);
20076 add_stmt (substmt);
20077 }
20078 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
20079 "expected %<#pragma omp section%> or %<}%>");
20080
20081 substmt = pop_stmt_list (stmt);
20082
20083 stmt = make_node (OMP_SECTIONS);
20084 SET_EXPR_LOCATION (stmt, sections_loc);
20085 TREE_TYPE (stmt) = void_type_node;
20086 OMP_SECTIONS_BODY (stmt) = substmt;
20087
20088 return add_stmt (stmt);
20089 }
20090
20091 /* OpenMP 2.5:
20092 # pragma omp sections sections-clause[optseq] newline
20093 sections-scope
20094
20095 LOC is the location of the #pragma token.
20096 */
20097
20098 #define OMP_SECTIONS_CLAUSE_MASK \
20099 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20100 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20101 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20102 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20103 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20104 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20105
20106 static tree
20107 c_parser_omp_sections (location_t loc, c_parser *parser,
20108 char *p_name, omp_clause_mask mask, tree *cclauses)
20109 {
20110 tree block, clauses, ret;
20111
20112 strcat (p_name, " sections");
20113 mask |= OMP_SECTIONS_CLAUSE_MASK;
20114 if (cclauses)
20115 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
20116
20117 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20118 if (cclauses)
20119 {
20120 omp_split_clauses (loc, OMP_SECTIONS, mask, clauses, cclauses);
20121 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS];
20122 }
20123
20124 block = c_begin_compound_stmt (true);
20125 ret = c_parser_omp_sections_scope (loc, parser);
20126 if (ret)
20127 OMP_SECTIONS_CLAUSES (ret) = clauses;
20128 block = c_end_compound_stmt (loc, block, true);
20129 add_stmt (block);
20130
20131 return ret;
20132 }
20133
20134 /* OpenMP 2.5:
20135 # pragma omp parallel parallel-clause[optseq] new-line
20136 structured-block
20137 # pragma omp parallel for parallel-for-clause[optseq] new-line
20138 structured-block
20139 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
20140 structured-block
20141
20142 OpenMP 4.0:
20143 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
20144 structured-block
20145
20146 LOC is the location of the #pragma token.
20147 */
20148
20149 #define OMP_PARALLEL_CLAUSE_MASK \
20150 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20151 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20152 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20153 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
20154 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20155 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
20156 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20157 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
20158 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20159 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
20160
20161 static tree
20162 c_parser_omp_parallel (location_t loc, c_parser *parser,
20163 char *p_name, omp_clause_mask mask, tree *cclauses,
20164 bool *if_p)
20165 {
20166 tree stmt, clauses, block;
20167
20168 strcat (p_name, " parallel");
20169 mask |= OMP_PARALLEL_CLAUSE_MASK;
20170 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
20171 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0
20172 && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
20173 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN);
20174
20175 if (c_parser_next_token_is_keyword (parser, RID_FOR))
20176 {
20177 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20178 if (cclauses == NULL)
20179 cclauses = cclauses_buf;
20180
20181 c_parser_consume_token (parser);
20182 if (!flag_openmp) /* flag_openmp_simd */
20183 return c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
20184 block = c_begin_omp_parallel ();
20185 tree ret = c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
20186 stmt
20187 = c_finish_omp_parallel (loc, cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20188 block);
20189 if (ret == NULL_TREE)
20190 return ret;
20191 OMP_PARALLEL_COMBINED (stmt) = 1;
20192 return stmt;
20193 }
20194 /* When combined with distribute, parallel has to be followed by for.
20195 #pragma omp target parallel is allowed though. */
20196 else if (cclauses
20197 && (mask & (OMP_CLAUSE_MASK_1
20198 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
20199 {
20200 error_at (loc, "expected %<for%> after %qs", p_name);
20201 c_parser_skip_to_pragma_eol (parser);
20202 return NULL_TREE;
20203 }
20204 else if (c_parser_next_token_is (parser, CPP_NAME))
20205 {
20206 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20207 if (cclauses == NULL && strcmp (p, "masked") == 0)
20208 {
20209 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20210 cclauses = cclauses_buf;
20211
20212 c_parser_consume_token (parser);
20213 if (!flag_openmp) /* flag_openmp_simd */
20214 return c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
20215 if_p);
20216 block = c_begin_omp_parallel ();
20217 tree ret = c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
20218 if_p);
20219 stmt = c_finish_omp_parallel (loc,
20220 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20221 block);
20222 if (ret == NULL)
20223 return ret;
20224 /* masked does have just filter clause, but during gimplification
20225 isn't represented by a gimplification omp context, so for
20226 #pragma omp parallel masked don't set OMP_PARALLEL_COMBINED,
20227 so that
20228 #pragma omp parallel masked
20229 #pragma omp taskloop simd lastprivate (x)
20230 isn't confused with
20231 #pragma omp parallel masked taskloop simd lastprivate (x) */
20232 if (OMP_MASKED_COMBINED (ret))
20233 OMP_PARALLEL_COMBINED (stmt) = 1;
20234 return stmt;
20235 }
20236 else if (cclauses == NULL && strcmp (p, "master") == 0)
20237 {
20238 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20239 cclauses = cclauses_buf;
20240
20241 c_parser_consume_token (parser);
20242 if (!flag_openmp) /* flag_openmp_simd */
20243 return c_parser_omp_master (loc, parser, p_name, mask, cclauses,
20244 if_p);
20245 block = c_begin_omp_parallel ();
20246 tree ret = c_parser_omp_master (loc, parser, p_name, mask, cclauses,
20247 if_p);
20248 stmt = c_finish_omp_parallel (loc,
20249 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20250 block);
20251 if (ret == NULL)
20252 return ret;
20253 /* master doesn't have any clauses and during gimplification
20254 isn't represented by a gimplification omp context, so for
20255 #pragma omp parallel master don't set OMP_PARALLEL_COMBINED,
20256 so that
20257 #pragma omp parallel master
20258 #pragma omp taskloop simd lastprivate (x)
20259 isn't confused with
20260 #pragma omp parallel master taskloop simd lastprivate (x) */
20261 if (OMP_MASTER_COMBINED (ret))
20262 OMP_PARALLEL_COMBINED (stmt) = 1;
20263 return stmt;
20264 }
20265 else if (strcmp (p, "loop") == 0)
20266 {
20267 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20268 if (cclauses == NULL)
20269 cclauses = cclauses_buf;
20270
20271 c_parser_consume_token (parser);
20272 if (!flag_openmp) /* flag_openmp_simd */
20273 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
20274 if_p);
20275 block = c_begin_omp_parallel ();
20276 tree ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
20277 if_p);
20278 stmt
20279 = c_finish_omp_parallel (loc,
20280 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20281 block);
20282 if (ret == NULL_TREE)
20283 return ret;
20284 OMP_PARALLEL_COMBINED (stmt) = 1;
20285 return stmt;
20286 }
20287 else if (!flag_openmp) /* flag_openmp_simd */
20288 {
20289 c_parser_skip_to_pragma_eol (parser, false);
20290 return NULL_TREE;
20291 }
20292 else if (cclauses == NULL && strcmp (p, "sections") == 0)
20293 {
20294 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20295 cclauses = cclauses_buf;
20296
20297 c_parser_consume_token (parser);
20298 block = c_begin_omp_parallel ();
20299 c_parser_omp_sections (loc, parser, p_name, mask, cclauses);
20300 stmt = c_finish_omp_parallel (loc,
20301 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
20302 block);
20303 OMP_PARALLEL_COMBINED (stmt) = 1;
20304 return stmt;
20305 }
20306 }
20307 else if (!flag_openmp) /* flag_openmp_simd */
20308 {
20309 c_parser_skip_to_pragma_eol (parser, false);
20310 return NULL_TREE;
20311 }
20312
20313 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20314 if (cclauses)
20315 {
20316 omp_split_clauses (loc, OMP_PARALLEL, mask, clauses, cclauses);
20317 clauses = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
20318 }
20319
20320 block = c_begin_omp_parallel ();
20321 c_parser_statement (parser, if_p);
20322 stmt = c_finish_omp_parallel (loc, clauses, block);
20323
20324 return stmt;
20325 }
20326
20327 /* OpenMP 2.5:
20328 # pragma omp single single-clause[optseq] new-line
20329 structured-block
20330
20331 LOC is the location of the #pragma.
20332 */
20333
20334 #define OMP_SINGLE_CLAUSE_MASK \
20335 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20336 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20337 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
20338 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20339 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20340
20341 static tree
20342 c_parser_omp_single (location_t loc, c_parser *parser, bool *if_p)
20343 {
20344 tree stmt = make_node (OMP_SINGLE);
20345 SET_EXPR_LOCATION (stmt, loc);
20346 TREE_TYPE (stmt) = void_type_node;
20347
20348 OMP_SINGLE_CLAUSES (stmt)
20349 = c_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK,
20350 "#pragma omp single");
20351 OMP_SINGLE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
20352
20353 return add_stmt (stmt);
20354 }
20355
20356 /* OpenMP 5.1:
20357 # pragma omp scope scope-clause[optseq] new-line
20358 structured-block
20359
20360 LOC is the location of the #pragma.
20361 */
20362
20363 #define OMP_SCOPE_CLAUSE_MASK \
20364 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20365 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20366 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20367
20368 static tree
20369 c_parser_omp_scope (location_t loc, c_parser *parser, bool *if_p)
20370 {
20371 tree stmt = make_node (OMP_SCOPE);
20372 SET_EXPR_LOCATION (stmt, loc);
20373 TREE_TYPE (stmt) = void_type_node;
20374
20375 OMP_SCOPE_CLAUSES (stmt)
20376 = c_parser_omp_all_clauses (parser, OMP_SCOPE_CLAUSE_MASK,
20377 "#pragma omp scope");
20378 OMP_SCOPE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
20379
20380 return add_stmt (stmt);
20381 }
20382
20383 /* OpenMP 3.0:
20384 # pragma omp task task-clause[optseq] new-line
20385
20386 LOC is the location of the #pragma.
20387 */
20388
20389 #define OMP_TASK_CLAUSE_MASK \
20390 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20391 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
20392 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
20393 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20394 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20395 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20396 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
20397 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
20398 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20399 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
20400 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20401 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
20402 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH) \
20403 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_AFFINITY))
20404
20405 static tree
20406 c_parser_omp_task (location_t loc, c_parser *parser, bool *if_p)
20407 {
20408 tree clauses, block;
20409
20410 clauses = c_parser_omp_all_clauses (parser, OMP_TASK_CLAUSE_MASK,
20411 "#pragma omp task");
20412
20413 block = c_begin_omp_task ();
20414 c_parser_statement (parser, if_p);
20415 return c_finish_omp_task (loc, clauses, block);
20416 }
20417
20418 /* OpenMP 3.0:
20419 # pragma omp taskwait new-line
20420
20421 OpenMP 5.0:
20422 # pragma omp taskwait taskwait-clause[optseq] new-line
20423 */
20424
20425 #define OMP_TASKWAIT_CLAUSE_MASK \
20426 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
20427
20428 static void
20429 c_parser_omp_taskwait (c_parser *parser)
20430 {
20431 location_t loc = c_parser_peek_token (parser)->location;
20432 c_parser_consume_pragma (parser);
20433
20434 tree clauses
20435 = c_parser_omp_all_clauses (parser, OMP_TASKWAIT_CLAUSE_MASK,
20436 "#pragma omp taskwait");
20437
20438 if (clauses)
20439 {
20440 tree stmt = make_node (OMP_TASK);
20441 TREE_TYPE (stmt) = void_node;
20442 OMP_TASK_CLAUSES (stmt) = clauses;
20443 OMP_TASK_BODY (stmt) = NULL_TREE;
20444 SET_EXPR_LOCATION (stmt, loc);
20445 add_stmt (stmt);
20446 }
20447 else
20448 c_finish_omp_taskwait (loc);
20449 }
20450
20451 /* OpenMP 3.1:
20452 # pragma omp taskyield new-line
20453 */
20454
20455 static void
20456 c_parser_omp_taskyield (c_parser *parser)
20457 {
20458 location_t loc = c_parser_peek_token (parser)->location;
20459 c_parser_consume_pragma (parser);
20460 c_parser_skip_to_pragma_eol (parser);
20461
20462 c_finish_omp_taskyield (loc);
20463 }
20464
20465 /* OpenMP 4.0:
20466 # pragma omp taskgroup new-line
20467
20468 OpenMP 5.0:
20469 # pragma omp taskgroup taskgroup-clause[optseq] new-line
20470 */
20471
20472 #define OMP_TASKGROUP_CLAUSE_MASK \
20473 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20474 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
20475
20476 static tree
20477 c_parser_omp_taskgroup (location_t loc, c_parser *parser, bool *if_p)
20478 {
20479 tree clauses = c_parser_omp_all_clauses (parser, OMP_TASKGROUP_CLAUSE_MASK,
20480 "#pragma omp taskgroup");
20481
20482 tree body = c_parser_omp_structured_block (parser, if_p);
20483 return c_finish_omp_taskgroup (loc, body, clauses);
20484 }
20485
20486 /* OpenMP 4.0:
20487 # pragma omp cancel cancel-clause[optseq] new-line
20488
20489 LOC is the location of the #pragma.
20490 */
20491
20492 #define OMP_CANCEL_CLAUSE_MASK \
20493 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
20494 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
20495 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
20496 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
20497 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
20498
20499 static void
20500 c_parser_omp_cancel (c_parser *parser)
20501 {
20502 location_t loc = c_parser_peek_token (parser)->location;
20503
20504 c_parser_consume_pragma (parser);
20505 tree clauses = c_parser_omp_all_clauses (parser, OMP_CANCEL_CLAUSE_MASK,
20506 "#pragma omp cancel");
20507
20508 c_finish_omp_cancel (loc, clauses);
20509 }
20510
20511 /* OpenMP 4.0:
20512 # pragma omp cancellation point cancelpt-clause[optseq] new-line
20513
20514 LOC is the location of the #pragma.
20515 */
20516
20517 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \
20518 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
20519 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
20520 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
20521 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
20522
20523 static bool
20524 c_parser_omp_cancellation_point (c_parser *parser, enum pragma_context context)
20525 {
20526 location_t loc = c_parser_peek_token (parser)->location;
20527 tree clauses;
20528 bool point_seen = false;
20529
20530 c_parser_consume_pragma (parser);
20531 if (c_parser_next_token_is (parser, CPP_NAME))
20532 {
20533 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20534 if (strcmp (p, "point") == 0)
20535 {
20536 c_parser_consume_token (parser);
20537 point_seen = true;
20538 }
20539 }
20540 if (!point_seen)
20541 {
20542 c_parser_error (parser, "expected %<point%>");
20543 c_parser_skip_to_pragma_eol (parser);
20544 return false;
20545 }
20546
20547 if (context != pragma_compound)
20548 {
20549 if (context == pragma_stmt)
20550 error_at (loc,
20551 "%<#pragma %s%> may only be used in compound statements",
20552 "omp cancellation point");
20553 else
20554 c_parser_error (parser, "expected declaration specifiers");
20555 c_parser_skip_to_pragma_eol (parser, false);
20556 return true;
20557 }
20558
20559 clauses
20560 = c_parser_omp_all_clauses (parser, OMP_CANCELLATION_POINT_CLAUSE_MASK,
20561 "#pragma omp cancellation point");
20562
20563 c_finish_omp_cancellation_point (loc, clauses);
20564 return true;
20565 }
20566
20567 /* OpenMP 4.0:
20568 #pragma omp distribute distribute-clause[optseq] new-line
20569 for-loop */
20570
20571 #define OMP_DISTRIBUTE_CLAUSE_MASK \
20572 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20573 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20574 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20575 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
20576 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20577 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
20578 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
20579
20580 static tree
20581 c_parser_omp_distribute (location_t loc, c_parser *parser,
20582 char *p_name, omp_clause_mask mask, tree *cclauses,
20583 bool *if_p)
20584 {
20585 tree clauses, block, ret;
20586
20587 strcat (p_name, " distribute");
20588 mask |= OMP_DISTRIBUTE_CLAUSE_MASK;
20589
20590 if (c_parser_next_token_is (parser, CPP_NAME))
20591 {
20592 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20593 bool simd = false;
20594 bool parallel = false;
20595
20596 if (strcmp (p, "simd") == 0)
20597 simd = true;
20598 else
20599 parallel = strcmp (p, "parallel") == 0;
20600 if (parallel || simd)
20601 {
20602 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20603 if (cclauses == NULL)
20604 cclauses = cclauses_buf;
20605 c_parser_consume_token (parser);
20606 if (!flag_openmp) /* flag_openmp_simd */
20607 {
20608 if (simd)
20609 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
20610 if_p);
20611 else
20612 return c_parser_omp_parallel (loc, parser, p_name, mask,
20613 cclauses, if_p);
20614 }
20615 block = c_begin_compound_stmt (true);
20616 if (simd)
20617 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
20618 if_p);
20619 else
20620 ret = c_parser_omp_parallel (loc, parser, p_name, mask, cclauses,
20621 if_p);
20622 block = c_end_compound_stmt (loc, block, true);
20623 if (ret == NULL)
20624 return ret;
20625 ret = make_node (OMP_DISTRIBUTE);
20626 TREE_TYPE (ret) = void_type_node;
20627 OMP_FOR_BODY (ret) = block;
20628 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
20629 SET_EXPR_LOCATION (ret, loc);
20630 add_stmt (ret);
20631 return ret;
20632 }
20633 }
20634 if (!flag_openmp) /* flag_openmp_simd */
20635 {
20636 c_parser_skip_to_pragma_eol (parser, false);
20637 return NULL_TREE;
20638 }
20639
20640 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20641 if (cclauses)
20642 {
20643 omp_split_clauses (loc, OMP_DISTRIBUTE, mask, clauses, cclauses);
20644 clauses = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
20645 }
20646
20647 block = c_begin_compound_stmt (true);
20648 ret = c_parser_omp_for_loop (loc, parser, OMP_DISTRIBUTE, clauses, NULL,
20649 if_p);
20650 block = c_end_compound_stmt (loc, block, true);
20651 add_stmt (block);
20652
20653 return ret;
20654 }
20655
20656 /* OpenMP 4.0:
20657 # pragma omp teams teams-clause[optseq] new-line
20658 structured-block */
20659
20660 #define OMP_TEAMS_CLAUSE_MASK \
20661 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20662 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20663 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20664 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20665 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
20666 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
20667 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
20668 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
20669
20670 static tree
20671 c_parser_omp_teams (location_t loc, c_parser *parser,
20672 char *p_name, omp_clause_mask mask, tree *cclauses,
20673 bool *if_p)
20674 {
20675 tree clauses, block, ret;
20676
20677 strcat (p_name, " teams");
20678 mask |= OMP_TEAMS_CLAUSE_MASK;
20679
20680 if (c_parser_next_token_is (parser, CPP_NAME))
20681 {
20682 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20683 if (strcmp (p, "distribute") == 0)
20684 {
20685 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20686 if (cclauses == NULL)
20687 cclauses = cclauses_buf;
20688
20689 c_parser_consume_token (parser);
20690 if (!flag_openmp) /* flag_openmp_simd */
20691 return c_parser_omp_distribute (loc, parser, p_name, mask,
20692 cclauses, if_p);
20693 block = c_begin_omp_parallel ();
20694 ret = c_parser_omp_distribute (loc, parser, p_name, mask, cclauses,
20695 if_p);
20696 block = c_end_compound_stmt (loc, block, true);
20697 if (ret == NULL)
20698 return ret;
20699 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
20700 ret = make_node (OMP_TEAMS);
20701 TREE_TYPE (ret) = void_type_node;
20702 OMP_TEAMS_CLAUSES (ret) = clauses;
20703 OMP_TEAMS_BODY (ret) = block;
20704 OMP_TEAMS_COMBINED (ret) = 1;
20705 SET_EXPR_LOCATION (ret, loc);
20706 return add_stmt (ret);
20707 }
20708 else if (strcmp (p, "loop") == 0)
20709 {
20710 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20711 if (cclauses == NULL)
20712 cclauses = cclauses_buf;
20713
20714 c_parser_consume_token (parser);
20715 if (!flag_openmp) /* flag_openmp_simd */
20716 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
20717 if_p);
20718 block = c_begin_omp_parallel ();
20719 ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses, if_p);
20720 block = c_end_compound_stmt (loc, block, true);
20721 if (ret == NULL)
20722 return ret;
20723 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
20724 ret = make_node (OMP_TEAMS);
20725 TREE_TYPE (ret) = void_type_node;
20726 OMP_TEAMS_CLAUSES (ret) = clauses;
20727 OMP_TEAMS_BODY (ret) = block;
20728 OMP_TEAMS_COMBINED (ret) = 1;
20729 SET_EXPR_LOCATION (ret, loc);
20730 return add_stmt (ret);
20731 }
20732 }
20733 if (!flag_openmp) /* flag_openmp_simd */
20734 {
20735 c_parser_skip_to_pragma_eol (parser, false);
20736 return NULL_TREE;
20737 }
20738
20739 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20740 if (cclauses)
20741 {
20742 omp_split_clauses (loc, OMP_TEAMS, mask, clauses, cclauses);
20743 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
20744 }
20745
20746 tree stmt = make_node (OMP_TEAMS);
20747 TREE_TYPE (stmt) = void_type_node;
20748 OMP_TEAMS_CLAUSES (stmt) = clauses;
20749 block = c_begin_omp_parallel ();
20750 add_stmt (c_parser_omp_structured_block (parser, if_p));
20751 OMP_TEAMS_BODY (stmt) = c_end_compound_stmt (loc, block, true);
20752 SET_EXPR_LOCATION (stmt, loc);
20753
20754 return add_stmt (stmt);
20755 }
20756
20757 /* OpenMP 4.0:
20758 # pragma omp target data target-data-clause[optseq] new-line
20759 structured-block */
20760
20761 #define OMP_TARGET_DATA_CLAUSE_MASK \
20762 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
20763 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
20764 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20765 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
20766 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
20767
20768 static tree
20769 c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p)
20770 {
20771 tree clauses
20772 = c_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
20773 "#pragma omp target data");
20774 c_omp_adjust_map_clauses (clauses, false);
20775 int map_seen = 0;
20776 for (tree *pc = &clauses; *pc;)
20777 {
20778 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
20779 switch (OMP_CLAUSE_MAP_KIND (*pc))
20780 {
20781 case GOMP_MAP_TO:
20782 case GOMP_MAP_ALWAYS_TO:
20783 case GOMP_MAP_FROM:
20784 case GOMP_MAP_ALWAYS_FROM:
20785 case GOMP_MAP_TOFROM:
20786 case GOMP_MAP_ALWAYS_TOFROM:
20787 case GOMP_MAP_ALLOC:
20788 map_seen = 3;
20789 break;
20790 case GOMP_MAP_FIRSTPRIVATE_POINTER:
20791 case GOMP_MAP_ALWAYS_POINTER:
20792 case GOMP_MAP_ATTACH_DETACH:
20793 break;
20794 default:
20795 map_seen |= 1;
20796 error_at (OMP_CLAUSE_LOCATION (*pc),
20797 "%<#pragma omp target data%> with map-type other "
20798 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
20799 "on %<map%> clause");
20800 *pc = OMP_CLAUSE_CHAIN (*pc);
20801 continue;
20802 }
20803 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
20804 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
20805 map_seen = 3;
20806 pc = &OMP_CLAUSE_CHAIN (*pc);
20807 }
20808
20809 if (map_seen != 3)
20810 {
20811 if (map_seen == 0)
20812 error_at (loc,
20813 "%<#pragma omp target data%> must contain at least "
20814 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
20815 "clause");
20816 return NULL_TREE;
20817 }
20818
20819 tree stmt = make_node (OMP_TARGET_DATA);
20820 TREE_TYPE (stmt) = void_type_node;
20821 OMP_TARGET_DATA_CLAUSES (stmt) = clauses;
20822 keep_next_level ();
20823 tree block = c_begin_compound_stmt (true);
20824 add_stmt (c_parser_omp_structured_block (parser, if_p));
20825 OMP_TARGET_DATA_BODY (stmt) = c_end_compound_stmt (loc, block, true);
20826
20827 SET_EXPR_LOCATION (stmt, loc);
20828 return add_stmt (stmt);
20829 }
20830
20831 /* OpenMP 4.0:
20832 # pragma omp target update target-update-clause[optseq] new-line */
20833
20834 #define OMP_TARGET_UPDATE_CLAUSE_MASK \
20835 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
20836 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
20837 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
20838 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20839 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20840 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20841
20842 static bool
20843 c_parser_omp_target_update (location_t loc, c_parser *parser,
20844 enum pragma_context context)
20845 {
20846 if (context == pragma_stmt)
20847 {
20848 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
20849 "omp target update");
20850 c_parser_skip_to_pragma_eol (parser, false);
20851 return true;
20852 }
20853
20854 tree clauses
20855 = c_parser_omp_all_clauses (parser, OMP_TARGET_UPDATE_CLAUSE_MASK,
20856 "#pragma omp target update");
20857 if (omp_find_clause (clauses, OMP_CLAUSE_TO) == NULL_TREE
20858 && omp_find_clause (clauses, OMP_CLAUSE_FROM) == NULL_TREE)
20859 {
20860 error_at (loc,
20861 "%<#pragma omp target update%> must contain at least one "
20862 "%<from%> or %<to%> clauses");
20863 return false;
20864 }
20865
20866 tree stmt = make_node (OMP_TARGET_UPDATE);
20867 TREE_TYPE (stmt) = void_type_node;
20868 OMP_TARGET_UPDATE_CLAUSES (stmt) = clauses;
20869 SET_EXPR_LOCATION (stmt, loc);
20870 add_stmt (stmt);
20871 return false;
20872 }
20873
20874 /* OpenMP 4.5:
20875 # pragma omp target enter data target-data-clause[optseq] new-line */
20876
20877 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
20878 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
20879 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
20880 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20881 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20882 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20883
20884 static bool
20885 c_parser_omp_target_enter_data (location_t loc, c_parser *parser,
20886 enum pragma_context context)
20887 {
20888 bool data_seen = false;
20889 if (c_parser_next_token_is (parser, CPP_NAME))
20890 {
20891 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20892 if (strcmp (p, "data") == 0)
20893 {
20894 c_parser_consume_token (parser);
20895 data_seen = true;
20896 }
20897 }
20898 if (!data_seen)
20899 {
20900 c_parser_error (parser, "expected %<data%>");
20901 c_parser_skip_to_pragma_eol (parser);
20902 return false;
20903 }
20904
20905 if (context == pragma_stmt)
20906 {
20907 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
20908 "omp target enter data");
20909 c_parser_skip_to_pragma_eol (parser, false);
20910 return true;
20911 }
20912
20913 tree clauses
20914 = c_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK,
20915 "#pragma omp target enter data");
20916 c_omp_adjust_map_clauses (clauses, false);
20917 int map_seen = 0;
20918 for (tree *pc = &clauses; *pc;)
20919 {
20920 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
20921 switch (OMP_CLAUSE_MAP_KIND (*pc))
20922 {
20923 case GOMP_MAP_TO:
20924 case GOMP_MAP_ALWAYS_TO:
20925 case GOMP_MAP_ALLOC:
20926 map_seen = 3;
20927 break;
20928 case GOMP_MAP_FIRSTPRIVATE_POINTER:
20929 case GOMP_MAP_ALWAYS_POINTER:
20930 case GOMP_MAP_ATTACH_DETACH:
20931 break;
20932 default:
20933 map_seen |= 1;
20934 error_at (OMP_CLAUSE_LOCATION (*pc),
20935 "%<#pragma omp target enter data%> with map-type other "
20936 "than %<to%> or %<alloc%> on %<map%> clause");
20937 *pc = OMP_CLAUSE_CHAIN (*pc);
20938 continue;
20939 }
20940 pc = &OMP_CLAUSE_CHAIN (*pc);
20941 }
20942
20943 if (map_seen != 3)
20944 {
20945 if (map_seen == 0)
20946 error_at (loc,
20947 "%<#pragma omp target enter data%> must contain at least "
20948 "one %<map%> clause");
20949 return true;
20950 }
20951
20952 tree stmt = make_node (OMP_TARGET_ENTER_DATA);
20953 TREE_TYPE (stmt) = void_type_node;
20954 OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses;
20955 SET_EXPR_LOCATION (stmt, loc);
20956 add_stmt (stmt);
20957 return true;
20958 }
20959
20960 /* OpenMP 4.5:
20961 # pragma omp target exit data target-data-clause[optseq] new-line */
20962
20963 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
20964 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
20965 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
20966 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20967 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
20968 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
20969
20970 static bool
20971 c_parser_omp_target_exit_data (location_t loc, c_parser *parser,
20972 enum pragma_context context)
20973 {
20974 bool data_seen = false;
20975 if (c_parser_next_token_is (parser, CPP_NAME))
20976 {
20977 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20978 if (strcmp (p, "data") == 0)
20979 {
20980 c_parser_consume_token (parser);
20981 data_seen = true;
20982 }
20983 }
20984 if (!data_seen)
20985 {
20986 c_parser_error (parser, "expected %<data%>");
20987 c_parser_skip_to_pragma_eol (parser);
20988 return false;
20989 }
20990
20991 if (context == pragma_stmt)
20992 {
20993 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
20994 "omp target exit data");
20995 c_parser_skip_to_pragma_eol (parser, false);
20996 return true;
20997 }
20998
20999 tree clauses
21000 = c_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK,
21001 "#pragma omp target exit data");
21002 c_omp_adjust_map_clauses (clauses, false);
21003 int map_seen = 0;
21004 for (tree *pc = &clauses; *pc;)
21005 {
21006 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
21007 switch (OMP_CLAUSE_MAP_KIND (*pc))
21008 {
21009 case GOMP_MAP_FROM:
21010 case GOMP_MAP_ALWAYS_FROM:
21011 case GOMP_MAP_RELEASE:
21012 case GOMP_MAP_DELETE:
21013 map_seen = 3;
21014 break;
21015 case GOMP_MAP_FIRSTPRIVATE_POINTER:
21016 case GOMP_MAP_ALWAYS_POINTER:
21017 case GOMP_MAP_ATTACH_DETACH:
21018 break;
21019 default:
21020 map_seen |= 1;
21021 error_at (OMP_CLAUSE_LOCATION (*pc),
21022 "%<#pragma omp target exit data%> with map-type other "
21023 "than %<from%>, %<release%> or %<delete%> on %<map%>"
21024 " clause");
21025 *pc = OMP_CLAUSE_CHAIN (*pc);
21026 continue;
21027 }
21028 pc = &OMP_CLAUSE_CHAIN (*pc);
21029 }
21030
21031 if (map_seen != 3)
21032 {
21033 if (map_seen == 0)
21034 error_at (loc,
21035 "%<#pragma omp target exit data%> must contain at least one "
21036 "%<map%> clause");
21037 return true;
21038 }
21039
21040 tree stmt = make_node (OMP_TARGET_EXIT_DATA);
21041 TREE_TYPE (stmt) = void_type_node;
21042 OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses;
21043 SET_EXPR_LOCATION (stmt, loc);
21044 add_stmt (stmt);
21045 return true;
21046 }
21047
21048 /* OpenMP 4.0:
21049 # pragma omp target target-clause[optseq] new-line
21050 structured-block */
21051
21052 #define OMP_TARGET_CLAUSE_MASK \
21053 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
21054 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
21055 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
21056 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
21057 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
21058 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
21059 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
21060 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
21061 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
21062 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
21063 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
21064 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)\
21065 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR))
21066
21067 static bool
21068 c_parser_omp_target (c_parser *parser, enum pragma_context context, bool *if_p)
21069 {
21070 location_t loc = c_parser_peek_token (parser)->location;
21071 c_parser_consume_pragma (parser);
21072 tree *pc = NULL, stmt, block;
21073
21074 if (context != pragma_stmt && context != pragma_compound)
21075 {
21076 c_parser_error (parser, "expected declaration specifiers");
21077 c_parser_skip_to_pragma_eol (parser);
21078 return false;
21079 }
21080
21081 if (flag_openmp)
21082 omp_requires_mask
21083 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
21084
21085 if (c_parser_next_token_is (parser, CPP_NAME))
21086 {
21087 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21088 enum tree_code ccode = ERROR_MARK;
21089
21090 if (strcmp (p, "teams") == 0)
21091 ccode = OMP_TEAMS;
21092 else if (strcmp (p, "parallel") == 0)
21093 ccode = OMP_PARALLEL;
21094 else if (strcmp (p, "simd") == 0)
21095 ccode = OMP_SIMD;
21096 if (ccode != ERROR_MARK)
21097 {
21098 tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT];
21099 char p_name[sizeof ("#pragma omp target teams distribute "
21100 "parallel for simd")];
21101
21102 c_parser_consume_token (parser);
21103 strcpy (p_name, "#pragma omp target");
21104 if (!flag_openmp) /* flag_openmp_simd */
21105 {
21106 tree stmt;
21107 switch (ccode)
21108 {
21109 case OMP_TEAMS:
21110 stmt = c_parser_omp_teams (loc, parser, p_name,
21111 OMP_TARGET_CLAUSE_MASK,
21112 cclauses, if_p);
21113 break;
21114 case OMP_PARALLEL:
21115 stmt = c_parser_omp_parallel (loc, parser, p_name,
21116 OMP_TARGET_CLAUSE_MASK,
21117 cclauses, if_p);
21118 break;
21119 case OMP_SIMD:
21120 stmt = c_parser_omp_simd (loc, parser, p_name,
21121 OMP_TARGET_CLAUSE_MASK,
21122 cclauses, if_p);
21123 break;
21124 default:
21125 gcc_unreachable ();
21126 }
21127 return stmt != NULL_TREE;
21128 }
21129 keep_next_level ();
21130 tree block = c_begin_compound_stmt (true), ret;
21131 switch (ccode)
21132 {
21133 case OMP_TEAMS:
21134 ret = c_parser_omp_teams (loc, parser, p_name,
21135 OMP_TARGET_CLAUSE_MASK, cclauses,
21136 if_p);
21137 break;
21138 case OMP_PARALLEL:
21139 ret = c_parser_omp_parallel (loc, parser, p_name,
21140 OMP_TARGET_CLAUSE_MASK, cclauses,
21141 if_p);
21142 break;
21143 case OMP_SIMD:
21144 ret = c_parser_omp_simd (loc, parser, p_name,
21145 OMP_TARGET_CLAUSE_MASK, cclauses,
21146 if_p);
21147 break;
21148 default:
21149 gcc_unreachable ();
21150 }
21151 block = c_end_compound_stmt (loc, block, true);
21152 if (ret == NULL_TREE)
21153 return false;
21154 if (ccode == OMP_TEAMS)
21155 /* For combined target teams, ensure the num_teams and
21156 thread_limit clause expressions are evaluated on the host,
21157 before entering the target construct. */
21158 for (tree c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
21159 c; c = OMP_CLAUSE_CHAIN (c))
21160 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
21161 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
21162 for (int i = 0;
21163 i <= (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS); ++i)
21164 if (OMP_CLAUSE_OPERAND (c, i)
21165 && TREE_CODE (OMP_CLAUSE_OPERAND (c, i)) != INTEGER_CST)
21166 {
21167 tree expr = OMP_CLAUSE_OPERAND (c, i);
21168 tree tmp = create_tmp_var_raw (TREE_TYPE (expr));
21169 expr = build4 (TARGET_EXPR, TREE_TYPE (expr), tmp,
21170 expr, NULL_TREE, NULL_TREE);
21171 add_stmt (expr);
21172 OMP_CLAUSE_OPERAND (c, i) = expr;
21173 tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
21174 OMP_CLAUSE_FIRSTPRIVATE);
21175 OMP_CLAUSE_DECL (tc) = tmp;
21176 OMP_CLAUSE_CHAIN (tc)
21177 = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
21178 cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc;
21179 }
21180 tree stmt = make_node (OMP_TARGET);
21181 TREE_TYPE (stmt) = void_type_node;
21182 OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
21183 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
21184 OMP_TARGET_BODY (stmt) = block;
21185 OMP_TARGET_COMBINED (stmt) = 1;
21186 SET_EXPR_LOCATION (stmt, loc);
21187 add_stmt (stmt);
21188 pc = &OMP_TARGET_CLAUSES (stmt);
21189 goto check_clauses;
21190 }
21191 else if (!flag_openmp) /* flag_openmp_simd */
21192 {
21193 c_parser_skip_to_pragma_eol (parser, false);
21194 return false;
21195 }
21196 else if (strcmp (p, "data") == 0)
21197 {
21198 c_parser_consume_token (parser);
21199 c_parser_omp_target_data (loc, parser, if_p);
21200 return true;
21201 }
21202 else if (strcmp (p, "enter") == 0)
21203 {
21204 c_parser_consume_token (parser);
21205 return c_parser_omp_target_enter_data (loc, parser, context);
21206 }
21207 else if (strcmp (p, "exit") == 0)
21208 {
21209 c_parser_consume_token (parser);
21210 return c_parser_omp_target_exit_data (loc, parser, context);
21211 }
21212 else if (strcmp (p, "update") == 0)
21213 {
21214 c_parser_consume_token (parser);
21215 return c_parser_omp_target_update (loc, parser, context);
21216 }
21217 }
21218 if (!flag_openmp) /* flag_openmp_simd */
21219 {
21220 c_parser_skip_to_pragma_eol (parser, false);
21221 return false;
21222 }
21223
21224 stmt = make_node (OMP_TARGET);
21225 TREE_TYPE (stmt) = void_type_node;
21226
21227 OMP_TARGET_CLAUSES (stmt)
21228 = c_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK,
21229 "#pragma omp target", false);
21230 for (tree c = OMP_TARGET_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c))
21231 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION)
21232 {
21233 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
21234 OMP_CLAUSE_DECL (nc) = OMP_CLAUSE_DECL (c);
21235 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_ALWAYS_TOFROM);
21236 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
21237 OMP_CLAUSE_CHAIN (c) = nc;
21238 }
21239 OMP_TARGET_CLAUSES (stmt)
21240 = c_finish_omp_clauses (OMP_TARGET_CLAUSES (stmt), C_ORT_OMP_TARGET);
21241 c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
21242
21243 pc = &OMP_TARGET_CLAUSES (stmt);
21244 keep_next_level ();
21245 block = c_begin_compound_stmt (true);
21246 add_stmt (c_parser_omp_structured_block (parser, if_p));
21247 OMP_TARGET_BODY (stmt) = c_end_compound_stmt (loc, block, true);
21248
21249 SET_EXPR_LOCATION (stmt, loc);
21250 add_stmt (stmt);
21251
21252 check_clauses:
21253 while (*pc)
21254 {
21255 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
21256 switch (OMP_CLAUSE_MAP_KIND (*pc))
21257 {
21258 case GOMP_MAP_TO:
21259 case GOMP_MAP_ALWAYS_TO:
21260 case GOMP_MAP_FROM:
21261 case GOMP_MAP_ALWAYS_FROM:
21262 case GOMP_MAP_TOFROM:
21263 case GOMP_MAP_ALWAYS_TOFROM:
21264 case GOMP_MAP_ALLOC:
21265 case GOMP_MAP_FIRSTPRIVATE_POINTER:
21266 case GOMP_MAP_ALWAYS_POINTER:
21267 case GOMP_MAP_ATTACH_DETACH:
21268 break;
21269 default:
21270 error_at (OMP_CLAUSE_LOCATION (*pc),
21271 "%<#pragma omp target%> with map-type other "
21272 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
21273 "on %<map%> clause");
21274 *pc = OMP_CLAUSE_CHAIN (*pc);
21275 continue;
21276 }
21277 pc = &OMP_CLAUSE_CHAIN (*pc);
21278 }
21279 cfun->has_omp_target = true;
21280 return true;
21281 }
21282
21283 /* OpenMP 4.0:
21284 # pragma omp declare simd declare-simd-clauses[optseq] new-line
21285
21286 OpenMP 5.0:
21287 # pragma omp declare variant (identifier) match(context-selector) new-line
21288 */
21289
21290 #define OMP_DECLARE_SIMD_CLAUSE_MASK \
21291 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
21292 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
21293 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
21294 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
21295 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
21296 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
21297
21298 static void
21299 c_parser_omp_declare_simd (c_parser *parser, enum pragma_context context)
21300 {
21301 c_token *token = c_parser_peek_token (parser);
21302 gcc_assert (token->type == CPP_NAME);
21303 tree kind = token->value;
21304 gcc_assert (strcmp (IDENTIFIER_POINTER (kind), "simd") == 0
21305 || strcmp (IDENTIFIER_POINTER (kind), "variant") == 0);
21306
21307 auto_vec<c_token> clauses;
21308 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
21309 {
21310 c_token *token = c_parser_peek_token (parser);
21311 if (token->type == CPP_EOF)
21312 {
21313 c_parser_skip_to_pragma_eol (parser);
21314 return;
21315 }
21316 clauses.safe_push (*token);
21317 c_parser_consume_token (parser);
21318 }
21319 clauses.safe_push (*c_parser_peek_token (parser));
21320 c_parser_skip_to_pragma_eol (parser);
21321
21322 while (c_parser_next_token_is (parser, CPP_PRAGMA))
21323 {
21324 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_DECLARE
21325 || c_parser_peek_2nd_token (parser)->type != CPP_NAME
21326 || c_parser_peek_2nd_token (parser)->value != kind)
21327 {
21328 error ("%<#pragma omp declare %s%> must be followed by "
21329 "function declaration or definition or another "
21330 "%<#pragma omp declare %s%>",
21331 IDENTIFIER_POINTER (kind), IDENTIFIER_POINTER (kind));
21332 return;
21333 }
21334 c_parser_consume_pragma (parser);
21335 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
21336 {
21337 c_token *token = c_parser_peek_token (parser);
21338 if (token->type == CPP_EOF)
21339 {
21340 c_parser_skip_to_pragma_eol (parser);
21341 return;
21342 }
21343 clauses.safe_push (*token);
21344 c_parser_consume_token (parser);
21345 }
21346 clauses.safe_push (*c_parser_peek_token (parser));
21347 c_parser_skip_to_pragma_eol (parser);
21348 }
21349
21350 /* Make sure nothing tries to read past the end of the tokens. */
21351 c_token eof_token;
21352 memset (&eof_token, 0, sizeof (eof_token));
21353 eof_token.type = CPP_EOF;
21354 clauses.safe_push (eof_token);
21355 clauses.safe_push (eof_token);
21356
21357 switch (context)
21358 {
21359 case pragma_external:
21360 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21361 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
21362 {
21363 int ext = disable_extension_diagnostics ();
21364 do
21365 c_parser_consume_token (parser);
21366 while (c_parser_next_token_is (parser, CPP_KEYWORD)
21367 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
21368 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
21369 NULL, &clauses);
21370 restore_extension_diagnostics (ext);
21371 }
21372 else
21373 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
21374 NULL, &clauses);
21375 break;
21376 case pragma_struct:
21377 case pragma_param:
21378 case pragma_stmt:
21379 error ("%<#pragma omp declare %s%> must be followed by "
21380 "function declaration or definition",
21381 IDENTIFIER_POINTER (kind));
21382 break;
21383 case pragma_compound:
21384 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21385 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
21386 {
21387 int ext = disable_extension_diagnostics ();
21388 do
21389 c_parser_consume_token (parser);
21390 while (c_parser_next_token_is (parser, CPP_KEYWORD)
21391 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
21392 if (c_parser_next_tokens_start_declaration (parser))
21393 {
21394 c_parser_declaration_or_fndef (parser, true, true, true, true,
21395 true, NULL, &clauses);
21396 restore_extension_diagnostics (ext);
21397 break;
21398 }
21399 restore_extension_diagnostics (ext);
21400 }
21401 else if (c_parser_next_tokens_start_declaration (parser))
21402 {
21403 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
21404 NULL, &clauses);
21405 break;
21406 }
21407 error ("%<#pragma omp declare %s%> must be followed by "
21408 "function declaration or definition",
21409 IDENTIFIER_POINTER (kind));
21410 break;
21411 default:
21412 gcc_unreachable ();
21413 }
21414 }
21415
21416 static const char *const omp_construct_selectors[] = {
21417 "simd", "target", "teams", "parallel", "for", NULL };
21418 static const char *const omp_device_selectors[] = {
21419 "kind", "isa", "arch", NULL };
21420 static const char *const omp_implementation_selectors[] = {
21421 "vendor", "extension", "atomic_default_mem_order", "unified_address",
21422 "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL };
21423 static const char *const omp_user_selectors[] = {
21424 "condition", NULL };
21425
21426 /* OpenMP 5.0:
21427
21428 trait-selector:
21429 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
21430
21431 trait-score:
21432 score(score-expression) */
21433
21434 static tree
21435 c_parser_omp_context_selector (c_parser *parser, tree set, tree parms)
21436 {
21437 tree ret = NULL_TREE;
21438 do
21439 {
21440 tree selector;
21441 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21442 || c_parser_next_token_is (parser, CPP_NAME))
21443 selector = c_parser_peek_token (parser)->value;
21444 else
21445 {
21446 c_parser_error (parser, "expected trait selector name");
21447 return error_mark_node;
21448 }
21449
21450 tree properties = NULL_TREE;
21451 const char *const *selectors = NULL;
21452 bool allow_score = true;
21453 bool allow_user = false;
21454 int property_limit = 0;
21455 enum { CTX_PROPERTY_NONE, CTX_PROPERTY_USER, CTX_PROPERTY_NAME_LIST,
21456 CTX_PROPERTY_ID, CTX_PROPERTY_EXPR,
21457 CTX_PROPERTY_SIMD } property_kind = CTX_PROPERTY_NONE;
21458 switch (IDENTIFIER_POINTER (set)[0])
21459 {
21460 case 'c': /* construct */
21461 selectors = omp_construct_selectors;
21462 allow_score = false;
21463 property_limit = 1;
21464 property_kind = CTX_PROPERTY_SIMD;
21465 break;
21466 case 'd': /* device */
21467 selectors = omp_device_selectors;
21468 allow_score = false;
21469 allow_user = true;
21470 property_limit = 3;
21471 property_kind = CTX_PROPERTY_NAME_LIST;
21472 break;
21473 case 'i': /* implementation */
21474 selectors = omp_implementation_selectors;
21475 allow_user = true;
21476 property_limit = 3;
21477 property_kind = CTX_PROPERTY_NAME_LIST;
21478 break;
21479 case 'u': /* user */
21480 selectors = omp_user_selectors;
21481 property_limit = 1;
21482 property_kind = CTX_PROPERTY_EXPR;
21483 break;
21484 default:
21485 gcc_unreachable ();
21486 }
21487 for (int i = 0; ; i++)
21488 {
21489 if (selectors[i] == NULL)
21490 {
21491 if (allow_user)
21492 {
21493 property_kind = CTX_PROPERTY_USER;
21494 break;
21495 }
21496 else
21497 {
21498 error_at (c_parser_peek_token (parser)->location,
21499 "selector %qs not allowed for context selector "
21500 "set %qs", IDENTIFIER_POINTER (selector),
21501 IDENTIFIER_POINTER (set));
21502 c_parser_consume_token (parser);
21503 return error_mark_node;
21504 }
21505 }
21506 if (i == property_limit)
21507 property_kind = CTX_PROPERTY_NONE;
21508 if (strcmp (selectors[i], IDENTIFIER_POINTER (selector)) == 0)
21509 break;
21510 }
21511 if (property_kind == CTX_PROPERTY_NAME_LIST
21512 && IDENTIFIER_POINTER (set)[0] == 'i'
21513 && strcmp (IDENTIFIER_POINTER (selector),
21514 "atomic_default_mem_order") == 0)
21515 property_kind = CTX_PROPERTY_ID;
21516
21517 c_parser_consume_token (parser);
21518
21519 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
21520 {
21521 if (property_kind == CTX_PROPERTY_NONE)
21522 {
21523 error_at (c_parser_peek_token (parser)->location,
21524 "selector %qs does not accept any properties",
21525 IDENTIFIER_POINTER (selector));
21526 return error_mark_node;
21527 }
21528
21529 matching_parens parens;
21530 parens.require_open (parser);
21531
21532 c_token *token = c_parser_peek_token (parser);
21533 if (allow_score
21534 && c_parser_next_token_is (parser, CPP_NAME)
21535 && strcmp (IDENTIFIER_POINTER (token->value), "score") == 0
21536 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
21537 {
21538 c_parser_consume_token (parser);
21539
21540 matching_parens parens2;
21541 parens2.require_open (parser);
21542 tree score = c_parser_expr_no_commas (parser, NULL).value;
21543 parens2.skip_until_found_close (parser);
21544 c_parser_require (parser, CPP_COLON, "expected %<:%>");
21545 if (score != error_mark_node)
21546 {
21547 mark_exp_read (score);
21548 score = c_fully_fold (score, false, NULL);
21549 if (!INTEGRAL_TYPE_P (TREE_TYPE (score))
21550 || TREE_CODE (score) != INTEGER_CST)
21551 error_at (token->location, "score argument must be "
21552 "constant integer expression");
21553 else if (tree_int_cst_sgn (score) < 0)
21554 error_at (token->location, "score argument must be "
21555 "non-negative");
21556 else
21557 properties = tree_cons (get_identifier (" score"),
21558 score, properties);
21559 }
21560 token = c_parser_peek_token (parser);
21561 }
21562
21563 switch (property_kind)
21564 {
21565 tree t;
21566 case CTX_PROPERTY_USER:
21567 do
21568 {
21569 t = c_parser_expr_no_commas (parser, NULL).value;
21570 if (TREE_CODE (t) == STRING_CST)
21571 properties = tree_cons (NULL_TREE, t, properties);
21572 else if (t != error_mark_node)
21573 {
21574 mark_exp_read (t);
21575 t = c_fully_fold (t, false, NULL);
21576 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
21577 || !tree_fits_shwi_p (t))
21578 error_at (token->location, "property must be "
21579 "constant integer expression or string "
21580 "literal");
21581 else
21582 properties = tree_cons (NULL_TREE, t, properties);
21583 }
21584 else
21585 return error_mark_node;
21586
21587 if (c_parser_next_token_is (parser, CPP_COMMA))
21588 c_parser_consume_token (parser);
21589 else
21590 break;
21591 }
21592 while (1);
21593 break;
21594 case CTX_PROPERTY_ID:
21595 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21596 || c_parser_next_token_is (parser, CPP_NAME))
21597 {
21598 tree prop = c_parser_peek_token (parser)->value;
21599 c_parser_consume_token (parser);
21600 properties = tree_cons (prop, NULL_TREE, properties);
21601 }
21602 else
21603 {
21604 c_parser_error (parser, "expected identifier");
21605 return error_mark_node;
21606 }
21607 break;
21608 case CTX_PROPERTY_NAME_LIST:
21609 do
21610 {
21611 tree prop = NULL_TREE, value = NULL_TREE;
21612 if (c_parser_next_token_is (parser, CPP_KEYWORD)
21613 || c_parser_next_token_is (parser, CPP_NAME))
21614 {
21615 prop = c_parser_peek_token (parser)->value;
21616 c_parser_consume_token (parser);
21617 }
21618 else if (c_parser_next_token_is (parser, CPP_STRING))
21619 value = c_parser_string_literal (parser, false,
21620 false).value;
21621 else
21622 {
21623 c_parser_error (parser, "expected identifier or "
21624 "string literal");
21625 return error_mark_node;
21626 }
21627
21628 properties = tree_cons (prop, value, properties);
21629
21630 if (c_parser_next_token_is (parser, CPP_COMMA))
21631 c_parser_consume_token (parser);
21632 else
21633 break;
21634 }
21635 while (1);
21636 break;
21637 case CTX_PROPERTY_EXPR:
21638 t = c_parser_expr_no_commas (parser, NULL).value;
21639 if (t != error_mark_node)
21640 {
21641 mark_exp_read (t);
21642 t = c_fully_fold (t, false, NULL);
21643 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
21644 || !tree_fits_shwi_p (t))
21645 error_at (token->location, "property must be "
21646 "constant integer expression");
21647 else
21648 properties = tree_cons (NULL_TREE, t, properties);
21649 }
21650 else
21651 return error_mark_node;
21652 break;
21653 case CTX_PROPERTY_SIMD:
21654 if (parms == NULL_TREE)
21655 {
21656 error_at (token->location, "properties for %<simd%> "
21657 "selector may not be specified in "
21658 "%<metadirective%>");
21659 return error_mark_node;
21660 }
21661 tree c;
21662 c = c_parser_omp_all_clauses (parser,
21663 OMP_DECLARE_SIMD_CLAUSE_MASK,
21664 "simd", true, 2);
21665 c = c_omp_declare_simd_clauses_to_numbers (parms
21666 == error_mark_node
21667 ? NULL_TREE : parms,
21668 c);
21669 properties = c;
21670 break;
21671 default:
21672 gcc_unreachable ();
21673 }
21674
21675 parens.skip_until_found_close (parser);
21676 properties = nreverse (properties);
21677 }
21678 else if (property_kind == CTX_PROPERTY_NAME_LIST
21679 || property_kind == CTX_PROPERTY_ID
21680 || property_kind == CTX_PROPERTY_EXPR)
21681 {
21682 c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>");
21683 return error_mark_node;
21684 }
21685
21686 ret = tree_cons (selector, properties, ret);
21687
21688 if (c_parser_next_token_is (parser, CPP_COMMA))
21689 c_parser_consume_token (parser);
21690 else
21691 break;
21692 }
21693 while (1);
21694
21695 return nreverse (ret);
21696 }
21697
21698 /* OpenMP 5.0:
21699
21700 trait-set-selector[,trait-set-selector[,...]]
21701
21702 trait-set-selector:
21703 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
21704
21705 trait-set-selector-name:
21706 constructor
21707 device
21708 implementation
21709 user */
21710
21711 static tree
21712 c_parser_omp_context_selector_specification (c_parser *parser, tree parms)
21713 {
21714 tree ret = NULL_TREE;
21715 do
21716 {
21717 const char *setp = "";
21718 if (c_parser_next_token_is (parser, CPP_NAME))
21719 setp = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21720 switch (setp[0])
21721 {
21722 case 'c':
21723 if (strcmp (setp, "construct") == 0)
21724 setp = NULL;
21725 break;
21726 case 'd':
21727 if (strcmp (setp, "device") == 0)
21728 setp = NULL;
21729 break;
21730 case 'i':
21731 if (strcmp (setp, "implementation") == 0)
21732 setp = NULL;
21733 break;
21734 case 'u':
21735 if (strcmp (setp, "user") == 0)
21736 setp = NULL;
21737 break;
21738 default:
21739 break;
21740 }
21741 if (setp)
21742 {
21743 c_parser_error (parser, "expected %<construct%>, %<device%>, "
21744 "%<implementation%> or %<user%>");
21745 return error_mark_node;
21746 }
21747
21748 tree set = c_parser_peek_token (parser)->value;
21749 c_parser_consume_token (parser);
21750
21751 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
21752 return error_mark_node;
21753
21754 matching_braces braces;
21755 if (!braces.require_open (parser))
21756 return error_mark_node;
21757
21758 tree selectors = c_parser_omp_context_selector (parser, set, parms);
21759 if (selectors == error_mark_node)
21760 ret = error_mark_node;
21761 else if (ret != error_mark_node)
21762 ret = tree_cons (set, selectors, ret);
21763
21764 braces.skip_until_found_close (parser);
21765
21766 if (c_parser_next_token_is (parser, CPP_COMMA))
21767 c_parser_consume_token (parser);
21768 else
21769 break;
21770 }
21771 while (1);
21772
21773 if (ret == error_mark_node)
21774 return ret;
21775 return nreverse (ret);
21776 }
21777
21778 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
21779 that into "omp declare variant base" attribute. */
21780
21781 static void
21782 c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms)
21783 {
21784 matching_parens parens;
21785 if (!parens.require_open (parser))
21786 {
21787 fail:
21788 c_parser_skip_to_pragma_eol (parser, false);
21789 return;
21790 }
21791
21792 if (c_parser_next_token_is_not (parser, CPP_NAME)
21793 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
21794 {
21795 c_parser_error (parser, "expected identifier");
21796 goto fail;
21797 }
21798
21799 c_token *token = c_parser_peek_token (parser);
21800 tree variant = lookup_name (token->value);
21801
21802 if (variant == NULL_TREE)
21803 {
21804 undeclared_variable (token->location, token->value);
21805 variant = error_mark_node;
21806 }
21807
21808 c_parser_consume_token (parser);
21809
21810 parens.require_close (parser);
21811
21812 const char *clause = "";
21813 location_t match_loc = c_parser_peek_token (parser)->location;
21814 if (c_parser_next_token_is (parser, CPP_NAME))
21815 clause = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
21816 if (strcmp (clause, "match"))
21817 {
21818 c_parser_error (parser, "expected %<match%>");
21819 goto fail;
21820 }
21821
21822 c_parser_consume_token (parser);
21823
21824 if (!parens.require_open (parser))
21825 goto fail;
21826
21827 if (parms == NULL_TREE)
21828 parms = error_mark_node;
21829
21830 tree ctx = c_parser_omp_context_selector_specification (parser, parms);
21831 if (ctx == error_mark_node)
21832 goto fail;
21833 ctx = omp_check_context_selector (match_loc, ctx);
21834 if (ctx != error_mark_node && variant != error_mark_node)
21835 {
21836 if (TREE_CODE (variant) != FUNCTION_DECL)
21837 {
21838 error_at (token->location, "variant %qD is not a function", variant);
21839 variant = error_mark_node;
21840 }
21841 else if (omp_get_context_selector (ctx, "construct", "simd") == NULL_TREE
21842 && !comptypes (TREE_TYPE (fndecl), TREE_TYPE (variant)))
21843 {
21844 error_at (token->location, "variant %qD and base %qD have "
21845 "incompatible types", variant, fndecl);
21846 variant = error_mark_node;
21847 }
21848 else if (fndecl_built_in_p (variant)
21849 && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
21850 "__builtin_", strlen ("__builtin_")) == 0
21851 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
21852 "__sync_", strlen ("__sync_")) == 0
21853 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
21854 "__atomic_", strlen ("__atomic_")) == 0))
21855 {
21856 error_at (token->location, "variant %qD is a built-in", variant);
21857 variant = error_mark_node;
21858 }
21859 if (variant != error_mark_node)
21860 {
21861 C_DECL_USED (variant) = 1;
21862 tree construct = omp_get_context_selector (ctx, "construct", NULL);
21863 omp_mark_declare_variant (match_loc, variant, construct);
21864 if (omp_context_selector_matches (ctx))
21865 {
21866 tree attr
21867 = tree_cons (get_identifier ("omp declare variant base"),
21868 build_tree_list (variant, ctx),
21869 DECL_ATTRIBUTES (fndecl));
21870 DECL_ATTRIBUTES (fndecl) = attr;
21871 }
21872 }
21873 }
21874
21875 parens.require_close (parser);
21876 c_parser_skip_to_pragma_eol (parser);
21877 }
21878
21879 /* Finalize #pragma omp declare simd or #pragma omp declare variant
21880 clauses after FNDECL has been parsed, and put that into "omp declare simd"
21881 or "omp declare variant base" attribute. */
21882
21883 static void
21884 c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms,
21885 vec<c_token> *pclauses)
21886 {
21887 vec<c_token> &clauses = *pclauses;
21888
21889 /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there
21890 indicates error has been reported and CPP_PRAGMA that
21891 c_finish_omp_declare_simd has already processed the tokens. */
21892 if (clauses.exists () && clauses[0].type == CPP_EOF)
21893 return;
21894 const char *kind = "simd";
21895 if (clauses.exists ()
21896 && (clauses[0].type == CPP_NAME || clauses[0].type == CPP_PRAGMA))
21897 kind = IDENTIFIER_POINTER (clauses[0].value);
21898 gcc_assert (strcmp (kind, "simd") == 0 || strcmp (kind, "variant") == 0);
21899 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
21900 {
21901 error ("%<#pragma omp declare %s%> not immediately followed by "
21902 "a function declaration or definition", kind);
21903 clauses[0].type = CPP_EOF;
21904 return;
21905 }
21906 if (clauses.exists () && clauses[0].type != CPP_NAME)
21907 {
21908 error_at (DECL_SOURCE_LOCATION (fndecl),
21909 "%<#pragma omp declare %s%> not immediately followed by "
21910 "a single function declaration or definition", kind);
21911 clauses[0].type = CPP_EOF;
21912 return;
21913 }
21914
21915 if (parms == NULL_TREE)
21916 parms = DECL_ARGUMENTS (fndecl);
21917
21918 unsigned int tokens_avail = parser->tokens_avail;
21919 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
21920
21921 parser->tokens = clauses.address ();
21922 parser->tokens_avail = clauses.length ();
21923
21924 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
21925 while (parser->tokens_avail > 3)
21926 {
21927 c_token *token = c_parser_peek_token (parser);
21928 gcc_assert (token->type == CPP_NAME
21929 && strcmp (IDENTIFIER_POINTER (token->value), kind) == 0);
21930 c_parser_consume_token (parser);
21931 parser->in_pragma = true;
21932
21933 if (strcmp (kind, "simd") == 0)
21934 {
21935 tree c;
21936 c = c_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
21937 "#pragma omp declare simd");
21938 c = c_omp_declare_simd_clauses_to_numbers (parms, c);
21939 if (c != NULL_TREE)
21940 c = tree_cons (NULL_TREE, c, NULL_TREE);
21941 c = build_tree_list (get_identifier ("omp declare simd"), c);
21942 TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl);
21943 DECL_ATTRIBUTES (fndecl) = c;
21944 }
21945 else
21946 {
21947 gcc_assert (strcmp (kind, "variant") == 0);
21948 c_finish_omp_declare_variant (parser, fndecl, parms);
21949 }
21950 }
21951
21952 parser->tokens = &parser->tokens_buf[0];
21953 parser->tokens_avail = tokens_avail;
21954 if (clauses.exists ())
21955 clauses[0].type = CPP_PRAGMA;
21956 }
21957
21958
21959 /* OpenMP 4.0:
21960 # pragma omp declare target new-line
21961 declarations and definitions
21962 # pragma omp end declare target new-line
21963
21964 OpenMP 4.5:
21965 # pragma omp declare target ( extended-list ) new-line
21966
21967 # pragma omp declare target declare-target-clauses[seq] new-line */
21968
21969 #define OMP_DECLARE_TARGET_CLAUSE_MASK \
21970 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
21971 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
21972 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
21973
21974 static void
21975 c_parser_omp_declare_target (c_parser *parser)
21976 {
21977 tree clauses = NULL_TREE;
21978 int device_type = 0;
21979 bool only_device_type = true;
21980 if (c_parser_next_token_is (parser, CPP_NAME))
21981 clauses = c_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
21982 "#pragma omp declare target");
21983 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
21984 {
21985 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO_DECLARE,
21986 clauses);
21987 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
21988 c_parser_skip_to_pragma_eol (parser);
21989 }
21990 else
21991 {
21992 c_parser_skip_to_pragma_eol (parser);
21993 current_omp_declare_target_attribute++;
21994 return;
21995 }
21996 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
21997 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
21998 device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
21999 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
22000 {
22001 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
22002 continue;
22003 tree t = OMP_CLAUSE_DECL (c), id;
22004 tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
22005 tree at2 = lookup_attribute ("omp declare target link",
22006 DECL_ATTRIBUTES (t));
22007 only_device_type = false;
22008 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
22009 {
22010 id = get_identifier ("omp declare target link");
22011 std::swap (at1, at2);
22012 }
22013 else
22014 id = get_identifier ("omp declare target");
22015 if (at2)
22016 {
22017 error_at (OMP_CLAUSE_LOCATION (c),
22018 "%qD specified both in declare target %<link%> and %<to%>"
22019 " clauses", t);
22020 continue;
22021 }
22022 if (!at1)
22023 {
22024 DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
22025 if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t))
22026 continue;
22027
22028 symtab_node *node = symtab_node::get (t);
22029 if (node != NULL)
22030 {
22031 node->offloadable = 1;
22032 if (ENABLE_OFFLOADING)
22033 {
22034 g->have_offload = true;
22035 if (is_a <varpool_node *> (node))
22036 vec_safe_push (offload_vars, t);
22037 }
22038 }
22039 }
22040 if (TREE_CODE (t) != FUNCTION_DECL)
22041 continue;
22042 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0)
22043 {
22044 tree at3 = lookup_attribute ("omp declare target host",
22045 DECL_ATTRIBUTES (t));
22046 if (at3 == NULL_TREE)
22047 {
22048 id = get_identifier ("omp declare target host");
22049 DECL_ATTRIBUTES (t)
22050 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
22051 }
22052 }
22053 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0)
22054 {
22055 tree at3 = lookup_attribute ("omp declare target nohost",
22056 DECL_ATTRIBUTES (t));
22057 if (at3 == NULL_TREE)
22058 {
22059 id = get_identifier ("omp declare target nohost");
22060 DECL_ATTRIBUTES (t)
22061 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
22062 }
22063 }
22064 }
22065 if (device_type && only_device_type)
22066 warning_at (OMP_CLAUSE_LOCATION (clauses), 0,
22067 "directive with only %<device_type%> clauses ignored");
22068 }
22069
22070 static void
22071 c_parser_omp_end_declare_target (c_parser *parser)
22072 {
22073 location_t loc = c_parser_peek_token (parser)->location;
22074 c_parser_consume_pragma (parser);
22075 if (c_parser_next_token_is (parser, CPP_NAME)
22076 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
22077 "declare") == 0)
22078 {
22079 c_parser_consume_token (parser);
22080 if (c_parser_next_token_is (parser, CPP_NAME)
22081 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
22082 "target") == 0)
22083 c_parser_consume_token (parser);
22084 else
22085 {
22086 c_parser_error (parser, "expected %<target%>");
22087 c_parser_skip_to_pragma_eol (parser);
22088 return;
22089 }
22090 }
22091 else
22092 {
22093 c_parser_error (parser, "expected %<declare%>");
22094 c_parser_skip_to_pragma_eol (parser);
22095 return;
22096 }
22097 c_parser_skip_to_pragma_eol (parser);
22098 if (!current_omp_declare_target_attribute)
22099 error_at (loc, "%<#pragma omp end declare target%> without corresponding "
22100 "%<#pragma omp declare target%>");
22101 else
22102 current_omp_declare_target_attribute--;
22103 }
22104
22105
22106 /* OpenMP 4.0
22107 #pragma omp declare reduction (reduction-id : typename-list : expression) \
22108 initializer-clause[opt] new-line
22109
22110 initializer-clause:
22111 initializer (omp_priv = initializer)
22112 initializer (function-name (argument-list)) */
22113
22114 static void
22115 c_parser_omp_declare_reduction (c_parser *parser, enum pragma_context context)
22116 {
22117 unsigned int tokens_avail = 0, i;
22118 vec<tree> types = vNULL;
22119 vec<c_token> clauses = vNULL;
22120 enum tree_code reduc_code = ERROR_MARK;
22121 tree reduc_id = NULL_TREE;
22122 tree type;
22123 location_t rloc = c_parser_peek_token (parser)->location;
22124
22125 if (context == pragma_struct || context == pragma_param)
22126 {
22127 error ("%<#pragma omp declare reduction%> not at file or block scope");
22128 goto fail;
22129 }
22130
22131 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
22132 goto fail;
22133
22134 switch (c_parser_peek_token (parser)->type)
22135 {
22136 case CPP_PLUS:
22137 reduc_code = PLUS_EXPR;
22138 break;
22139 case CPP_MULT:
22140 reduc_code = MULT_EXPR;
22141 break;
22142 case CPP_MINUS:
22143 reduc_code = MINUS_EXPR;
22144 break;
22145 case CPP_AND:
22146 reduc_code = BIT_AND_EXPR;
22147 break;
22148 case CPP_XOR:
22149 reduc_code = BIT_XOR_EXPR;
22150 break;
22151 case CPP_OR:
22152 reduc_code = BIT_IOR_EXPR;
22153 break;
22154 case CPP_AND_AND:
22155 reduc_code = TRUTH_ANDIF_EXPR;
22156 break;
22157 case CPP_OR_OR:
22158 reduc_code = TRUTH_ORIF_EXPR;
22159 break;
22160 case CPP_NAME:
22161 const char *p;
22162 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22163 if (strcmp (p, "min") == 0)
22164 {
22165 reduc_code = MIN_EXPR;
22166 break;
22167 }
22168 if (strcmp (p, "max") == 0)
22169 {
22170 reduc_code = MAX_EXPR;
22171 break;
22172 }
22173 reduc_id = c_parser_peek_token (parser)->value;
22174 break;
22175 default:
22176 c_parser_error (parser,
22177 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
22178 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
22179 goto fail;
22180 }
22181
22182 tree orig_reduc_id, reduc_decl;
22183 orig_reduc_id = reduc_id;
22184 reduc_id = c_omp_reduction_id (reduc_code, reduc_id);
22185 reduc_decl = c_omp_reduction_decl (reduc_id);
22186 c_parser_consume_token (parser);
22187
22188 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
22189 goto fail;
22190
22191 while (true)
22192 {
22193 location_t loc = c_parser_peek_token (parser)->location;
22194 struct c_type_name *ctype = c_parser_type_name (parser);
22195 if (ctype != NULL)
22196 {
22197 type = groktypename (ctype, NULL, NULL);
22198 if (type == error_mark_node)
22199 ;
22200 else if ((INTEGRAL_TYPE_P (type)
22201 || TREE_CODE (type) == REAL_TYPE
22202 || TREE_CODE (type) == COMPLEX_TYPE)
22203 && orig_reduc_id == NULL_TREE)
22204 error_at (loc, "predeclared arithmetic type in "
22205 "%<#pragma omp declare reduction%>");
22206 else if (TREE_CODE (type) == FUNCTION_TYPE
22207 || TREE_CODE (type) == ARRAY_TYPE)
22208 error_at (loc, "function or array type in "
22209 "%<#pragma omp declare reduction%>");
22210 else if (TYPE_ATOMIC (type))
22211 error_at (loc, "%<_Atomic%> qualified type in "
22212 "%<#pragma omp declare reduction%>");
22213 else if (TYPE_QUALS_NO_ADDR_SPACE (type))
22214 error_at (loc, "const, volatile or restrict qualified type in "
22215 "%<#pragma omp declare reduction%>");
22216 else
22217 {
22218 tree t;
22219 for (t = DECL_INITIAL (reduc_decl); t; t = TREE_CHAIN (t))
22220 if (comptypes (TREE_PURPOSE (t), type))
22221 {
22222 error_at (loc, "redeclaration of %qs "
22223 "%<#pragma omp declare reduction%> for "
22224 "type %qT",
22225 IDENTIFIER_POINTER (reduc_id)
22226 + sizeof ("omp declare reduction ") - 1,
22227 type);
22228 location_t ploc
22229 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t),
22230 0));
22231 error_at (ploc, "previous %<#pragma omp declare "
22232 "reduction%>");
22233 break;
22234 }
22235 if (t == NULL_TREE)
22236 types.safe_push (type);
22237 }
22238 if (c_parser_next_token_is (parser, CPP_COMMA))
22239 c_parser_consume_token (parser);
22240 else
22241 break;
22242 }
22243 else
22244 break;
22245 }
22246
22247 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")
22248 || types.is_empty ())
22249 {
22250 fail:
22251 clauses.release ();
22252 types.release ();
22253 while (true)
22254 {
22255 c_token *token = c_parser_peek_token (parser);
22256 if (token->type == CPP_EOF || token->type == CPP_PRAGMA_EOL)
22257 break;
22258 c_parser_consume_token (parser);
22259 }
22260 c_parser_skip_to_pragma_eol (parser);
22261 return;
22262 }
22263
22264 if (types.length () > 1)
22265 {
22266 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
22267 {
22268 c_token *token = c_parser_peek_token (parser);
22269 if (token->type == CPP_EOF)
22270 goto fail;
22271 clauses.safe_push (*token);
22272 c_parser_consume_token (parser);
22273 }
22274 clauses.safe_push (*c_parser_peek_token (parser));
22275 c_parser_skip_to_pragma_eol (parser);
22276
22277 /* Make sure nothing tries to read past the end of the tokens. */
22278 c_token eof_token;
22279 memset (&eof_token, 0, sizeof (eof_token));
22280 eof_token.type = CPP_EOF;
22281 clauses.safe_push (eof_token);
22282 clauses.safe_push (eof_token);
22283 }
22284
22285 int errs = errorcount;
22286 FOR_EACH_VEC_ELT (types, i, type)
22287 {
22288 tokens_avail = parser->tokens_avail;
22289 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
22290 if (!clauses.is_empty ())
22291 {
22292 parser->tokens = clauses.address ();
22293 parser->tokens_avail = clauses.length ();
22294 parser->in_pragma = true;
22295 }
22296
22297 bool nested = current_function_decl != NULL_TREE;
22298 if (nested)
22299 c_push_function_context ();
22300 tree fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
22301 reduc_id, default_function_type);
22302 current_function_decl = fndecl;
22303 allocate_struct_function (fndecl, true);
22304 push_scope ();
22305 tree stmt = push_stmt_list ();
22306 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
22307 warn about these. */
22308 tree omp_out = build_decl (BUILTINS_LOCATION, VAR_DECL,
22309 get_identifier ("omp_out"), type);
22310 DECL_ARTIFICIAL (omp_out) = 1;
22311 DECL_CONTEXT (omp_out) = fndecl;
22312 pushdecl (omp_out);
22313 tree omp_in = build_decl (BUILTINS_LOCATION, VAR_DECL,
22314 get_identifier ("omp_in"), type);
22315 DECL_ARTIFICIAL (omp_in) = 1;
22316 DECL_CONTEXT (omp_in) = fndecl;
22317 pushdecl (omp_in);
22318 struct c_expr combiner = c_parser_expression (parser);
22319 struct c_expr initializer;
22320 tree omp_priv = NULL_TREE, omp_orig = NULL_TREE;
22321 bool bad = false;
22322 initializer.set_error ();
22323 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
22324 bad = true;
22325 else if (c_parser_next_token_is (parser, CPP_NAME)
22326 && strcmp (IDENTIFIER_POINTER
22327 (c_parser_peek_token (parser)->value),
22328 "initializer") == 0)
22329 {
22330 c_parser_consume_token (parser);
22331 pop_scope ();
22332 push_scope ();
22333 omp_priv = build_decl (BUILTINS_LOCATION, VAR_DECL,
22334 get_identifier ("omp_priv"), type);
22335 DECL_ARTIFICIAL (omp_priv) = 1;
22336 DECL_INITIAL (omp_priv) = error_mark_node;
22337 DECL_CONTEXT (omp_priv) = fndecl;
22338 pushdecl (omp_priv);
22339 omp_orig = build_decl (BUILTINS_LOCATION, VAR_DECL,
22340 get_identifier ("omp_orig"), type);
22341 DECL_ARTIFICIAL (omp_orig) = 1;
22342 DECL_CONTEXT (omp_orig) = fndecl;
22343 pushdecl (omp_orig);
22344 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
22345 bad = true;
22346 else if (!c_parser_next_token_is (parser, CPP_NAME))
22347 {
22348 c_parser_error (parser, "expected %<omp_priv%> or "
22349 "function-name");
22350 bad = true;
22351 }
22352 else if (strcmp (IDENTIFIER_POINTER
22353 (c_parser_peek_token (parser)->value),
22354 "omp_priv") != 0)
22355 {
22356 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
22357 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
22358 {
22359 c_parser_error (parser, "expected function-name %<(%>");
22360 bad = true;
22361 }
22362 else
22363 initializer = c_parser_postfix_expression (parser);
22364 if (initializer.value
22365 && TREE_CODE (initializer.value) == CALL_EXPR)
22366 {
22367 int j;
22368 tree c = initializer.value;
22369 for (j = 0; j < call_expr_nargs (c); j++)
22370 {
22371 tree a = CALL_EXPR_ARG (c, j);
22372 STRIP_NOPS (a);
22373 if (TREE_CODE (a) == ADDR_EXPR
22374 && TREE_OPERAND (a, 0) == omp_priv)
22375 break;
22376 }
22377 if (j == call_expr_nargs (c))
22378 error ("one of the initializer call arguments should be "
22379 "%<&omp_priv%>");
22380 }
22381 }
22382 else
22383 {
22384 c_parser_consume_token (parser);
22385 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
22386 bad = true;
22387 else
22388 {
22389 tree st = push_stmt_list ();
22390 location_t loc = c_parser_peek_token (parser)->location;
22391 rich_location richloc (line_table, loc);
22392 start_init (omp_priv, NULL_TREE, 0, &richloc);
22393 struct c_expr init = c_parser_initializer (parser);
22394 finish_init ();
22395 finish_decl (omp_priv, loc, init.value,
22396 init.original_type, NULL_TREE);
22397 pop_stmt_list (st);
22398 }
22399 }
22400 if (!bad
22401 && !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
22402 bad = true;
22403 }
22404
22405 if (!bad)
22406 {
22407 c_parser_skip_to_pragma_eol (parser);
22408
22409 tree t = tree_cons (type, make_tree_vec (omp_priv ? 6 : 3),
22410 DECL_INITIAL (reduc_decl));
22411 DECL_INITIAL (reduc_decl) = t;
22412 DECL_SOURCE_LOCATION (omp_out) = rloc;
22413 TREE_VEC_ELT (TREE_VALUE (t), 0) = omp_out;
22414 TREE_VEC_ELT (TREE_VALUE (t), 1) = omp_in;
22415 TREE_VEC_ELT (TREE_VALUE (t), 2) = combiner.value;
22416 walk_tree (&combiner.value, c_check_omp_declare_reduction_r,
22417 &TREE_VEC_ELT (TREE_VALUE (t), 0), NULL);
22418 if (omp_priv)
22419 {
22420 DECL_SOURCE_LOCATION (omp_priv) = rloc;
22421 TREE_VEC_ELT (TREE_VALUE (t), 3) = omp_priv;
22422 TREE_VEC_ELT (TREE_VALUE (t), 4) = omp_orig;
22423 TREE_VEC_ELT (TREE_VALUE (t), 5) = initializer.value;
22424 walk_tree (&initializer.value, c_check_omp_declare_reduction_r,
22425 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
22426 walk_tree (&DECL_INITIAL (omp_priv),
22427 c_check_omp_declare_reduction_r,
22428 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
22429 }
22430 }
22431
22432 pop_stmt_list (stmt);
22433 pop_scope ();
22434 if (cfun->language != NULL)
22435 {
22436 ggc_free (cfun->language);
22437 cfun->language = NULL;
22438 }
22439 set_cfun (NULL);
22440 current_function_decl = NULL_TREE;
22441 if (nested)
22442 c_pop_function_context ();
22443
22444 if (!clauses.is_empty ())
22445 {
22446 parser->tokens = &parser->tokens_buf[0];
22447 parser->tokens_avail = tokens_avail;
22448 }
22449 if (bad)
22450 goto fail;
22451 if (errs != errorcount)
22452 break;
22453 }
22454
22455 clauses.release ();
22456 types.release ();
22457 }
22458
22459
22460 /* OpenMP 4.0
22461 #pragma omp declare simd declare-simd-clauses[optseq] new-line
22462 #pragma omp declare reduction (reduction-id : typename-list : expression) \
22463 initializer-clause[opt] new-line
22464 #pragma omp declare target new-line
22465
22466 OpenMP 5.0
22467 #pragma omp declare variant (identifier) match (context-selector) */
22468
22469 static bool
22470 c_parser_omp_declare (c_parser *parser, enum pragma_context context)
22471 {
22472 c_parser_consume_pragma (parser);
22473 if (c_parser_next_token_is (parser, CPP_NAME))
22474 {
22475 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22476 if (strcmp (p, "simd") == 0)
22477 {
22478 /* c_parser_consume_token (parser); done in
22479 c_parser_omp_declare_simd. */
22480 c_parser_omp_declare_simd (parser, context);
22481 return true;
22482 }
22483 if (strcmp (p, "reduction") == 0)
22484 {
22485 c_parser_consume_token (parser);
22486 c_parser_omp_declare_reduction (parser, context);
22487 return false;
22488 }
22489 if (!flag_openmp) /* flag_openmp_simd */
22490 {
22491 c_parser_skip_to_pragma_eol (parser, false);
22492 return false;
22493 }
22494 if (strcmp (p, "target") == 0)
22495 {
22496 c_parser_consume_token (parser);
22497 c_parser_omp_declare_target (parser);
22498 return false;
22499 }
22500 if (strcmp (p, "variant") == 0)
22501 {
22502 /* c_parser_consume_token (parser); done in
22503 c_parser_omp_declare_simd. */
22504 c_parser_omp_declare_simd (parser, context);
22505 return true;
22506 }
22507 }
22508
22509 c_parser_error (parser, "expected %<simd%>, %<reduction%>, "
22510 "%<target%> or %<variant%>");
22511 c_parser_skip_to_pragma_eol (parser);
22512 return false;
22513 }
22514
22515 /* OpenMP 5.0
22516 #pragma omp requires clauses[optseq] new-line */
22517
22518 static void
22519 c_parser_omp_requires (c_parser *parser)
22520 {
22521 bool first = true;
22522 enum omp_requires new_req = (enum omp_requires) 0;
22523
22524 c_parser_consume_pragma (parser);
22525
22526 location_t loc = c_parser_peek_token (parser)->location;
22527 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
22528 {
22529 if (!first
22530 && c_parser_next_token_is (parser, CPP_COMMA)
22531 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
22532 c_parser_consume_token (parser);
22533
22534 first = false;
22535
22536 if (c_parser_next_token_is (parser, CPP_NAME))
22537 {
22538 const char *p
22539 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22540 location_t cloc = c_parser_peek_token (parser)->location;
22541 enum omp_requires this_req = (enum omp_requires) 0;
22542
22543 if (!strcmp (p, "unified_address"))
22544 this_req = OMP_REQUIRES_UNIFIED_ADDRESS;
22545 else if (!strcmp (p, "unified_shared_memory"))
22546 this_req = OMP_REQUIRES_UNIFIED_SHARED_MEMORY;
22547 else if (!strcmp (p, "dynamic_allocators"))
22548 this_req = OMP_REQUIRES_DYNAMIC_ALLOCATORS;
22549 else if (!strcmp (p, "reverse_offload"))
22550 this_req = OMP_REQUIRES_REVERSE_OFFLOAD;
22551 else if (!strcmp (p, "atomic_default_mem_order"))
22552 {
22553 c_parser_consume_token (parser);
22554
22555 matching_parens parens;
22556 if (parens.require_open (parser))
22557 {
22558 if (c_parser_next_token_is (parser, CPP_NAME))
22559 {
22560 tree v = c_parser_peek_token (parser)->value;
22561 p = IDENTIFIER_POINTER (v);
22562
22563 if (!strcmp (p, "seq_cst"))
22564 this_req
22565 = (enum omp_requires) OMP_MEMORY_ORDER_SEQ_CST;
22566 else if (!strcmp (p, "relaxed"))
22567 this_req
22568 = (enum omp_requires) OMP_MEMORY_ORDER_RELAXED;
22569 else if (!strcmp (p, "acq_rel"))
22570 this_req
22571 = (enum omp_requires) OMP_MEMORY_ORDER_ACQ_REL;
22572 }
22573 if (this_req == 0)
22574 {
22575 error_at (c_parser_peek_token (parser)->location,
22576 "expected %<seq_cst%>, %<relaxed%> or "
22577 "%<acq_rel%>");
22578 switch (c_parser_peek_token (parser)->type)
22579 {
22580 case CPP_EOF:
22581 case CPP_PRAGMA_EOL:
22582 case CPP_CLOSE_PAREN:
22583 break;
22584 default:
22585 if (c_parser_peek_2nd_token (parser)->type
22586 == CPP_CLOSE_PAREN)
22587 c_parser_consume_token (parser);
22588 break;
22589 }
22590 }
22591 else
22592 c_parser_consume_token (parser);
22593
22594 parens.skip_until_found_close (parser);
22595 if (this_req == 0)
22596 {
22597 c_parser_skip_to_pragma_eol (parser, false);
22598 return;
22599 }
22600 }
22601 p = NULL;
22602 }
22603 else
22604 {
22605 error_at (cloc, "expected %<unified_address%>, "
22606 "%<unified_shared_memory%>, "
22607 "%<dynamic_allocators%>, "
22608 "%<reverse_offload%> "
22609 "or %<atomic_default_mem_order%> clause");
22610 c_parser_skip_to_pragma_eol (parser, false);
22611 return;
22612 }
22613 if (p && this_req != OMP_REQUIRES_DYNAMIC_ALLOCATORS)
22614 sorry_at (cloc, "%qs clause on %<requires%> directive not "
22615 "supported yet", p);
22616 if (p)
22617 c_parser_consume_token (parser);
22618 if (this_req)
22619 {
22620 if ((this_req & ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
22621 {
22622 if ((this_req & new_req) != 0)
22623 error_at (cloc, "too many %qs clauses", p);
22624 if (this_req != OMP_REQUIRES_DYNAMIC_ALLOCATORS
22625 && (omp_requires_mask & OMP_REQUIRES_TARGET_USED) != 0)
22626 error_at (cloc, "%qs clause used lexically after first "
22627 "target construct or offloading API", p);
22628 }
22629 else if ((new_req & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
22630 {
22631 error_at (cloc, "too many %qs clauses",
22632 "atomic_default_mem_order");
22633 this_req = (enum omp_requires) 0;
22634 }
22635 else if ((omp_requires_mask
22636 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
22637 {
22638 error_at (cloc, "more than one %<atomic_default_mem_order%>"
22639 " clause in a single compilation unit");
22640 this_req
22641 = (enum omp_requires)
22642 (omp_requires_mask
22643 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER);
22644 }
22645 else if ((omp_requires_mask
22646 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED) != 0)
22647 error_at (cloc, "%<atomic_default_mem_order%> clause used "
22648 "lexically after first %<atomic%> construct "
22649 "without memory order clause");
22650 new_req = (enum omp_requires) (new_req | this_req);
22651 omp_requires_mask
22652 = (enum omp_requires) (omp_requires_mask | this_req);
22653 continue;
22654 }
22655 }
22656 break;
22657 }
22658 c_parser_skip_to_pragma_eol (parser);
22659
22660 if (new_req == 0)
22661 error_at (loc, "%<pragma omp requires%> requires at least one clause");
22662 }
22663
22664 /* Helper function for c_parser_omp_taskloop.
22665 Disallow zero sized or potentially zero sized task reductions. */
22666
22667 static tree
22668 c_finish_taskloop_clauses (tree clauses)
22669 {
22670 tree *pc = &clauses;
22671 for (tree c = clauses; c; c = *pc)
22672 {
22673 bool remove = false;
22674 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
22675 {
22676 tree type = strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c)));
22677 if (integer_zerop (TYPE_SIZE_UNIT (type)))
22678 {
22679 error_at (OMP_CLAUSE_LOCATION (c),
22680 "zero sized type %qT in %<reduction%> clause", type);
22681 remove = true;
22682 }
22683 else if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
22684 {
22685 error_at (OMP_CLAUSE_LOCATION (c),
22686 "variable sized type %qT in %<reduction%> clause",
22687 type);
22688 remove = true;
22689 }
22690 }
22691 if (remove)
22692 *pc = OMP_CLAUSE_CHAIN (c);
22693 else
22694 pc = &OMP_CLAUSE_CHAIN (c);
22695 }
22696 return clauses;
22697 }
22698
22699 /* OpenMP 4.5:
22700 #pragma omp taskloop taskloop-clause[optseq] new-line
22701 for-loop
22702
22703 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
22704 for-loop */
22705
22706 #define OMP_TASKLOOP_CLAUSE_MASK \
22707 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
22708 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
22709 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
22710 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
22711 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
22712 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
22713 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
22714 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
22715 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
22716 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
22717 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
22718 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
22719 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
22720 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
22721 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
22722 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
22723 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
22724
22725 static tree
22726 c_parser_omp_taskloop (location_t loc, c_parser *parser,
22727 char *p_name, omp_clause_mask mask, tree *cclauses,
22728 bool *if_p)
22729 {
22730 tree clauses, block, ret;
22731
22732 strcat (p_name, " taskloop");
22733 mask |= OMP_TASKLOOP_CLAUSE_MASK;
22734 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
22735 clause. */
22736 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
22737 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION);
22738
22739 if (c_parser_next_token_is (parser, CPP_NAME))
22740 {
22741 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22742
22743 if (strcmp (p, "simd") == 0)
22744 {
22745 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
22746 if (cclauses == NULL)
22747 cclauses = cclauses_buf;
22748 c_parser_consume_token (parser);
22749 if (!flag_openmp) /* flag_openmp_simd */
22750 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
22751 if_p);
22752 block = c_begin_compound_stmt (true);
22753 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
22754 block = c_end_compound_stmt (loc, block, true);
22755 if (ret == NULL)
22756 return ret;
22757 ret = make_node (OMP_TASKLOOP);
22758 TREE_TYPE (ret) = void_type_node;
22759 OMP_FOR_BODY (ret) = block;
22760 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
22761 OMP_FOR_CLAUSES (ret)
22762 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret));
22763 SET_EXPR_LOCATION (ret, loc);
22764 add_stmt (ret);
22765 return ret;
22766 }
22767 }
22768 if (!flag_openmp) /* flag_openmp_simd */
22769 {
22770 c_parser_skip_to_pragma_eol (parser, false);
22771 return NULL_TREE;
22772 }
22773
22774 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
22775 if (cclauses)
22776 {
22777 omp_split_clauses (loc, OMP_TASKLOOP, mask, clauses, cclauses);
22778 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
22779 }
22780
22781 clauses = c_finish_taskloop_clauses (clauses);
22782 block = c_begin_compound_stmt (true);
22783 ret = c_parser_omp_for_loop (loc, parser, OMP_TASKLOOP, clauses, NULL, if_p);
22784 block = c_end_compound_stmt (loc, block, true);
22785 add_stmt (block);
22786
22787 return ret;
22788 }
22789
22790 /* OpenMP 5.1
22791 #pragma omp nothing new-line */
22792
22793 static void
22794 c_parser_omp_nothing (c_parser *parser)
22795 {
22796 c_parser_consume_pragma (parser);
22797 c_parser_skip_to_pragma_eol (parser);
22798 }
22799
22800 /* OpenMP 5.1
22801 #pragma omp error clauses[optseq] new-line */
22802
22803 static bool
22804 c_parser_omp_error (c_parser *parser, enum pragma_context context)
22805 {
22806 int at_compilation = -1;
22807 int severity_fatal = -1;
22808 tree message = NULL_TREE;
22809 bool first = true;
22810 bool bad = false;
22811 location_t loc = c_parser_peek_token (parser)->location;
22812
22813 c_parser_consume_pragma (parser);
22814
22815 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
22816 {
22817 if (!first
22818 && c_parser_next_token_is (parser, CPP_COMMA)
22819 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
22820 c_parser_consume_token (parser);
22821
22822 first = false;
22823
22824 if (!c_parser_next_token_is (parser, CPP_NAME))
22825 break;
22826
22827 const char *p
22828 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
22829 location_t cloc = c_parser_peek_token (parser)->location;
22830 static const char *args[] = {
22831 "execution", "compilation", "warning", "fatal"
22832 };
22833 int *v = NULL;
22834 int idx = 0, n = -1;
22835 tree m = NULL_TREE;
22836
22837 if (!strcmp (p, "at"))
22838 v = &at_compilation;
22839 else if (!strcmp (p, "severity"))
22840 {
22841 v = &severity_fatal;
22842 idx += 2;
22843 }
22844 else if (strcmp (p, "message"))
22845 {
22846 error_at (cloc,
22847 "expected %<at%>, %<severity%> or %<message%> clause");
22848 c_parser_skip_to_pragma_eol (parser, false);
22849 return false;
22850 }
22851
22852 c_parser_consume_token (parser);
22853
22854 matching_parens parens;
22855 if (parens.require_open (parser))
22856 {
22857 if (v == NULL)
22858 {
22859 location_t expr_loc = c_parser_peek_token (parser)->location;
22860 c_expr expr = c_parser_expr_no_commas (parser, NULL);
22861 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
22862 m = convert (const_string_type_node, expr.value);
22863 m = c_fully_fold (m, false, NULL);
22864 }
22865 else
22866 {
22867 if (c_parser_next_token_is (parser, CPP_NAME))
22868 {
22869 tree val = c_parser_peek_token (parser)->value;
22870 const char *q = IDENTIFIER_POINTER (val);
22871
22872 if (!strcmp (q, args[idx]))
22873 n = 0;
22874 else if (!strcmp (q, args[idx + 1]))
22875 n = 1;
22876 }
22877 if (n == -1)
22878 {
22879 error_at (c_parser_peek_token (parser)->location,
22880 "expected %qs or %qs", args[idx], args[idx + 1]);
22881 bad = true;
22882 switch (c_parser_peek_token (parser)->type)
22883 {
22884 case CPP_EOF:
22885 case CPP_PRAGMA_EOL:
22886 case CPP_CLOSE_PAREN:
22887 break;
22888 default:
22889 if (c_parser_peek_2nd_token (parser)->type
22890 == CPP_CLOSE_PAREN)
22891 c_parser_consume_token (parser);
22892 break;
22893 }
22894 }
22895 else
22896 c_parser_consume_token (parser);
22897 }
22898
22899 parens.skip_until_found_close (parser);
22900
22901 if (v == NULL)
22902 {
22903 if (message)
22904 {
22905 error_at (cloc, "too many %qs clauses", p);
22906 bad = true;
22907 }
22908 else
22909 message = m;
22910 }
22911 else if (n != -1)
22912 {
22913 if (*v != -1)
22914 {
22915 error_at (cloc, "too many %qs clauses", p);
22916 bad = true;
22917 }
22918 else
22919 *v = n;
22920 }
22921 }
22922 else
22923 bad = true;
22924 }
22925 c_parser_skip_to_pragma_eol (parser);
22926 if (bad)
22927 return true;
22928
22929 if (at_compilation == -1)
22930 at_compilation = 1;
22931 if (severity_fatal == -1)
22932 severity_fatal = 1;
22933 if (!at_compilation)
22934 {
22935 if (context != pragma_compound)
22936 {
22937 error_at (loc, "%<#pragma omp error%> with %<at(execution)%> clause "
22938 "may only be used in compound statements");
22939 return true;
22940 }
22941 tree fndecl
22942 = builtin_decl_explicit (severity_fatal ? BUILT_IN_GOMP_ERROR
22943 : BUILT_IN_GOMP_WARNING);
22944 if (!message)
22945 message = build_zero_cst (const_string_type_node);
22946 tree stmt = build_call_expr_loc (loc, fndecl, 2, message,
22947 build_all_ones_cst (size_type_node));
22948 add_stmt (stmt);
22949 return true;
22950 }
22951 const char *msg = NULL;
22952 if (message)
22953 {
22954 msg = c_getstr (message);
22955 if (msg == NULL)
22956 msg = _("<message unknown at compile time>");
22957 }
22958 if (msg)
22959 emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
22960 "%<pragma omp error%> encountered: %s", msg);
22961 else
22962 emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
22963 "%<pragma omp error%> encountered");
22964 return false;
22965 }
22966
22967 /* Main entry point to parsing most OpenMP pragmas. */
22968
22969 static void
22970 c_parser_omp_construct (c_parser *parser, bool *if_p)
22971 {
22972 enum pragma_kind p_kind;
22973 location_t loc;
22974 tree stmt;
22975 char p_name[sizeof "#pragma omp teams distribute parallel for simd"];
22976 omp_clause_mask mask (0);
22977
22978 loc = c_parser_peek_token (parser)->location;
22979 p_kind = c_parser_peek_token (parser)->pragma_kind;
22980 c_parser_consume_pragma (parser);
22981
22982 switch (p_kind)
22983 {
22984 case PRAGMA_OACC_ATOMIC:
22985 c_parser_omp_atomic (loc, parser, true);
22986 return;
22987 case PRAGMA_OACC_CACHE:
22988 strcpy (p_name, "#pragma acc");
22989 stmt = c_parser_oacc_cache (loc, parser);
22990 break;
22991 case PRAGMA_OACC_DATA:
22992 stmt = c_parser_oacc_data (loc, parser, if_p);
22993 break;
22994 case PRAGMA_OACC_HOST_DATA:
22995 stmt = c_parser_oacc_host_data (loc, parser, if_p);
22996 break;
22997 case PRAGMA_OACC_KERNELS:
22998 case PRAGMA_OACC_PARALLEL:
22999 case PRAGMA_OACC_SERIAL:
23000 strcpy (p_name, "#pragma acc");
23001 stmt = c_parser_oacc_compute (loc, parser, p_kind, p_name, if_p);
23002 break;
23003 case PRAGMA_OACC_LOOP:
23004 strcpy (p_name, "#pragma acc");
23005 stmt = c_parser_oacc_loop (loc, parser, p_name, mask, NULL, if_p);
23006 break;
23007 case PRAGMA_OACC_WAIT:
23008 strcpy (p_name, "#pragma wait");
23009 stmt = c_parser_oacc_wait (loc, parser, p_name);
23010 break;
23011 case PRAGMA_OMP_ALLOCATE:
23012 c_parser_omp_allocate (loc, parser);
23013 return;
23014 case PRAGMA_OMP_ATOMIC:
23015 c_parser_omp_atomic (loc, parser, false);
23016 return;
23017 case PRAGMA_OMP_CRITICAL:
23018 stmt = c_parser_omp_critical (loc, parser, if_p);
23019 break;
23020 case PRAGMA_OMP_DISTRIBUTE:
23021 strcpy (p_name, "#pragma omp");
23022 stmt = c_parser_omp_distribute (loc, parser, p_name, mask, NULL, if_p);
23023 break;
23024 case PRAGMA_OMP_FOR:
23025 strcpy (p_name, "#pragma omp");
23026 stmt = c_parser_omp_for (loc, parser, p_name, mask, NULL, if_p);
23027 break;
23028 case PRAGMA_OMP_LOOP:
23029 strcpy (p_name, "#pragma omp");
23030 stmt = c_parser_omp_loop (loc, parser, p_name, mask, NULL, if_p);
23031 break;
23032 case PRAGMA_OMP_MASKED:
23033 strcpy (p_name, "#pragma omp");
23034 stmt = c_parser_omp_masked (loc, parser, p_name, mask, NULL, if_p);
23035 break;
23036 case PRAGMA_OMP_MASTER:
23037 strcpy (p_name, "#pragma omp");
23038 stmt = c_parser_omp_master (loc, parser, p_name, mask, NULL, if_p);
23039 break;
23040 case PRAGMA_OMP_PARALLEL:
23041 strcpy (p_name, "#pragma omp");
23042 stmt = c_parser_omp_parallel (loc, parser, p_name, mask, NULL, if_p);
23043 break;
23044 case PRAGMA_OMP_SCOPE:
23045 stmt = c_parser_omp_scope (loc, parser, if_p);
23046 break;
23047 case PRAGMA_OMP_SECTIONS:
23048 strcpy (p_name, "#pragma omp");
23049 stmt = c_parser_omp_sections (loc, parser, p_name, mask, NULL);
23050 break;
23051 case PRAGMA_OMP_SIMD:
23052 strcpy (p_name, "#pragma omp");
23053 stmt = c_parser_omp_simd (loc, parser, p_name, mask, NULL, if_p);
23054 break;
23055 case PRAGMA_OMP_SINGLE:
23056 stmt = c_parser_omp_single (loc, parser, if_p);
23057 break;
23058 case PRAGMA_OMP_TASK:
23059 stmt = c_parser_omp_task (loc, parser, if_p);
23060 break;
23061 case PRAGMA_OMP_TASKGROUP:
23062 stmt = c_parser_omp_taskgroup (loc, parser, if_p);
23063 break;
23064 case PRAGMA_OMP_TASKLOOP:
23065 strcpy (p_name, "#pragma omp");
23066 stmt = c_parser_omp_taskloop (loc, parser, p_name, mask, NULL, if_p);
23067 break;
23068 case PRAGMA_OMP_TEAMS:
23069 strcpy (p_name, "#pragma omp");
23070 stmt = c_parser_omp_teams (loc, parser, p_name, mask, NULL, if_p);
23071 break;
23072 default:
23073 gcc_unreachable ();
23074 }
23075
23076 if (stmt && stmt != error_mark_node)
23077 gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION);
23078 }
23079
23080
23081 /* OpenMP 2.5:
23082 # pragma omp threadprivate (variable-list) */
23083
23084 static void
23085 c_parser_omp_threadprivate (c_parser *parser)
23086 {
23087 tree vars, t;
23088 location_t loc;
23089
23090 c_parser_consume_pragma (parser);
23091 loc = c_parser_peek_token (parser)->location;
23092 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
23093
23094 /* Mark every variable in VARS to be assigned thread local storage. */
23095 for (t = vars; t; t = TREE_CHAIN (t))
23096 {
23097 tree v = TREE_PURPOSE (t);
23098
23099 /* FIXME diagnostics: Ideally we should keep individual
23100 locations for all the variables in the var list to make the
23101 following errors more precise. Perhaps
23102 c_parser_omp_var_list_parens() should construct a list of
23103 locations to go along with the var list. */
23104
23105 /* If V had already been marked threadprivate, it doesn't matter
23106 whether it had been used prior to this point. */
23107 if (!VAR_P (v))
23108 error_at (loc, "%qD is not a variable", v);
23109 else if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v))
23110 error_at (loc, "%qE declared %<threadprivate%> after first use", v);
23111 else if (! is_global_var (v))
23112 error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v);
23113 else if (TREE_TYPE (v) == error_mark_node)
23114 ;
23115 else if (! COMPLETE_TYPE_P (TREE_TYPE (v)))
23116 error_at (loc, "%<threadprivate%> %qE has incomplete type", v);
23117 else
23118 {
23119 if (! DECL_THREAD_LOCAL_P (v))
23120 {
23121 set_decl_tls_model (v, decl_default_tls_model (v));
23122 /* If rtl has been already set for this var, call
23123 make_decl_rtl once again, so that encode_section_info
23124 has a chance to look at the new decl flags. */
23125 if (DECL_RTL_SET_P (v))
23126 make_decl_rtl (v);
23127 }
23128 C_DECL_THREADPRIVATE_P (v) = 1;
23129 }
23130 }
23131
23132 c_parser_skip_to_pragma_eol (parser);
23133 }
23134
23135 /* Parse a transaction attribute (GCC Extension).
23136
23137 transaction-attribute:
23138 gnu-attributes
23139 attribute-specifier
23140 */
23141
23142 static tree
23143 c_parser_transaction_attributes (c_parser *parser)
23144 {
23145 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
23146 return c_parser_gnu_attributes (parser);
23147
23148 if (!c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
23149 return NULL_TREE;
23150 return c_parser_std_attribute_specifier (parser, true);
23151 }
23152
23153 /* Parse a __transaction_atomic or __transaction_relaxed statement
23154 (GCC Extension).
23155
23156 transaction-statement:
23157 __transaction_atomic transaction-attribute[opt] compound-statement
23158 __transaction_relaxed compound-statement
23159
23160 Note that the only valid attribute is: "outer".
23161 */
23162
23163 static tree
23164 c_parser_transaction (c_parser *parser, enum rid keyword)
23165 {
23166 unsigned int old_in = parser->in_transaction;
23167 unsigned int this_in = 1, new_in;
23168 location_t loc = c_parser_peek_token (parser)->location;
23169 tree stmt, attrs;
23170
23171 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
23172 || keyword == RID_TRANSACTION_RELAXED)
23173 && c_parser_next_token_is_keyword (parser, keyword));
23174 c_parser_consume_token (parser);
23175
23176 if (keyword == RID_TRANSACTION_RELAXED)
23177 this_in |= TM_STMT_ATTR_RELAXED;
23178 else
23179 {
23180 attrs = c_parser_transaction_attributes (parser);
23181 if (attrs)
23182 this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
23183 }
23184
23185 /* Keep track if we're in the lexical scope of an outer transaction. */
23186 new_in = this_in | (old_in & TM_STMT_ATTR_OUTER);
23187
23188 parser->in_transaction = new_in;
23189 stmt = c_parser_compound_statement (parser);
23190 parser->in_transaction = old_in;
23191
23192 if (flag_tm)
23193 stmt = c_finish_transaction (loc, stmt, this_in);
23194 else
23195 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
23196 "%<__transaction_atomic%> without transactional memory support enabled"
23197 : "%<__transaction_relaxed %> "
23198 "without transactional memory support enabled"));
23199
23200 return stmt;
23201 }
23202
23203 /* Parse a __transaction_atomic or __transaction_relaxed expression
23204 (GCC Extension).
23205
23206 transaction-expression:
23207 __transaction_atomic ( expression )
23208 __transaction_relaxed ( expression )
23209 */
23210
23211 static struct c_expr
23212 c_parser_transaction_expression (c_parser *parser, enum rid keyword)
23213 {
23214 struct c_expr ret;
23215 unsigned int old_in = parser->in_transaction;
23216 unsigned int this_in = 1;
23217 location_t loc = c_parser_peek_token (parser)->location;
23218 tree attrs;
23219
23220 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
23221 || keyword == RID_TRANSACTION_RELAXED)
23222 && c_parser_next_token_is_keyword (parser, keyword));
23223 c_parser_consume_token (parser);
23224
23225 if (keyword == RID_TRANSACTION_RELAXED)
23226 this_in |= TM_STMT_ATTR_RELAXED;
23227 else
23228 {
23229 attrs = c_parser_transaction_attributes (parser);
23230 if (attrs)
23231 this_in |= parse_tm_stmt_attr (attrs, 0);
23232 }
23233
23234 parser->in_transaction = this_in;
23235 matching_parens parens;
23236 if (parens.require_open (parser))
23237 {
23238 tree expr = c_parser_expression (parser).value;
23239 ret.original_type = TREE_TYPE (expr);
23240 ret.value = build1 (TRANSACTION_EXPR, ret.original_type, expr);
23241 if (this_in & TM_STMT_ATTR_RELAXED)
23242 TRANSACTION_EXPR_RELAXED (ret.value) = 1;
23243 SET_EXPR_LOCATION (ret.value, loc);
23244 ret.original_code = TRANSACTION_EXPR;
23245 if (!parens.require_close (parser))
23246 {
23247 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
23248 goto error;
23249 }
23250 }
23251 else
23252 {
23253 error:
23254 ret.set_error ();
23255 ret.original_code = ERROR_MARK;
23256 ret.original_type = NULL;
23257 }
23258 parser->in_transaction = old_in;
23259
23260 if (!flag_tm)
23261 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
23262 "%<__transaction_atomic%> without transactional memory support enabled"
23263 : "%<__transaction_relaxed %> "
23264 "without transactional memory support enabled"));
23265
23266 set_c_expr_source_range (&ret, loc, loc);
23267
23268 return ret;
23269 }
23270
23271 /* Parse a __transaction_cancel statement (GCC Extension).
23272
23273 transaction-cancel-statement:
23274 __transaction_cancel transaction-attribute[opt] ;
23275
23276 Note that the only valid attribute is "outer".
23277 */
23278
23279 static tree
23280 c_parser_transaction_cancel (c_parser *parser)
23281 {
23282 location_t loc = c_parser_peek_token (parser)->location;
23283 tree attrs;
23284 bool is_outer = false;
23285
23286 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TRANSACTION_CANCEL));
23287 c_parser_consume_token (parser);
23288
23289 attrs = c_parser_transaction_attributes (parser);
23290 if (attrs)
23291 is_outer = (parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER) != 0);
23292
23293 if (!flag_tm)
23294 {
23295 error_at (loc, "%<__transaction_cancel%> without "
23296 "transactional memory support enabled");
23297 goto ret_error;
23298 }
23299 else if (parser->in_transaction & TM_STMT_ATTR_RELAXED)
23300 {
23301 error_at (loc, "%<__transaction_cancel%> within a "
23302 "%<__transaction_relaxed%>");
23303 goto ret_error;
23304 }
23305 else if (is_outer)
23306 {
23307 if ((parser->in_transaction & TM_STMT_ATTR_OUTER) == 0
23308 && !is_tm_may_cancel_outer (current_function_decl))
23309 {
23310 error_at (loc, "outer %<__transaction_cancel%> not "
23311 "within outer %<__transaction_atomic%> or "
23312 "a %<transaction_may_cancel_outer%> function");
23313 goto ret_error;
23314 }
23315 }
23316 else if (parser->in_transaction == 0)
23317 {
23318 error_at (loc, "%<__transaction_cancel%> not within "
23319 "%<__transaction_atomic%>");
23320 goto ret_error;
23321 }
23322
23323 return add_stmt (build_tm_abort_call (loc, is_outer));
23324
23325 ret_error:
23326 return build1 (NOP_EXPR, void_type_node, error_mark_node);
23327 }
23328 \f
23329 /* Parse a single source file. */
23330
23331 void
23332 c_parse_file (void)
23333 {
23334 /* Use local storage to begin. If the first token is a pragma, parse it.
23335 If it is #pragma GCC pch_preprocess, then this will load a PCH file
23336 which will cause garbage collection. */
23337 c_parser tparser;
23338
23339 memset (&tparser, 0, sizeof tparser);
23340 tparser.translate_strings_p = true;
23341 tparser.tokens = &tparser.tokens_buf[0];
23342 the_parser = &tparser;
23343
23344 if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS)
23345 c_parser_pragma_pch_preprocess (&tparser);
23346 else
23347 c_common_no_more_pch ();
23348
23349 the_parser = ggc_alloc<c_parser> ();
23350 *the_parser = tparser;
23351 if (tparser.tokens == &tparser.tokens_buf[0])
23352 the_parser->tokens = &the_parser->tokens_buf[0];
23353
23354 /* Initialize EH, if we've been told to do so. */
23355 if (flag_exceptions)
23356 using_eh_for_cleanups ();
23357
23358 c_parser_translation_unit (the_parser);
23359 the_parser = NULL;
23360 }
23361
23362 /* Parse the body of a function declaration marked with "__RTL".
23363
23364 The RTL parser works on the level of characters read from a
23365 FILE *, whereas c_parser works at the level of tokens.
23366 Square this circle by consuming all of the tokens up to and
23367 including the closing brace, recording the start/end of the RTL
23368 fragment, and reopening the file and re-reading the relevant
23369 lines within the RTL parser.
23370
23371 This requires the opening and closing braces of the C function
23372 to be on separate lines from the RTL they wrap.
23373
23374 Take ownership of START_WITH_PASS, if non-NULL. */
23375
23376 location_t
23377 c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass)
23378 {
23379 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
23380 {
23381 free (start_with_pass);
23382 return c_parser_peek_token (parser)->location;
23383 }
23384
23385 location_t start_loc = c_parser_peek_token (parser)->location;
23386
23387 /* Consume all tokens, up to the closing brace, handling
23388 matching pairs of braces in the rtl dump. */
23389 int num_open_braces = 1;
23390 while (1)
23391 {
23392 switch (c_parser_peek_token (parser)->type)
23393 {
23394 case CPP_OPEN_BRACE:
23395 num_open_braces++;
23396 break;
23397 case CPP_CLOSE_BRACE:
23398 if (--num_open_braces == 0)
23399 goto found_closing_brace;
23400 break;
23401 case CPP_EOF:
23402 error_at (start_loc, "no closing brace");
23403 free (start_with_pass);
23404 return c_parser_peek_token (parser)->location;
23405 default:
23406 break;
23407 }
23408 c_parser_consume_token (parser);
23409 }
23410
23411 found_closing_brace:
23412 /* At the closing brace; record its location. */
23413 location_t end_loc = c_parser_peek_token (parser)->location;
23414
23415 /* Consume the closing brace. */
23416 c_parser_consume_token (parser);
23417
23418 /* Invoke the RTL parser. */
23419 if (!read_rtl_function_body_from_file_range (start_loc, end_loc))
23420 {
23421 free (start_with_pass);
23422 return end_loc;
23423 }
23424
23425 /* Run the backend on the cfun created above, transferring ownership of
23426 START_WITH_PASS. */
23427 run_rtl_passes (start_with_pass);
23428 return end_loc;
23429 }
23430
23431 #include "gt-c-c-parser.h"