]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/c/c-parser.c
Move string concatenation for C into the parser.
[thirdparty/gcc.git] / gcc / c / c-parser.c
1 /* Parser for C and Objective-C.
2 Copyright (C) 1987-2019 Free Software Foundation, Inc.
3
4 Parser actions based on the old Bison parser; structure somewhat
5 influenced by and fragments based on the C++ parser.
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
22
23 /* TODO:
24
25 Make sure all relevant comments, and all relevant code from all
26 actions, brought over from old parser. Verify exact correspondence
27 of syntax accepted.
28
29 Add testcases covering every input symbol in every state in old and
30 new parsers.
31
32 Include full syntax for GNU C, including erroneous cases accepted
33 with error messages, in syntax productions in comments.
34
35 Make more diagnostics in the front end generally take an explicit
36 location rather than implicitly using input_location. */
37
38 #include "config.h"
39 #define INCLUDE_UNIQUE_PTR
40 #include "system.h"
41 #include "coretypes.h"
42 #include "target.h"
43 #include "function.h"
44 #include "c-tree.h"
45 #include "timevar.h"
46 #include "stringpool.h"
47 #include "cgraph.h"
48 #include "attribs.h"
49 #include "stor-layout.h"
50 #include "varasm.h"
51 #include "trans-mem.h"
52 #include "c-family/c-pragma.h"
53 #include "c-lang.h"
54 #include "c-family/c-objc.h"
55 #include "plugin.h"
56 #include "omp-general.h"
57 #include "omp-offload.h"
58 #include "builtins.h"
59 #include "gomp-constants.h"
60 #include "c-family/c-indentation.h"
61 #include "gimple-expr.h"
62 #include "context.h"
63 #include "gcc-rich-location.h"
64 #include "c-parser.h"
65 #include "gimple-parser.h"
66 #include "read-rtl-function.h"
67 #include "run-rtl-passes.h"
68 #include "intl.h"
69 #include "c-family/name-hint.h"
70 #include "tree-iterator.h"
71 #include "memmodel.h"
72
73 /* We need to walk over decls with incomplete struct/union/enum types
74 after parsing the whole translation unit.
75 In finish_decl(), if the decl is static, has incomplete
76 struct/union/enum type, it is appeneded to incomplete_record_decls.
77 In c_parser_translation_unit(), we iterate over incomplete_record_decls
78 and report error if any of the decls are still incomplete. */
79
80 vec<tree> incomplete_record_decls;
81
82 void
83 set_c_expr_source_range (c_expr *expr,
84 location_t start, location_t finish)
85 {
86 expr->src_range.m_start = start;
87 expr->src_range.m_finish = finish;
88 if (expr->value)
89 set_source_range (expr->value, start, finish);
90 }
91
92 void
93 set_c_expr_source_range (c_expr *expr,
94 source_range src_range)
95 {
96 expr->src_range = src_range;
97 if (expr->value)
98 set_source_range (expr->value, src_range);
99 }
100
101 \f
102 /* Initialization routine for this file. */
103
104 void
105 c_parse_init (void)
106 {
107 /* The only initialization required is of the reserved word
108 identifiers. */
109 unsigned int i;
110 tree id;
111 int mask = 0;
112
113 /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in
114 the c_token structure. */
115 gcc_assert (RID_MAX <= 255);
116
117 mask |= D_CXXONLY;
118 if (!flag_isoc99)
119 mask |= D_C99;
120 if (flag_no_asm)
121 {
122 mask |= D_ASM | D_EXT;
123 if (!flag_isoc99)
124 mask |= D_EXT89;
125 }
126 if (!c_dialect_objc ())
127 mask |= D_OBJC | D_CXX_OBJC;
128
129 ridpointers = ggc_cleared_vec_alloc<tree> ((int) RID_MAX);
130 for (i = 0; i < num_c_common_reswords; i++)
131 {
132 /* If a keyword is disabled, do not enter it into the table
133 and so create a canonical spelling that isn't a keyword. */
134 if (c_common_reswords[i].disable & mask)
135 {
136 if (warn_cxx_compat
137 && (c_common_reswords[i].disable & D_CXXWARN))
138 {
139 id = get_identifier (c_common_reswords[i].word);
140 C_SET_RID_CODE (id, RID_CXX_COMPAT_WARN);
141 C_IS_RESERVED_WORD (id) = 1;
142 }
143 continue;
144 }
145
146 id = get_identifier (c_common_reswords[i].word);
147 C_SET_RID_CODE (id, c_common_reswords[i].rid);
148 C_IS_RESERVED_WORD (id) = 1;
149 ridpointers [(int) c_common_reswords[i].rid] = id;
150 }
151
152 for (i = 0; i < NUM_INT_N_ENTS; i++)
153 {
154 /* We always create the symbols but they aren't always supported. */
155 char name[50];
156 sprintf (name, "__int%d", int_n_data[i].bitsize);
157 id = get_identifier (name);
158 C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
159 C_IS_RESERVED_WORD (id) = 1;
160
161 sprintf (name, "__int%d__", int_n_data[i].bitsize);
162 id = get_identifier (name);
163 C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
164 C_IS_RESERVED_WORD (id) = 1;
165 }
166 }
167 \f
168 /* A parser structure recording information about the state and
169 context of parsing. Includes lexer information with up to two
170 tokens of look-ahead; more are not needed for C. */
171 struct GTY(()) c_parser {
172 /* The look-ahead tokens. */
173 c_token * GTY((skip)) tokens;
174 /* Buffer for look-ahead tokens. */
175 c_token tokens_buf[4];
176 /* How many look-ahead tokens are available (0 - 4, or
177 more if parsing from pre-lexed tokens). */
178 unsigned int tokens_avail;
179 /* True if a syntax error is being recovered from; false otherwise.
180 c_parser_error sets this flag. It should clear this flag when
181 enough tokens have been consumed to recover from the error. */
182 BOOL_BITFIELD error : 1;
183 /* True if we're processing a pragma, and shouldn't automatically
184 consume CPP_PRAGMA_EOL. */
185 BOOL_BITFIELD in_pragma : 1;
186 /* True if we're parsing the outermost block of an if statement. */
187 BOOL_BITFIELD in_if_block : 1;
188 /* True if we want to lex a translated, joined string (for an
189 initial #pragma pch_preprocess). Otherwise the parser is
190 responsible for concatenating strings and translating to the
191 execution character set as needed. */
192 BOOL_BITFIELD lex_joined_string : 1;
193 /* True if, when the parser is concatenating string literals, it
194 should translate them to the execution character set (false
195 inside attributes). */
196 BOOL_BITFIELD translate_strings_p : 1;
197
198 /* Objective-C specific parser/lexer information. */
199
200 /* True if we are in a context where the Objective-C "PQ" keywords
201 are considered keywords. */
202 BOOL_BITFIELD objc_pq_context : 1;
203 /* True if we are parsing a (potential) Objective-C foreach
204 statement. This is set to true after we parsed 'for (' and while
205 we wait for 'in' or ';' to decide if it's a standard C for loop or an
206 Objective-C foreach loop. */
207 BOOL_BITFIELD objc_could_be_foreach_context : 1;
208 /* The following flag is needed to contextualize Objective-C lexical
209 analysis. In some cases (e.g., 'int NSObject;'), it is
210 undesirable to bind an identifier to an Objective-C class, even
211 if a class with that name exists. */
212 BOOL_BITFIELD objc_need_raw_identifier : 1;
213 /* Nonzero if we're processing a __transaction statement. The value
214 is 1 | TM_STMT_ATTR_*. */
215 unsigned int in_transaction : 4;
216 /* True if we are in a context where the Objective-C "Property attribute"
217 keywords are valid. */
218 BOOL_BITFIELD objc_property_attr_context : 1;
219
220 /* Location of the last consumed token. */
221 location_t last_token_location;
222 };
223
224 /* Return a pointer to the Nth token in PARSERs tokens_buf. */
225
226 c_token *
227 c_parser_tokens_buf (c_parser *parser, unsigned n)
228 {
229 return &parser->tokens_buf[n];
230 }
231
232 /* Return the error state of PARSER. */
233
234 bool
235 c_parser_error (c_parser *parser)
236 {
237 return parser->error;
238 }
239
240 /* Set the error state of PARSER to ERR. */
241
242 void
243 c_parser_set_error (c_parser *parser, bool err)
244 {
245 parser->error = err;
246 }
247
248
249 /* The actual parser and external interface. ??? Does this need to be
250 garbage-collected? */
251
252 static GTY (()) c_parser *the_parser;
253
254 /* Read in and lex a single token, storing it in *TOKEN. */
255
256 static void
257 c_lex_one_token (c_parser *parser, c_token *token)
258 {
259 timevar_push (TV_LEX);
260
261 token->type = c_lex_with_flags (&token->value, &token->location,
262 &token->flags,
263 (parser->lex_joined_string
264 ? 0 : C_LEX_STRING_NO_JOIN));
265 token->id_kind = C_ID_NONE;
266 token->keyword = RID_MAX;
267 token->pragma_kind = PRAGMA_NONE;
268
269 switch (token->type)
270 {
271 case CPP_NAME:
272 {
273 tree decl;
274
275 bool objc_force_identifier = parser->objc_need_raw_identifier;
276 if (c_dialect_objc ())
277 parser->objc_need_raw_identifier = false;
278
279 if (C_IS_RESERVED_WORD (token->value))
280 {
281 enum rid rid_code = C_RID_CODE (token->value);
282
283 if (rid_code == RID_CXX_COMPAT_WARN)
284 {
285 warning_at (token->location,
286 OPT_Wc___compat,
287 "identifier %qE conflicts with C++ keyword",
288 token->value);
289 }
290 else if (rid_code >= RID_FIRST_ADDR_SPACE
291 && rid_code <= RID_LAST_ADDR_SPACE)
292 {
293 addr_space_t as;
294 as = (addr_space_t) (rid_code - RID_FIRST_ADDR_SPACE);
295 targetm.addr_space.diagnose_usage (as, token->location);
296 token->id_kind = C_ID_ADDRSPACE;
297 token->keyword = rid_code;
298 break;
299 }
300 else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code))
301 {
302 /* We found an Objective-C "pq" keyword (in, out,
303 inout, bycopy, byref, oneway). They need special
304 care because the interpretation depends on the
305 context. */
306 if (parser->objc_pq_context)
307 {
308 token->type = CPP_KEYWORD;
309 token->keyword = rid_code;
310 break;
311 }
312 else if (parser->objc_could_be_foreach_context
313 && rid_code == RID_IN)
314 {
315 /* We are in Objective-C, inside a (potential)
316 foreach context (which means after having
317 parsed 'for (', but before having parsed ';'),
318 and we found 'in'. We consider it the keyword
319 which terminates the declaration at the
320 beginning of a foreach-statement. Note that
321 this means you can't use 'in' for anything else
322 in that context; in particular, in Objective-C
323 you can't use 'in' as the name of the running
324 variable in a C for loop. We could potentially
325 try to add code here to disambiguate, but it
326 seems a reasonable limitation. */
327 token->type = CPP_KEYWORD;
328 token->keyword = rid_code;
329 break;
330 }
331 /* Else, "pq" keywords outside of the "pq" context are
332 not keywords, and we fall through to the code for
333 normal tokens. */
334 }
335 else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code))
336 {
337 /* We found an Objective-C "property attribute"
338 keyword (getter, setter, readonly, etc). These are
339 only valid in the property context. */
340 if (parser->objc_property_attr_context)
341 {
342 token->type = CPP_KEYWORD;
343 token->keyword = rid_code;
344 break;
345 }
346 /* Else they are not special keywords.
347 */
348 }
349 else if (c_dialect_objc ()
350 && (OBJC_IS_AT_KEYWORD (rid_code)
351 || OBJC_IS_CXX_KEYWORD (rid_code)))
352 {
353 /* We found one of the Objective-C "@" keywords (defs,
354 selector, synchronized, etc) or one of the
355 Objective-C "cxx" keywords (class, private,
356 protected, public, try, catch, throw) without a
357 preceding '@' sign. Do nothing and fall through to
358 the code for normal tokens (in C++ we would still
359 consider the CXX ones keywords, but not in C). */
360 ;
361 }
362 else
363 {
364 token->type = CPP_KEYWORD;
365 token->keyword = rid_code;
366 break;
367 }
368 }
369
370 decl = lookup_name (token->value);
371 if (decl)
372 {
373 if (TREE_CODE (decl) == TYPE_DECL)
374 {
375 token->id_kind = C_ID_TYPENAME;
376 break;
377 }
378 }
379 else if (c_dialect_objc ())
380 {
381 tree objc_interface_decl = objc_is_class_name (token->value);
382 /* Objective-C class names are in the same namespace as
383 variables and typedefs, and hence are shadowed by local
384 declarations. */
385 if (objc_interface_decl
386 && (!objc_force_identifier || global_bindings_p ()))
387 {
388 token->value = objc_interface_decl;
389 token->id_kind = C_ID_CLASSNAME;
390 break;
391 }
392 }
393 token->id_kind = C_ID_ID;
394 }
395 break;
396 case CPP_AT_NAME:
397 /* This only happens in Objective-C; it must be a keyword. */
398 token->type = CPP_KEYWORD;
399 switch (C_RID_CODE (token->value))
400 {
401 /* Replace 'class' with '@class', 'private' with '@private',
402 etc. This prevents confusion with the C++ keyword
403 'class', and makes the tokens consistent with other
404 Objective-C 'AT' keywords. For example '@class' is
405 reported as RID_AT_CLASS which is consistent with
406 '@synchronized', which is reported as
407 RID_AT_SYNCHRONIZED.
408 */
409 case RID_CLASS: token->keyword = RID_AT_CLASS; break;
410 case RID_PRIVATE: token->keyword = RID_AT_PRIVATE; break;
411 case RID_PROTECTED: token->keyword = RID_AT_PROTECTED; break;
412 case RID_PUBLIC: token->keyword = RID_AT_PUBLIC; break;
413 case RID_THROW: token->keyword = RID_AT_THROW; break;
414 case RID_TRY: token->keyword = RID_AT_TRY; break;
415 case RID_CATCH: token->keyword = RID_AT_CATCH; break;
416 case RID_SYNCHRONIZED: token->keyword = RID_AT_SYNCHRONIZED; break;
417 default: token->keyword = C_RID_CODE (token->value);
418 }
419 break;
420 case CPP_COLON:
421 case CPP_COMMA:
422 case CPP_CLOSE_PAREN:
423 case CPP_SEMICOLON:
424 /* These tokens may affect the interpretation of any identifiers
425 following, if doing Objective-C. */
426 if (c_dialect_objc ())
427 parser->objc_need_raw_identifier = false;
428 break;
429 case CPP_PRAGMA:
430 /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */
431 token->pragma_kind = (enum pragma_kind) TREE_INT_CST_LOW (token->value);
432 token->value = NULL;
433 break;
434 default:
435 break;
436 }
437 timevar_pop (TV_LEX);
438 }
439
440 /* Return a pointer to the next token from PARSER, reading it in if
441 necessary. */
442
443 c_token *
444 c_parser_peek_token (c_parser *parser)
445 {
446 if (parser->tokens_avail == 0)
447 {
448 c_lex_one_token (parser, &parser->tokens[0]);
449 parser->tokens_avail = 1;
450 }
451 return &parser->tokens[0];
452 }
453
454 /* Return a pointer to the next-but-one token from PARSER, reading it
455 in if necessary. The next token is already read in. */
456
457 c_token *
458 c_parser_peek_2nd_token (c_parser *parser)
459 {
460 if (parser->tokens_avail >= 2)
461 return &parser->tokens[1];
462 gcc_assert (parser->tokens_avail == 1);
463 gcc_assert (parser->tokens[0].type != CPP_EOF);
464 gcc_assert (parser->tokens[0].type != CPP_PRAGMA_EOL);
465 c_lex_one_token (parser, &parser->tokens[1]);
466 parser->tokens_avail = 2;
467 return &parser->tokens[1];
468 }
469
470 /* Return a pointer to the Nth token from PARSER, reading it
471 in if necessary. The N-1th token is already read in. */
472
473 c_token *
474 c_parser_peek_nth_token (c_parser *parser, unsigned int n)
475 {
476 /* N is 1-based, not zero-based. */
477 gcc_assert (n > 0);
478
479 if (parser->tokens_avail >= n)
480 return &parser->tokens[n - 1];
481 gcc_assert (parser->tokens_avail == n - 1);
482 c_lex_one_token (parser, &parser->tokens[n - 1]);
483 parser->tokens_avail = n;
484 return &parser->tokens[n - 1];
485 }
486
487 bool
488 c_keyword_starts_typename (enum rid keyword)
489 {
490 switch (keyword)
491 {
492 case RID_UNSIGNED:
493 case RID_LONG:
494 case RID_SHORT:
495 case RID_SIGNED:
496 case RID_COMPLEX:
497 case RID_INT:
498 case RID_CHAR:
499 case RID_FLOAT:
500 case RID_DOUBLE:
501 case RID_VOID:
502 case RID_DFLOAT32:
503 case RID_DFLOAT64:
504 case RID_DFLOAT128:
505 CASE_RID_FLOATN_NX:
506 case RID_BOOL:
507 case RID_ENUM:
508 case RID_STRUCT:
509 case RID_UNION:
510 case RID_TYPEOF:
511 case RID_CONST:
512 case RID_ATOMIC:
513 case RID_VOLATILE:
514 case RID_RESTRICT:
515 case RID_ATTRIBUTE:
516 case RID_FRACT:
517 case RID_ACCUM:
518 case RID_SAT:
519 case RID_AUTO_TYPE:
520 case RID_ALIGNAS:
521 return true;
522 default:
523 if (keyword >= RID_FIRST_INT_N
524 && keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
525 && int_n_enabled_p[keyword - RID_FIRST_INT_N])
526 return true;
527 return false;
528 }
529 }
530
531 /* Return true if TOKEN can start a type name,
532 false otherwise. */
533 bool
534 c_token_starts_typename (c_token *token)
535 {
536 switch (token->type)
537 {
538 case CPP_NAME:
539 switch (token->id_kind)
540 {
541 case C_ID_ID:
542 return false;
543 case C_ID_ADDRSPACE:
544 return true;
545 case C_ID_TYPENAME:
546 return true;
547 case C_ID_CLASSNAME:
548 gcc_assert (c_dialect_objc ());
549 return true;
550 default:
551 gcc_unreachable ();
552 }
553 case CPP_KEYWORD:
554 return c_keyword_starts_typename (token->keyword);
555 case CPP_LESS:
556 if (c_dialect_objc ())
557 return true;
558 return false;
559 default:
560 return false;
561 }
562 }
563
564 /* Return true if the next token from PARSER can start a type name,
565 false otherwise. LA specifies how to do lookahead in order to
566 detect unknown type names. If unsure, pick CLA_PREFER_ID. */
567
568 static inline bool
569 c_parser_next_tokens_start_typename (c_parser *parser, enum c_lookahead_kind la)
570 {
571 c_token *token = c_parser_peek_token (parser);
572 if (c_token_starts_typename (token))
573 return true;
574
575 /* Try a bit harder to detect an unknown typename. */
576 if (la != cla_prefer_id
577 && token->type == CPP_NAME
578 && token->id_kind == C_ID_ID
579
580 /* Do not try too hard when we could have "object in array". */
581 && !parser->objc_could_be_foreach_context
582
583 && (la == cla_prefer_type
584 || c_parser_peek_2nd_token (parser)->type == CPP_NAME
585 || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
586
587 /* Only unknown identifiers. */
588 && !lookup_name (token->value))
589 return true;
590
591 return false;
592 }
593
594 /* Return true if TOKEN is a type qualifier, false otherwise. */
595 static bool
596 c_token_is_qualifier (c_token *token)
597 {
598 switch (token->type)
599 {
600 case CPP_NAME:
601 switch (token->id_kind)
602 {
603 case C_ID_ADDRSPACE:
604 return true;
605 default:
606 return false;
607 }
608 case CPP_KEYWORD:
609 switch (token->keyword)
610 {
611 case RID_CONST:
612 case RID_VOLATILE:
613 case RID_RESTRICT:
614 case RID_ATTRIBUTE:
615 case RID_ATOMIC:
616 return true;
617 default:
618 return false;
619 }
620 case CPP_LESS:
621 return false;
622 default:
623 gcc_unreachable ();
624 }
625 }
626
627 /* Return true if the next token from PARSER is a type qualifier,
628 false otherwise. */
629 static inline bool
630 c_parser_next_token_is_qualifier (c_parser *parser)
631 {
632 c_token *token = c_parser_peek_token (parser);
633 return c_token_is_qualifier (token);
634 }
635
636 /* Return true if TOKEN can start declaration specifiers, false
637 otherwise. */
638 static bool
639 c_token_starts_declspecs (c_token *token)
640 {
641 switch (token->type)
642 {
643 case CPP_NAME:
644 switch (token->id_kind)
645 {
646 case C_ID_ID:
647 return false;
648 case C_ID_ADDRSPACE:
649 return true;
650 case C_ID_TYPENAME:
651 return true;
652 case C_ID_CLASSNAME:
653 gcc_assert (c_dialect_objc ());
654 return true;
655 default:
656 gcc_unreachable ();
657 }
658 case CPP_KEYWORD:
659 switch (token->keyword)
660 {
661 case RID_STATIC:
662 case RID_EXTERN:
663 case RID_REGISTER:
664 case RID_TYPEDEF:
665 case RID_INLINE:
666 case RID_NORETURN:
667 case RID_AUTO:
668 case RID_THREAD:
669 case RID_UNSIGNED:
670 case RID_LONG:
671 case RID_SHORT:
672 case RID_SIGNED:
673 case RID_COMPLEX:
674 case RID_INT:
675 case RID_CHAR:
676 case RID_FLOAT:
677 case RID_DOUBLE:
678 case RID_VOID:
679 case RID_DFLOAT32:
680 case RID_DFLOAT64:
681 case RID_DFLOAT128:
682 CASE_RID_FLOATN_NX:
683 case RID_BOOL:
684 case RID_ENUM:
685 case RID_STRUCT:
686 case RID_UNION:
687 case RID_TYPEOF:
688 case RID_CONST:
689 case RID_VOLATILE:
690 case RID_RESTRICT:
691 case RID_ATTRIBUTE:
692 case RID_FRACT:
693 case RID_ACCUM:
694 case RID_SAT:
695 case RID_ALIGNAS:
696 case RID_ATOMIC:
697 case RID_AUTO_TYPE:
698 return true;
699 default:
700 if (token->keyword >= RID_FIRST_INT_N
701 && token->keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
702 && int_n_enabled_p[token->keyword - RID_FIRST_INT_N])
703 return true;
704 return false;
705 }
706 case CPP_LESS:
707 if (c_dialect_objc ())
708 return true;
709 return false;
710 default:
711 return false;
712 }
713 }
714
715
716 /* Return true if TOKEN can start declaration specifiers or a static
717 assertion, false otherwise. */
718 static bool
719 c_token_starts_declaration (c_token *token)
720 {
721 if (c_token_starts_declspecs (token)
722 || token->keyword == RID_STATIC_ASSERT)
723 return true;
724 else
725 return false;
726 }
727
728 /* Return true if the next token from PARSER can start declaration
729 specifiers, false otherwise. */
730 bool
731 c_parser_next_token_starts_declspecs (c_parser *parser)
732 {
733 c_token *token = c_parser_peek_token (parser);
734
735 /* In Objective-C, a classname normally starts a declspecs unless it
736 is immediately followed by a dot. In that case, it is the
737 Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
738 setter/getter on the class. c_token_starts_declspecs() can't
739 differentiate between the two cases because it only checks the
740 current token, so we have a special check here. */
741 if (c_dialect_objc ()
742 && token->type == CPP_NAME
743 && token->id_kind == C_ID_CLASSNAME
744 && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
745 return false;
746
747 return c_token_starts_declspecs (token);
748 }
749
750 /* Return true if the next tokens from PARSER can start declaration
751 specifiers or a static assertion, false otherwise. */
752 bool
753 c_parser_next_tokens_start_declaration (c_parser *parser)
754 {
755 c_token *token = c_parser_peek_token (parser);
756
757 /* Same as above. */
758 if (c_dialect_objc ()
759 && token->type == CPP_NAME
760 && token->id_kind == C_ID_CLASSNAME
761 && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
762 return false;
763
764 /* Labels do not start declarations. */
765 if (token->type == CPP_NAME
766 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
767 return false;
768
769 if (c_token_starts_declaration (token))
770 return true;
771
772 if (c_parser_next_tokens_start_typename (parser, cla_nonabstract_decl))
773 return true;
774
775 return false;
776 }
777
778 /* Consume the next token from PARSER. */
779
780 void
781 c_parser_consume_token (c_parser *parser)
782 {
783 gcc_assert (parser->tokens_avail >= 1);
784 gcc_assert (parser->tokens[0].type != CPP_EOF);
785 gcc_assert (!parser->in_pragma || parser->tokens[0].type != CPP_PRAGMA_EOL);
786 gcc_assert (parser->error || parser->tokens[0].type != CPP_PRAGMA);
787 parser->last_token_location = parser->tokens[0].location;
788 if (parser->tokens != &parser->tokens_buf[0])
789 parser->tokens++;
790 else if (parser->tokens_avail == 2)
791 parser->tokens[0] = parser->tokens[1];
792 parser->tokens_avail--;
793 }
794
795 /* Expect the current token to be a #pragma. Consume it and remember
796 that we've begun parsing a pragma. */
797
798 static void
799 c_parser_consume_pragma (c_parser *parser)
800 {
801 gcc_assert (!parser->in_pragma);
802 gcc_assert (parser->tokens_avail >= 1);
803 gcc_assert (parser->tokens[0].type == CPP_PRAGMA);
804 if (parser->tokens != &parser->tokens_buf[0])
805 parser->tokens++;
806 else if (parser->tokens_avail == 2)
807 parser->tokens[0] = parser->tokens[1];
808 parser->tokens_avail--;
809 parser->in_pragma = true;
810 }
811
812 /* Update the global input_location from TOKEN. */
813 static inline void
814 c_parser_set_source_position_from_token (c_token *token)
815 {
816 if (token->type != CPP_EOF)
817 {
818 input_location = token->location;
819 }
820 }
821
822 /* Helper function for c_parser_error.
823 Having peeked a token of kind TOK1_KIND that might signify
824 a conflict marker, peek successor tokens to determine
825 if we actually do have a conflict marker.
826 Specifically, we consider a run of 7 '<', '=' or '>' characters
827 at the start of a line as a conflict marker.
828 These come through the lexer as three pairs and a single,
829 e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<').
830 If it returns true, *OUT_LOC is written to with the location/range
831 of the marker. */
832
833 static bool
834 c_parser_peek_conflict_marker (c_parser *parser, enum cpp_ttype tok1_kind,
835 location_t *out_loc)
836 {
837 c_token *token2 = c_parser_peek_2nd_token (parser);
838 if (token2->type != tok1_kind)
839 return false;
840 c_token *token3 = c_parser_peek_nth_token (parser, 3);
841 if (token3->type != tok1_kind)
842 return false;
843 c_token *token4 = c_parser_peek_nth_token (parser, 4);
844 if (token4->type != conflict_marker_get_final_tok_kind (tok1_kind))
845 return false;
846
847 /* It must be at the start of the line. */
848 location_t start_loc = c_parser_peek_token (parser)->location;
849 if (LOCATION_COLUMN (start_loc) != 1)
850 return false;
851
852 /* We have a conflict marker. Construct a location of the form:
853 <<<<<<<
854 ^~~~~~~
855 with start == caret, finishing at the end of the marker. */
856 location_t finish_loc = get_finish (token4->location);
857 *out_loc = make_location (start_loc, start_loc, finish_loc);
858
859 return true;
860 }
861
862 /* Issue a diagnostic of the form
863 FILE:LINE: MESSAGE before TOKEN
864 where TOKEN is the next token in the input stream of PARSER.
865 MESSAGE (specified by the caller) is usually of the form "expected
866 OTHER-TOKEN".
867
868 Use RICHLOC as the location of the diagnostic.
869
870 Do not issue a diagnostic if still recovering from an error.
871
872 Return true iff an error was actually emitted.
873
874 ??? This is taken from the C++ parser, but building up messages in
875 this way is not i18n-friendly and some other approach should be
876 used. */
877
878 static bool
879 c_parser_error_richloc (c_parser *parser, const char *gmsgid,
880 rich_location *richloc)
881 {
882 c_token *token = c_parser_peek_token (parser);
883 if (parser->error)
884 return false;
885 parser->error = true;
886 if (!gmsgid)
887 return false;
888
889 /* If this is actually a conflict marker, report it as such. */
890 if (token->type == CPP_LSHIFT
891 || token->type == CPP_RSHIFT
892 || token->type == CPP_EQ_EQ)
893 {
894 location_t loc;
895 if (c_parser_peek_conflict_marker (parser, token->type, &loc))
896 {
897 error_at (loc, "version control conflict marker in file");
898 return true;
899 }
900 }
901
902 c_parse_error (gmsgid,
903 /* Because c_parse_error does not understand
904 CPP_KEYWORD, keywords are treated like
905 identifiers. */
906 (token->type == CPP_KEYWORD ? CPP_NAME : token->type),
907 /* ??? The C parser does not save the cpp flags of a
908 token, we need to pass 0 here and we will not get
909 the source spelling of some tokens but rather the
910 canonical spelling. */
911 token->value, /*flags=*/0, richloc);
912 return true;
913 }
914
915 /* As c_parser_error_richloc, but issue the message at the
916 location of PARSER's next token, or at input_location
917 if the next token is EOF. */
918
919 bool
920 c_parser_error (c_parser *parser, const char *gmsgid)
921 {
922 c_token *token = c_parser_peek_token (parser);
923 c_parser_set_source_position_from_token (token);
924 rich_location richloc (line_table, input_location);
925 return c_parser_error_richloc (parser, gmsgid, &richloc);
926 }
927
928 /* Some tokens naturally come in pairs e.g.'(' and ')'.
929 This class is for tracking such a matching pair of symbols.
930 In particular, it tracks the location of the first token,
931 so that if the second token is missing, we can highlight the
932 location of the first token when notifying the user about the
933 problem. */
934
935 template <typename traits_t>
936 class token_pair
937 {
938 public:
939 /* token_pair's ctor. */
940 token_pair () : m_open_loc (UNKNOWN_LOCATION) {}
941
942 /* If the next token is the opening symbol for this pair, consume it and
943 return true.
944 Otherwise, issue an error and return false.
945 In either case, record the location of the opening token. */
946
947 bool require_open (c_parser *parser)
948 {
949 c_token *token = c_parser_peek_token (parser);
950 if (token)
951 m_open_loc = token->location;
952
953 return c_parser_require (parser, traits_t::open_token_type,
954 traits_t::open_gmsgid);
955 }
956
957 /* Consume the next token from PARSER, recording its location as
958 that of the opening token within the pair. */
959
960 void consume_open (c_parser *parser)
961 {
962 c_token *token = c_parser_peek_token (parser);
963 gcc_assert (token->type == traits_t::open_token_type);
964 m_open_loc = token->location;
965 c_parser_consume_token (parser);
966 }
967
968 /* If the next token is the closing symbol for this pair, consume it
969 and return true.
970 Otherwise, issue an error, highlighting the location of the
971 corresponding opening token, and return false. */
972
973 bool require_close (c_parser *parser) const
974 {
975 return c_parser_require (parser, traits_t::close_token_type,
976 traits_t::close_gmsgid, m_open_loc);
977 }
978
979 /* Like token_pair::require_close, except that tokens will be skipped
980 until the desired token is found. An error message is still produced
981 if the next token is not as expected. */
982
983 void skip_until_found_close (c_parser *parser) const
984 {
985 c_parser_skip_until_found (parser, traits_t::close_token_type,
986 traits_t::close_gmsgid, m_open_loc);
987 }
988
989 private:
990 location_t m_open_loc;
991 };
992
993 /* Traits for token_pair<T> for tracking matching pairs of parentheses. */
994
995 struct matching_paren_traits
996 {
997 static const enum cpp_ttype open_token_type = CPP_OPEN_PAREN;
998 static const char * const open_gmsgid;
999 static const enum cpp_ttype close_token_type = CPP_CLOSE_PAREN;
1000 static const char * const close_gmsgid;
1001 };
1002
1003 const char * const matching_paren_traits::open_gmsgid = "expected %<(%>";
1004 const char * const matching_paren_traits::close_gmsgid = "expected %<)%>";
1005
1006 /* "matching_parens" is a token_pair<T> class for tracking matching
1007 pairs of parentheses. */
1008
1009 typedef token_pair<matching_paren_traits> matching_parens;
1010
1011 /* Traits for token_pair<T> for tracking matching pairs of braces. */
1012
1013 struct matching_brace_traits
1014 {
1015 static const enum cpp_ttype open_token_type = CPP_OPEN_BRACE;
1016 static const char * const open_gmsgid;
1017 static const enum cpp_ttype close_token_type = CPP_CLOSE_BRACE;
1018 static const char * const close_gmsgid;
1019 };
1020
1021 const char * const matching_brace_traits::open_gmsgid = "expected %<{%>";
1022 const char * const matching_brace_traits::close_gmsgid = "expected %<}%>";
1023
1024 /* "matching_braces" is a token_pair<T> class for tracking matching
1025 pairs of braces. */
1026
1027 typedef token_pair<matching_brace_traits> matching_braces;
1028
1029 /* Get a description of the matching symbol to TYPE e.g. "(" for
1030 CPP_CLOSE_PAREN. */
1031
1032 static const char *
1033 get_matching_symbol (enum cpp_ttype type)
1034 {
1035 switch (type)
1036 {
1037 default:
1038 gcc_unreachable ();
1039 return "";
1040 case CPP_CLOSE_PAREN:
1041 return "(";
1042 case CPP_CLOSE_BRACE:
1043 return "{";
1044 }
1045 }
1046
1047 /* If the next token is of the indicated TYPE, consume it. Otherwise,
1048 issue the error MSGID. If MSGID is NULL then a message has already
1049 been produced and no message will be produced this time. Returns
1050 true if found, false otherwise.
1051
1052 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1053 within any error as the location of an "opening" token matching
1054 the close token TYPE (e.g. the location of the '(' when TYPE is
1055 CPP_CLOSE_PAREN).
1056
1057 If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly
1058 one type (e.g. "expected %<)%>") and thus it may be reasonable to
1059 attempt to generate a fix-it hint for the problem.
1060 Otherwise msgid describes multiple token types (e.g.
1061 "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to
1062 generate a fix-it hint. */
1063
1064 bool
1065 c_parser_require (c_parser *parser,
1066 enum cpp_ttype type,
1067 const char *msgid,
1068 location_t matching_location,
1069 bool type_is_unique)
1070 {
1071 if (c_parser_next_token_is (parser, type))
1072 {
1073 c_parser_consume_token (parser);
1074 return true;
1075 }
1076 else
1077 {
1078 location_t next_token_loc = c_parser_peek_token (parser)->location;
1079 gcc_rich_location richloc (next_token_loc);
1080
1081 /* Potentially supply a fix-it hint, suggesting to add the
1082 missing token immediately after the *previous* token.
1083 This may move the primary location within richloc. */
1084 if (!parser->error && type_is_unique)
1085 maybe_suggest_missing_token_insertion (&richloc, type,
1086 parser->last_token_location);
1087
1088 /* If matching_location != UNKNOWN_LOCATION, highlight it.
1089 Attempt to consolidate diagnostics by printing it as a
1090 secondary range within the main diagnostic. */
1091 bool added_matching_location = false;
1092 if (matching_location != UNKNOWN_LOCATION)
1093 added_matching_location
1094 = richloc.add_location_if_nearby (matching_location);
1095
1096 if (c_parser_error_richloc (parser, msgid, &richloc))
1097 /* If we weren't able to consolidate matching_location, then
1098 print it as a secondary diagnostic. */
1099 if (matching_location != UNKNOWN_LOCATION && !added_matching_location)
1100 inform (matching_location, "to match this %qs",
1101 get_matching_symbol (type));
1102
1103 return false;
1104 }
1105 }
1106
1107 /* If the next token is the indicated keyword, consume it. Otherwise,
1108 issue the error MSGID. Returns true if found, false otherwise. */
1109
1110 static bool
1111 c_parser_require_keyword (c_parser *parser,
1112 enum rid keyword,
1113 const char *msgid)
1114 {
1115 if (c_parser_next_token_is_keyword (parser, keyword))
1116 {
1117 c_parser_consume_token (parser);
1118 return true;
1119 }
1120 else
1121 {
1122 c_parser_error (parser, msgid);
1123 return false;
1124 }
1125 }
1126
1127 /* Like c_parser_require, except that tokens will be skipped until the
1128 desired token is found. An error message is still produced if the
1129 next token is not as expected. If MSGID is NULL then a message has
1130 already been produced and no message will be produced this
1131 time.
1132
1133 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
1134 within any error as the location of an "opening" token matching
1135 the close token TYPE (e.g. the location of the '(' when TYPE is
1136 CPP_CLOSE_PAREN). */
1137
1138 void
1139 c_parser_skip_until_found (c_parser *parser,
1140 enum cpp_ttype type,
1141 const char *msgid,
1142 location_t matching_location)
1143 {
1144 unsigned nesting_depth = 0;
1145
1146 if (c_parser_require (parser, type, msgid, matching_location))
1147 return;
1148
1149 /* Skip tokens until the desired token is found. */
1150 while (true)
1151 {
1152 /* Peek at the next token. */
1153 c_token *token = c_parser_peek_token (parser);
1154 /* If we've reached the token we want, consume it and stop. */
1155 if (token->type == type && !nesting_depth)
1156 {
1157 c_parser_consume_token (parser);
1158 break;
1159 }
1160
1161 /* If we've run out of tokens, stop. */
1162 if (token->type == CPP_EOF)
1163 return;
1164 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1165 return;
1166 if (token->type == CPP_OPEN_BRACE
1167 || token->type == CPP_OPEN_PAREN
1168 || token->type == CPP_OPEN_SQUARE)
1169 ++nesting_depth;
1170 else if (token->type == CPP_CLOSE_BRACE
1171 || token->type == CPP_CLOSE_PAREN
1172 || token->type == CPP_CLOSE_SQUARE)
1173 {
1174 if (nesting_depth-- == 0)
1175 break;
1176 }
1177 /* Consume this token. */
1178 c_parser_consume_token (parser);
1179 }
1180 parser->error = false;
1181 }
1182
1183 /* Skip tokens until the end of a parameter is found, but do not
1184 consume the comma, semicolon or closing delimiter. */
1185
1186 static void
1187 c_parser_skip_to_end_of_parameter (c_parser *parser)
1188 {
1189 unsigned nesting_depth = 0;
1190
1191 while (true)
1192 {
1193 c_token *token = c_parser_peek_token (parser);
1194 if ((token->type == CPP_COMMA || token->type == CPP_SEMICOLON)
1195 && !nesting_depth)
1196 break;
1197 /* If we've run out of tokens, stop. */
1198 if (token->type == CPP_EOF)
1199 return;
1200 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
1201 return;
1202 if (token->type == CPP_OPEN_BRACE
1203 || token->type == CPP_OPEN_PAREN
1204 || token->type == CPP_OPEN_SQUARE)
1205 ++nesting_depth;
1206 else if (token->type == CPP_CLOSE_BRACE
1207 || token->type == CPP_CLOSE_PAREN
1208 || token->type == CPP_CLOSE_SQUARE)
1209 {
1210 if (nesting_depth-- == 0)
1211 break;
1212 }
1213 /* Consume this token. */
1214 c_parser_consume_token (parser);
1215 }
1216 parser->error = false;
1217 }
1218
1219 /* Expect to be at the end of the pragma directive and consume an
1220 end of line marker. */
1221
1222 static void
1223 c_parser_skip_to_pragma_eol (c_parser *parser, bool error_if_not_eol = true)
1224 {
1225 gcc_assert (parser->in_pragma);
1226 parser->in_pragma = false;
1227
1228 if (error_if_not_eol && c_parser_peek_token (parser)->type != CPP_PRAGMA_EOL)
1229 c_parser_error (parser, "expected end of line");
1230
1231 cpp_ttype token_type;
1232 do
1233 {
1234 c_token *token = c_parser_peek_token (parser);
1235 token_type = token->type;
1236 if (token_type == CPP_EOF)
1237 break;
1238 c_parser_consume_token (parser);
1239 }
1240 while (token_type != CPP_PRAGMA_EOL);
1241
1242 parser->error = false;
1243 }
1244
1245 /* Skip tokens until we have consumed an entire block, or until we
1246 have consumed a non-nested ';'. */
1247
1248 static void
1249 c_parser_skip_to_end_of_block_or_statement (c_parser *parser)
1250 {
1251 unsigned nesting_depth = 0;
1252 bool save_error = parser->error;
1253
1254 while (true)
1255 {
1256 c_token *token;
1257
1258 /* Peek at the next token. */
1259 token = c_parser_peek_token (parser);
1260
1261 switch (token->type)
1262 {
1263 case CPP_EOF:
1264 return;
1265
1266 case CPP_PRAGMA_EOL:
1267 if (parser->in_pragma)
1268 return;
1269 break;
1270
1271 case CPP_SEMICOLON:
1272 /* If the next token is a ';', we have reached the
1273 end of the statement. */
1274 if (!nesting_depth)
1275 {
1276 /* Consume the ';'. */
1277 c_parser_consume_token (parser);
1278 goto finished;
1279 }
1280 break;
1281
1282 case CPP_CLOSE_BRACE:
1283 /* If the next token is a non-nested '}', then we have
1284 reached the end of the current block. */
1285 if (nesting_depth == 0 || --nesting_depth == 0)
1286 {
1287 c_parser_consume_token (parser);
1288 goto finished;
1289 }
1290 break;
1291
1292 case CPP_OPEN_BRACE:
1293 /* If it the next token is a '{', then we are entering a new
1294 block. Consume the entire block. */
1295 ++nesting_depth;
1296 break;
1297
1298 case CPP_PRAGMA:
1299 /* If we see a pragma, consume the whole thing at once. We
1300 have some safeguards against consuming pragmas willy-nilly.
1301 Normally, we'd expect to be here with parser->error set,
1302 which disables these safeguards. But it's possible to get
1303 here for secondary error recovery, after parser->error has
1304 been cleared. */
1305 c_parser_consume_pragma (parser);
1306 c_parser_skip_to_pragma_eol (parser);
1307 parser->error = save_error;
1308 continue;
1309
1310 default:
1311 break;
1312 }
1313
1314 c_parser_consume_token (parser);
1315 }
1316
1317 finished:
1318 parser->error = false;
1319 }
1320
1321 /* CPP's options (initialized by c-opts.c). */
1322 extern cpp_options *cpp_opts;
1323
1324 /* Save the warning flags which are controlled by __extension__. */
1325
1326 static inline int
1327 disable_extension_diagnostics (void)
1328 {
1329 int ret = (pedantic
1330 | (warn_pointer_arith << 1)
1331 | (warn_traditional << 2)
1332 | (flag_iso << 3)
1333 | (warn_long_long << 4)
1334 | (warn_cxx_compat << 5)
1335 | (warn_overlength_strings << 6)
1336 /* warn_c90_c99_compat has three states: -1/0/1, so we must
1337 play tricks to properly restore it. */
1338 | ((warn_c90_c99_compat == 1) << 7)
1339 | ((warn_c90_c99_compat == -1) << 8)
1340 /* Similarly for warn_c99_c11_compat. */
1341 | ((warn_c99_c11_compat == 1) << 9)
1342 | ((warn_c99_c11_compat == -1) << 10)
1343 /* Similarly for warn_c11_c2x_compat. */
1344 | ((warn_c11_c2x_compat == 1) << 11)
1345 | ((warn_c11_c2x_compat == -1) << 12)
1346 );
1347 cpp_opts->cpp_pedantic = pedantic = 0;
1348 warn_pointer_arith = 0;
1349 cpp_opts->cpp_warn_traditional = warn_traditional = 0;
1350 flag_iso = 0;
1351 cpp_opts->cpp_warn_long_long = warn_long_long = 0;
1352 warn_cxx_compat = 0;
1353 warn_overlength_strings = 0;
1354 warn_c90_c99_compat = 0;
1355 warn_c99_c11_compat = 0;
1356 warn_c11_c2x_compat = 0;
1357 return ret;
1358 }
1359
1360 /* Restore the warning flags which are controlled by __extension__.
1361 FLAGS is the return value from disable_extension_diagnostics. */
1362
1363 static inline void
1364 restore_extension_diagnostics (int flags)
1365 {
1366 cpp_opts->cpp_pedantic = pedantic = flags & 1;
1367 warn_pointer_arith = (flags >> 1) & 1;
1368 cpp_opts->cpp_warn_traditional = warn_traditional = (flags >> 2) & 1;
1369 flag_iso = (flags >> 3) & 1;
1370 cpp_opts->cpp_warn_long_long = warn_long_long = (flags >> 4) & 1;
1371 warn_cxx_compat = (flags >> 5) & 1;
1372 warn_overlength_strings = (flags >> 6) & 1;
1373 /* See above for why is this needed. */
1374 warn_c90_c99_compat = (flags >> 7) & 1 ? 1 : ((flags >> 8) & 1 ? -1 : 0);
1375 warn_c99_c11_compat = (flags >> 9) & 1 ? 1 : ((flags >> 10) & 1 ? -1 : 0);
1376 warn_c11_c2x_compat = (flags >> 11) & 1 ? 1 : ((flags >> 12) & 1 ? -1 : 0);
1377 }
1378
1379 /* Helper data structure for parsing #pragma acc routine. */
1380 struct oacc_routine_data {
1381 bool error_seen; /* Set if error has been reported. */
1382 bool fndecl_seen; /* Set if one fn decl/definition has been seen already. */
1383 tree clauses;
1384 location_t loc;
1385 };
1386
1387 static void c_parser_external_declaration (c_parser *);
1388 static void c_parser_asm_definition (c_parser *);
1389 static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
1390 bool, bool, tree *, vec<c_token>,
1391 struct oacc_routine_data * = NULL,
1392 bool * = NULL);
1393 static void c_parser_static_assert_declaration_no_semi (c_parser *);
1394 static void c_parser_static_assert_declaration (c_parser *);
1395 static struct c_typespec c_parser_enum_specifier (c_parser *);
1396 static struct c_typespec c_parser_struct_or_union_specifier (c_parser *);
1397 static tree c_parser_struct_declaration (c_parser *);
1398 static struct c_typespec c_parser_typeof_specifier (c_parser *);
1399 static tree c_parser_alignas_specifier (c_parser *);
1400 static struct c_declarator *c_parser_direct_declarator (c_parser *, bool,
1401 c_dtr_syn, bool *);
1402 static struct c_declarator *c_parser_direct_declarator_inner (c_parser *,
1403 bool,
1404 struct c_declarator *);
1405 static struct c_arg_info *c_parser_parms_declarator (c_parser *, bool, tree);
1406 static struct c_arg_info *c_parser_parms_list_declarator (c_parser *, tree,
1407 tree);
1408 static struct c_parm *c_parser_parameter_declaration (c_parser *, tree);
1409 static tree c_parser_simple_asm_expr (c_parser *);
1410 static tree c_parser_gnu_attributes (c_parser *);
1411 static struct c_expr c_parser_initializer (c_parser *);
1412 static struct c_expr c_parser_braced_init (c_parser *, tree, bool,
1413 struct obstack *);
1414 static void c_parser_initelt (c_parser *, struct obstack *);
1415 static void c_parser_initval (c_parser *, struct c_expr *,
1416 struct obstack *);
1417 static tree c_parser_compound_statement (c_parser *);
1418 static void c_parser_compound_statement_nostart (c_parser *);
1419 static void c_parser_label (c_parser *);
1420 static void c_parser_statement (c_parser *, bool *, location_t * = NULL);
1421 static void c_parser_statement_after_labels (c_parser *, bool *,
1422 vec<tree> * = NULL);
1423 static tree c_parser_c99_block_statement (c_parser *, bool *,
1424 location_t * = NULL);
1425 static void c_parser_if_statement (c_parser *, bool *, vec<tree> *);
1426 static void c_parser_switch_statement (c_parser *, bool *);
1427 static void c_parser_while_statement (c_parser *, bool, unsigned short, bool *);
1428 static void c_parser_do_statement (c_parser *, bool, unsigned short);
1429 static void c_parser_for_statement (c_parser *, bool, unsigned short, bool *);
1430 static tree c_parser_asm_statement (c_parser *);
1431 static tree c_parser_asm_operands (c_parser *);
1432 static tree c_parser_asm_goto_operands (c_parser *);
1433 static tree c_parser_asm_clobbers (c_parser *);
1434 static struct c_expr c_parser_expr_no_commas (c_parser *, struct c_expr *,
1435 tree = NULL_TREE);
1436 static struct c_expr c_parser_conditional_expression (c_parser *,
1437 struct c_expr *, tree);
1438 static struct c_expr c_parser_binary_expression (c_parser *, struct c_expr *,
1439 tree);
1440 static struct c_expr c_parser_cast_expression (c_parser *, struct c_expr *);
1441 static struct c_expr c_parser_unary_expression (c_parser *);
1442 static struct c_expr c_parser_sizeof_expression (c_parser *);
1443 static struct c_expr c_parser_alignof_expression (c_parser *);
1444 static struct c_expr c_parser_postfix_expression (c_parser *);
1445 static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *,
1446 struct c_type_name *,
1447 location_t);
1448 static struct c_expr c_parser_postfix_expression_after_primary (c_parser *,
1449 location_t loc,
1450 struct c_expr);
1451 static tree c_parser_transaction (c_parser *, enum rid);
1452 static struct c_expr c_parser_transaction_expression (c_parser *, enum rid);
1453 static tree c_parser_transaction_cancel (c_parser *);
1454 static struct c_expr c_parser_expression (c_parser *);
1455 static struct c_expr c_parser_expression_conv (c_parser *);
1456 static vec<tree, va_gc> *c_parser_expr_list (c_parser *, bool, bool,
1457 vec<tree, va_gc> **, location_t *,
1458 tree *, vec<location_t> *,
1459 unsigned int * = NULL);
1460 static struct c_expr c_parser_has_attribute_expression (c_parser *);
1461
1462 static void c_parser_oacc_declare (c_parser *);
1463 static void c_parser_oacc_enter_exit_data (c_parser *, bool);
1464 static void c_parser_oacc_update (c_parser *);
1465 static void c_parser_omp_construct (c_parser *, bool *);
1466 static void c_parser_omp_threadprivate (c_parser *);
1467 static void c_parser_omp_barrier (c_parser *);
1468 static void c_parser_omp_depobj (c_parser *);
1469 static void c_parser_omp_flush (c_parser *);
1470 static tree c_parser_omp_for_loop (location_t, c_parser *, enum tree_code,
1471 tree, tree *, bool *);
1472 static void c_parser_omp_taskwait (c_parser *);
1473 static void c_parser_omp_taskyield (c_parser *);
1474 static void c_parser_omp_cancel (c_parser *);
1475
1476 enum pragma_context { pragma_external, pragma_struct, pragma_param,
1477 pragma_stmt, pragma_compound };
1478 static bool c_parser_pragma (c_parser *, enum pragma_context, bool *);
1479 static void c_parser_omp_cancellation_point (c_parser *, enum pragma_context);
1480 static bool c_parser_omp_target (c_parser *, enum pragma_context, bool *);
1481 static void c_parser_omp_end_declare_target (c_parser *);
1482 static void c_parser_omp_declare (c_parser *, enum pragma_context);
1483 static void c_parser_omp_requires (c_parser *);
1484 static bool c_parser_omp_ordered (c_parser *, enum pragma_context, bool *);
1485 static void c_parser_oacc_routine (c_parser *, enum pragma_context);
1486
1487 /* These Objective-C parser functions are only ever called when
1488 compiling Objective-C. */
1489 static void c_parser_objc_class_definition (c_parser *, tree);
1490 static void c_parser_objc_class_instance_variables (c_parser *);
1491 static void c_parser_objc_class_declaration (c_parser *);
1492 static void c_parser_objc_alias_declaration (c_parser *);
1493 static void c_parser_objc_protocol_definition (c_parser *, tree);
1494 static bool c_parser_objc_method_type (c_parser *);
1495 static void c_parser_objc_method_definition (c_parser *);
1496 static void c_parser_objc_methodprotolist (c_parser *);
1497 static void c_parser_objc_methodproto (c_parser *);
1498 static tree c_parser_objc_method_decl (c_parser *, bool, tree *, tree *);
1499 static tree c_parser_objc_type_name (c_parser *);
1500 static tree c_parser_objc_protocol_refs (c_parser *);
1501 static void c_parser_objc_try_catch_finally_statement (c_parser *);
1502 static void c_parser_objc_synchronized_statement (c_parser *);
1503 static tree c_parser_objc_selector (c_parser *);
1504 static tree c_parser_objc_selector_arg (c_parser *);
1505 static tree c_parser_objc_receiver (c_parser *);
1506 static tree c_parser_objc_message_args (c_parser *);
1507 static tree c_parser_objc_keywordexpr (c_parser *);
1508 static void c_parser_objc_at_property_declaration (c_parser *);
1509 static void c_parser_objc_at_synthesize_declaration (c_parser *);
1510 static void c_parser_objc_at_dynamic_declaration (c_parser *);
1511 static bool c_parser_objc_diagnose_bad_element_prefix
1512 (c_parser *, struct c_declspecs *);
1513
1514 static void c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass);
1515
1516 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
1517
1518 translation-unit:
1519 external-declarations
1520
1521 external-declarations:
1522 external-declaration
1523 external-declarations external-declaration
1524
1525 GNU extensions:
1526
1527 translation-unit:
1528 empty
1529 */
1530
1531 static void
1532 c_parser_translation_unit (c_parser *parser)
1533 {
1534 if (c_parser_next_token_is (parser, CPP_EOF))
1535 {
1536 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1537 "ISO C forbids an empty translation unit");
1538 }
1539 else
1540 {
1541 void *obstack_position = obstack_alloc (&parser_obstack, 0);
1542 mark_valid_location_for_stdc_pragma (false);
1543 do
1544 {
1545 ggc_collect ();
1546 c_parser_external_declaration (parser);
1547 obstack_free (&parser_obstack, obstack_position);
1548 }
1549 while (c_parser_next_token_is_not (parser, CPP_EOF));
1550 }
1551
1552 unsigned int i;
1553 tree decl;
1554 FOR_EACH_VEC_ELT (incomplete_record_decls, i, decl)
1555 if (DECL_SIZE (decl) == NULL_TREE && TREE_TYPE (decl) != error_mark_node)
1556 error ("storage size of %q+D isn%'t known", decl);
1557 }
1558
1559 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
1560
1561 external-declaration:
1562 function-definition
1563 declaration
1564
1565 GNU extensions:
1566
1567 external-declaration:
1568 asm-definition
1569 ;
1570 __extension__ external-declaration
1571
1572 Objective-C:
1573
1574 external-declaration:
1575 objc-class-definition
1576 objc-class-declaration
1577 objc-alias-declaration
1578 objc-protocol-definition
1579 objc-method-definition
1580 @end
1581 */
1582
1583 static void
1584 c_parser_external_declaration (c_parser *parser)
1585 {
1586 int ext;
1587 switch (c_parser_peek_token (parser)->type)
1588 {
1589 case CPP_KEYWORD:
1590 switch (c_parser_peek_token (parser)->keyword)
1591 {
1592 case RID_EXTENSION:
1593 ext = disable_extension_diagnostics ();
1594 c_parser_consume_token (parser);
1595 c_parser_external_declaration (parser);
1596 restore_extension_diagnostics (ext);
1597 break;
1598 case RID_ASM:
1599 c_parser_asm_definition (parser);
1600 break;
1601 case RID_AT_INTERFACE:
1602 case RID_AT_IMPLEMENTATION:
1603 gcc_assert (c_dialect_objc ());
1604 c_parser_objc_class_definition (parser, NULL_TREE);
1605 break;
1606 case RID_AT_CLASS:
1607 gcc_assert (c_dialect_objc ());
1608 c_parser_objc_class_declaration (parser);
1609 break;
1610 case RID_AT_ALIAS:
1611 gcc_assert (c_dialect_objc ());
1612 c_parser_objc_alias_declaration (parser);
1613 break;
1614 case RID_AT_PROTOCOL:
1615 gcc_assert (c_dialect_objc ());
1616 c_parser_objc_protocol_definition (parser, NULL_TREE);
1617 break;
1618 case RID_AT_PROPERTY:
1619 gcc_assert (c_dialect_objc ());
1620 c_parser_objc_at_property_declaration (parser);
1621 break;
1622 case RID_AT_SYNTHESIZE:
1623 gcc_assert (c_dialect_objc ());
1624 c_parser_objc_at_synthesize_declaration (parser);
1625 break;
1626 case RID_AT_DYNAMIC:
1627 gcc_assert (c_dialect_objc ());
1628 c_parser_objc_at_dynamic_declaration (parser);
1629 break;
1630 case RID_AT_END:
1631 gcc_assert (c_dialect_objc ());
1632 c_parser_consume_token (parser);
1633 objc_finish_implementation ();
1634 break;
1635 default:
1636 goto decl_or_fndef;
1637 }
1638 break;
1639 case CPP_SEMICOLON:
1640 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
1641 "ISO C does not allow extra %<;%> outside of a function");
1642 c_parser_consume_token (parser);
1643 break;
1644 case CPP_PRAGMA:
1645 mark_valid_location_for_stdc_pragma (true);
1646 c_parser_pragma (parser, pragma_external, NULL);
1647 mark_valid_location_for_stdc_pragma (false);
1648 break;
1649 case CPP_PLUS:
1650 case CPP_MINUS:
1651 if (c_dialect_objc ())
1652 {
1653 c_parser_objc_method_definition (parser);
1654 break;
1655 }
1656 /* Else fall through, and yield a syntax error trying to parse
1657 as a declaration or function definition. */
1658 /* FALLTHRU */
1659 default:
1660 decl_or_fndef:
1661 /* A declaration or a function definition (or, in Objective-C,
1662 an @interface or @protocol with prefix attributes). We can
1663 only tell which after parsing the declaration specifiers, if
1664 any, and the first declarator. */
1665 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
1666 NULL, vNULL);
1667 break;
1668 }
1669 }
1670
1671 static void c_finish_omp_declare_simd (c_parser *, tree, tree, vec<c_token>);
1672 static void c_finish_oacc_routine (struct oacc_routine_data *, tree, bool);
1673
1674 /* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */
1675
1676 static void
1677 add_debug_begin_stmt (location_t loc)
1678 {
1679 /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721. */
1680 if (!MAY_HAVE_DEBUG_MARKER_STMTS || !building_stmt_list_p ())
1681 return;
1682
1683 tree stmt = build0 (DEBUG_BEGIN_STMT, void_type_node);
1684 SET_EXPR_LOCATION (stmt, loc);
1685 add_stmt (stmt);
1686 }
1687
1688 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
1689 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition
1690 is accepted; otherwise (old-style parameter declarations) only other
1691 declarations are accepted. If STATIC_ASSERT_OK is true, a static
1692 assertion is accepted; otherwise (old-style parameter declarations)
1693 it is not. If NESTED is true, we are inside a function or parsing
1694 old-style parameter declarations; any functions encountered are
1695 nested functions and declaration specifiers are required; otherwise
1696 we are at top level and functions are normal functions and
1697 declaration specifiers may be optional. If EMPTY_OK is true, empty
1698 declarations are OK (subject to all other constraints); otherwise
1699 (old-style parameter declarations) they are diagnosed. If
1700 START_ATTR_OK is true, the declaration specifiers may start with
1701 attributes; otherwise they may not.
1702 OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
1703 declaration when parsing an Objective-C foreach statement.
1704 FALLTHRU_ATTR_P is used to signal whether this function parsed
1705 "__attribute__((fallthrough));".
1706
1707 declaration:
1708 declaration-specifiers init-declarator-list[opt] ;
1709 static_assert-declaration
1710
1711 function-definition:
1712 declaration-specifiers[opt] declarator declaration-list[opt]
1713 compound-statement
1714
1715 declaration-list:
1716 declaration
1717 declaration-list declaration
1718
1719 init-declarator-list:
1720 init-declarator
1721 init-declarator-list , init-declarator
1722
1723 init-declarator:
1724 declarator simple-asm-expr[opt] gnu-attributes[opt]
1725 declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
1726
1727 GNU extensions:
1728
1729 nested-function-definition:
1730 declaration-specifiers declarator declaration-list[opt]
1731 compound-statement
1732
1733 attribute ;
1734
1735 Objective-C:
1736 gnu-attributes objc-class-definition
1737 gnu-attributes objc-category-definition
1738 gnu-attributes objc-protocol-definition
1739
1740 The simple-asm-expr and gnu-attributes are GNU extensions.
1741
1742 This function does not handle __extension__; that is handled in its
1743 callers. ??? Following the old parser, __extension__ may start
1744 external declarations, declarations in functions and declarations
1745 at the start of "for" loops, but not old-style parameter
1746 declarations.
1747
1748 C99 requires declaration specifiers in a function definition; the
1749 absence is diagnosed through the diagnosis of implicit int. In GNU
1750 C we also allow but diagnose declarations without declaration
1751 specifiers, but only at top level (elsewhere they conflict with
1752 other syntax).
1753
1754 In Objective-C, declarations of the looping variable in a foreach
1755 statement are exceptionally terminated by 'in' (for example, 'for
1756 (NSObject *object in array) { ... }').
1757
1758 OpenMP:
1759
1760 declaration:
1761 threadprivate-directive
1762
1763 GIMPLE:
1764
1765 gimple-function-definition:
1766 declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
1767 declaration-list[opt] compound-statement
1768
1769 rtl-function-definition:
1770 declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
1771 declaration-list[opt] compound-statement */
1772
1773 static void
1774 c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
1775 bool static_assert_ok, bool empty_ok,
1776 bool nested, bool start_attr_ok,
1777 tree *objc_foreach_object_declaration,
1778 vec<c_token> omp_declare_simd_clauses,
1779 struct oacc_routine_data *oacc_routine_data,
1780 bool *fallthru_attr_p)
1781 {
1782 struct c_declspecs *specs;
1783 tree prefix_attrs;
1784 tree all_prefix_attrs;
1785 bool diagnosed_no_specs = false;
1786 location_t here = c_parser_peek_token (parser)->location;
1787
1788 add_debug_begin_stmt (c_parser_peek_token (parser)->location);
1789
1790 if (static_assert_ok
1791 && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
1792 {
1793 c_parser_static_assert_declaration (parser);
1794 return;
1795 }
1796 specs = build_null_declspecs ();
1797
1798 /* Try to detect an unknown type name when we have "A B" or "A *B". */
1799 if (c_parser_peek_token (parser)->type == CPP_NAME
1800 && c_parser_peek_token (parser)->id_kind == C_ID_ID
1801 && (c_parser_peek_2nd_token (parser)->type == CPP_NAME
1802 || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
1803 && (!nested || !lookup_name (c_parser_peek_token (parser)->value)))
1804 {
1805 tree name = c_parser_peek_token (parser)->value;
1806
1807 /* Issue a warning about NAME being an unknown type name, perhaps
1808 with some kind of hint.
1809 If the user forgot a "struct" etc, suggest inserting
1810 it. Otherwise, attempt to look for misspellings. */
1811 gcc_rich_location richloc (here);
1812 if (tag_exists_p (RECORD_TYPE, name))
1813 {
1814 /* This is not C++ with its implicit typedef. */
1815 richloc.add_fixit_insert_before ("struct ");
1816 error_at (&richloc,
1817 "unknown type name %qE;"
1818 " use %<struct%> keyword to refer to the type",
1819 name);
1820 }
1821 else if (tag_exists_p (UNION_TYPE, name))
1822 {
1823 richloc.add_fixit_insert_before ("union ");
1824 error_at (&richloc,
1825 "unknown type name %qE;"
1826 " use %<union%> keyword to refer to the type",
1827 name);
1828 }
1829 else if (tag_exists_p (ENUMERAL_TYPE, name))
1830 {
1831 richloc.add_fixit_insert_before ("enum ");
1832 error_at (&richloc,
1833 "unknown type name %qE;"
1834 " use %<enum%> keyword to refer to the type",
1835 name);
1836 }
1837 else
1838 {
1839 auto_diagnostic_group d;
1840 name_hint hint = lookup_name_fuzzy (name, FUZZY_LOOKUP_TYPENAME,
1841 here);
1842 if (const char *suggestion = hint.suggestion ())
1843 {
1844 richloc.add_fixit_replace (suggestion);
1845 error_at (&richloc,
1846 "unknown type name %qE; did you mean %qs?",
1847 name, suggestion);
1848 }
1849 else
1850 error_at (here, "unknown type name %qE", name);
1851 }
1852
1853 /* Parse declspecs normally to get a correct pointer type, but avoid
1854 a further "fails to be a type name" error. Refuse nested functions
1855 since it is not how the user likely wants us to recover. */
1856 c_parser_peek_token (parser)->type = CPP_KEYWORD;
1857 c_parser_peek_token (parser)->keyword = RID_VOID;
1858 c_parser_peek_token (parser)->value = error_mark_node;
1859 fndef_ok = !nested;
1860 }
1861
1862 c_parser_declspecs (parser, specs, true, true, start_attr_ok,
1863 true, true, cla_nonabstract_decl);
1864 if (parser->error)
1865 {
1866 c_parser_skip_to_end_of_block_or_statement (parser);
1867 return;
1868 }
1869 if (nested && !specs->declspecs_seen_p)
1870 {
1871 c_parser_error (parser, "expected declaration specifiers");
1872 c_parser_skip_to_end_of_block_or_statement (parser);
1873 return;
1874 }
1875
1876 finish_declspecs (specs);
1877 bool auto_type_p = specs->typespec_word == cts_auto_type;
1878 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
1879 {
1880 if (auto_type_p)
1881 error_at (here, "%<__auto_type%> in empty declaration");
1882 else if (specs->typespec_kind == ctsk_none
1883 && attribute_fallthrough_p (specs->attrs))
1884 {
1885 if (fallthru_attr_p != NULL)
1886 *fallthru_attr_p = true;
1887 tree fn = build_call_expr_internal_loc (here, IFN_FALLTHROUGH,
1888 void_type_node, 0);
1889 add_stmt (fn);
1890 }
1891 else if (empty_ok)
1892 shadow_tag (specs);
1893 else
1894 {
1895 shadow_tag_warned (specs, 1);
1896 pedwarn (here, 0, "empty declaration");
1897 }
1898 c_parser_consume_token (parser);
1899 if (oacc_routine_data)
1900 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
1901 return;
1902 }
1903
1904 /* Provide better error recovery. Note that a type name here is usually
1905 better diagnosed as a redeclaration. */
1906 if (empty_ok
1907 && specs->typespec_kind == ctsk_tagdef
1908 && c_parser_next_token_starts_declspecs (parser)
1909 && !c_parser_next_token_is (parser, CPP_NAME))
1910 {
1911 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
1912 parser->error = false;
1913 shadow_tag_warned (specs, 1);
1914 return;
1915 }
1916 else if (c_dialect_objc () && !auto_type_p)
1917 {
1918 /* Prefix attributes are an error on method decls. */
1919 switch (c_parser_peek_token (parser)->type)
1920 {
1921 case CPP_PLUS:
1922 case CPP_MINUS:
1923 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
1924 return;
1925 if (specs->attrs)
1926 {
1927 warning_at (c_parser_peek_token (parser)->location,
1928 OPT_Wattributes,
1929 "prefix attributes are ignored for methods");
1930 specs->attrs = NULL_TREE;
1931 }
1932 if (fndef_ok)
1933 c_parser_objc_method_definition (parser);
1934 else
1935 c_parser_objc_methodproto (parser);
1936 return;
1937 break;
1938 default:
1939 break;
1940 }
1941 /* This is where we parse 'attributes @interface ...',
1942 'attributes @implementation ...', 'attributes @protocol ...'
1943 (where attributes could be, for example, __attribute__
1944 ((deprecated)).
1945 */
1946 switch (c_parser_peek_token (parser)->keyword)
1947 {
1948 case RID_AT_INTERFACE:
1949 {
1950 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
1951 return;
1952 c_parser_objc_class_definition (parser, specs->attrs);
1953 return;
1954 }
1955 break;
1956 case RID_AT_IMPLEMENTATION:
1957 {
1958 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
1959 return;
1960 if (specs->attrs)
1961 {
1962 warning_at (c_parser_peek_token (parser)->location,
1963 OPT_Wattributes,
1964 "prefix attributes are ignored for implementations");
1965 specs->attrs = NULL_TREE;
1966 }
1967 c_parser_objc_class_definition (parser, NULL_TREE);
1968 return;
1969 }
1970 break;
1971 case RID_AT_PROTOCOL:
1972 {
1973 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
1974 return;
1975 c_parser_objc_protocol_definition (parser, specs->attrs);
1976 return;
1977 }
1978 break;
1979 case RID_AT_ALIAS:
1980 case RID_AT_CLASS:
1981 case RID_AT_END:
1982 case RID_AT_PROPERTY:
1983 if (specs->attrs)
1984 {
1985 c_parser_error (parser, "unexpected attribute");
1986 specs->attrs = NULL;
1987 }
1988 break;
1989 default:
1990 break;
1991 }
1992 }
1993 else if (attribute_fallthrough_p (specs->attrs))
1994 warning_at (here, OPT_Wattributes,
1995 "%<fallthrough%> attribute not followed by %<;%>");
1996
1997 pending_xref_error ();
1998 prefix_attrs = specs->attrs;
1999 all_prefix_attrs = prefix_attrs;
2000 specs->attrs = NULL_TREE;
2001 while (true)
2002 {
2003 struct c_declarator *declarator;
2004 bool dummy = false;
2005 timevar_id_t tv;
2006 tree fnbody = NULL_TREE;
2007 /* Declaring either one or more declarators (in which case we
2008 should diagnose if there were no declaration specifiers) or a
2009 function definition (in which case the diagnostic for
2010 implicit int suffices). */
2011 declarator = c_parser_declarator (parser,
2012 specs->typespec_kind != ctsk_none,
2013 C_DTR_NORMAL, &dummy);
2014 if (declarator == NULL)
2015 {
2016 if (omp_declare_simd_clauses.exists ())
2017 c_finish_omp_declare_simd (parser, NULL_TREE, NULL_TREE,
2018 omp_declare_simd_clauses);
2019 if (oacc_routine_data)
2020 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
2021 c_parser_skip_to_end_of_block_or_statement (parser);
2022 return;
2023 }
2024 if (auto_type_p && declarator->kind != cdk_id)
2025 {
2026 error_at (here,
2027 "%<__auto_type%> requires a plain identifier"
2028 " as declarator");
2029 c_parser_skip_to_end_of_block_or_statement (parser);
2030 return;
2031 }
2032 if (c_parser_next_token_is (parser, CPP_EQ)
2033 || c_parser_next_token_is (parser, CPP_COMMA)
2034 || c_parser_next_token_is (parser, CPP_SEMICOLON)
2035 || c_parser_next_token_is_keyword (parser, RID_ASM)
2036 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)
2037 || c_parser_next_token_is_keyword (parser, RID_IN))
2038 {
2039 tree asm_name = NULL_TREE;
2040 tree postfix_attrs = NULL_TREE;
2041 if (!diagnosed_no_specs && !specs->declspecs_seen_p)
2042 {
2043 diagnosed_no_specs = true;
2044 pedwarn (here, 0, "data definition has no type or storage class");
2045 }
2046 /* Having seen a data definition, there cannot now be a
2047 function definition. */
2048 fndef_ok = false;
2049 if (c_parser_next_token_is_keyword (parser, RID_ASM))
2050 asm_name = c_parser_simple_asm_expr (parser);
2051 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2052 {
2053 postfix_attrs = c_parser_gnu_attributes (parser);
2054 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
2055 {
2056 /* This means there is an attribute specifier after
2057 the declarator in a function definition. Provide
2058 some more information for the user. */
2059 error_at (here, "attributes should be specified before the "
2060 "declarator in a function definition");
2061 c_parser_skip_to_end_of_block_or_statement (parser);
2062 return;
2063 }
2064 }
2065 if (c_parser_next_token_is (parser, CPP_EQ))
2066 {
2067 tree d;
2068 struct c_expr init;
2069 location_t init_loc;
2070 c_parser_consume_token (parser);
2071 if (auto_type_p)
2072 {
2073 init_loc = c_parser_peek_token (parser)->location;
2074 rich_location richloc (line_table, init_loc);
2075 start_init (NULL_TREE, asm_name, global_bindings_p (), &richloc);
2076 /* A parameter is initialized, which is invalid. Don't
2077 attempt to instrument the initializer. */
2078 int flag_sanitize_save = flag_sanitize;
2079 if (nested && !empty_ok)
2080 flag_sanitize = 0;
2081 init = c_parser_expr_no_commas (parser, NULL);
2082 flag_sanitize = flag_sanitize_save;
2083 if (TREE_CODE (init.value) == COMPONENT_REF
2084 && DECL_C_BIT_FIELD (TREE_OPERAND (init.value, 1)))
2085 error_at (here,
2086 "%<__auto_type%> used with a bit-field"
2087 " initializer");
2088 init = convert_lvalue_to_rvalue (init_loc, init, true, true);
2089 tree init_type = TREE_TYPE (init.value);
2090 /* As with typeof, remove all qualifiers from atomic types. */
2091 if (init_type != error_mark_node && TYPE_ATOMIC (init_type))
2092 init_type
2093 = c_build_qualified_type (init_type, TYPE_UNQUALIFIED);
2094 bool vm_type = variably_modified_type_p (init_type,
2095 NULL_TREE);
2096 if (vm_type)
2097 init.value = save_expr (init.value);
2098 finish_init ();
2099 specs->typespec_kind = ctsk_typeof;
2100 specs->locations[cdw_typedef] = init_loc;
2101 specs->typedef_p = true;
2102 specs->type = init_type;
2103 if (vm_type)
2104 {
2105 bool maybe_const = true;
2106 tree type_expr = c_fully_fold (init.value, false,
2107 &maybe_const);
2108 specs->expr_const_operands &= maybe_const;
2109 if (specs->expr)
2110 specs->expr = build2 (COMPOUND_EXPR,
2111 TREE_TYPE (type_expr),
2112 specs->expr, type_expr);
2113 else
2114 specs->expr = type_expr;
2115 }
2116 d = start_decl (declarator, specs, true,
2117 chainon (postfix_attrs, all_prefix_attrs));
2118 if (!d)
2119 d = error_mark_node;
2120 if (omp_declare_simd_clauses.exists ())
2121 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2122 omp_declare_simd_clauses);
2123 }
2124 else
2125 {
2126 /* The declaration of the variable is in effect while
2127 its initializer is parsed. */
2128 d = start_decl (declarator, specs, true,
2129 chainon (postfix_attrs, all_prefix_attrs));
2130 if (!d)
2131 d = error_mark_node;
2132 if (omp_declare_simd_clauses.exists ())
2133 c_finish_omp_declare_simd (parser, d, NULL_TREE,
2134 omp_declare_simd_clauses);
2135 init_loc = c_parser_peek_token (parser)->location;
2136 rich_location richloc (line_table, init_loc);
2137 start_init (d, asm_name, global_bindings_p (), &richloc);
2138 /* A parameter is initialized, which is invalid. Don't
2139 attempt to instrument the initializer. */
2140 int flag_sanitize_save = flag_sanitize;
2141 if (TREE_CODE (d) == PARM_DECL)
2142 flag_sanitize = 0;
2143 init = c_parser_initializer (parser);
2144 flag_sanitize = flag_sanitize_save;
2145 finish_init ();
2146 }
2147 if (oacc_routine_data)
2148 c_finish_oacc_routine (oacc_routine_data, d, false);
2149 if (d != error_mark_node)
2150 {
2151 maybe_warn_string_init (init_loc, TREE_TYPE (d), init);
2152 finish_decl (d, init_loc, init.value,
2153 init.original_type, asm_name);
2154 }
2155 }
2156 else
2157 {
2158 if (auto_type_p)
2159 {
2160 error_at (here,
2161 "%<__auto_type%> requires an initialized "
2162 "data declaration");
2163 c_parser_skip_to_end_of_block_or_statement (parser);
2164 return;
2165 }
2166 tree d = start_decl (declarator, specs, false,
2167 chainon (postfix_attrs,
2168 all_prefix_attrs));
2169 if (d
2170 && TREE_CODE (d) == FUNCTION_DECL
2171 && DECL_ARGUMENTS (d) == NULL_TREE
2172 && DECL_INITIAL (d) == NULL_TREE)
2173 {
2174 /* Find the innermost declarator that is neither cdk_id
2175 nor cdk_attrs. */
2176 const struct c_declarator *decl = declarator;
2177 const struct c_declarator *last_non_id_attrs = NULL;
2178
2179 while (decl)
2180 switch (decl->kind)
2181 {
2182 case cdk_array:
2183 case cdk_function:
2184 case cdk_pointer:
2185 last_non_id_attrs = decl;
2186 decl = decl->declarator;
2187 break;
2188
2189 case cdk_attrs:
2190 decl = decl->declarator;
2191 break;
2192
2193 case cdk_id:
2194 decl = 0;
2195 break;
2196
2197 default:
2198 gcc_unreachable ();
2199 }
2200
2201 /* If it exists and is cdk_function, use its parameters. */
2202 if (last_non_id_attrs
2203 && last_non_id_attrs->kind == cdk_function)
2204 DECL_ARGUMENTS (d) = last_non_id_attrs->u.arg_info->parms;
2205 }
2206 if (omp_declare_simd_clauses.exists ())
2207 {
2208 tree parms = NULL_TREE;
2209 if (d && TREE_CODE (d) == FUNCTION_DECL)
2210 {
2211 struct c_declarator *ce = declarator;
2212 while (ce != NULL)
2213 if (ce->kind == cdk_function)
2214 {
2215 parms = ce->u.arg_info->parms;
2216 break;
2217 }
2218 else
2219 ce = ce->declarator;
2220 }
2221 if (parms)
2222 temp_store_parm_decls (d, parms);
2223 c_finish_omp_declare_simd (parser, d, parms,
2224 omp_declare_simd_clauses);
2225 if (parms)
2226 temp_pop_parm_decls ();
2227 }
2228 if (oacc_routine_data)
2229 c_finish_oacc_routine (oacc_routine_data, d, false);
2230 if (d)
2231 finish_decl (d, UNKNOWN_LOCATION, NULL_TREE,
2232 NULL_TREE, asm_name);
2233
2234 if (c_parser_next_token_is_keyword (parser, RID_IN))
2235 {
2236 if (d)
2237 *objc_foreach_object_declaration = d;
2238 else
2239 *objc_foreach_object_declaration = error_mark_node;
2240 }
2241 }
2242 if (c_parser_next_token_is (parser, CPP_COMMA))
2243 {
2244 if (auto_type_p)
2245 {
2246 error_at (here,
2247 "%<__auto_type%> may only be used with"
2248 " a single declarator");
2249 c_parser_skip_to_end_of_block_or_statement (parser);
2250 return;
2251 }
2252 c_parser_consume_token (parser);
2253 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
2254 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
2255 prefix_attrs);
2256 else
2257 all_prefix_attrs = prefix_attrs;
2258 continue;
2259 }
2260 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
2261 {
2262 c_parser_consume_token (parser);
2263 return;
2264 }
2265 else if (c_parser_next_token_is_keyword (parser, RID_IN))
2266 {
2267 /* This can only happen in Objective-C: we found the
2268 'in' that terminates the declaration inside an
2269 Objective-C foreach statement. Do not consume the
2270 token, so that the caller can use it to determine
2271 that this indeed is a foreach context. */
2272 return;
2273 }
2274 else
2275 {
2276 c_parser_error (parser, "expected %<,%> or %<;%>");
2277 c_parser_skip_to_end_of_block_or_statement (parser);
2278 return;
2279 }
2280 }
2281 else if (auto_type_p)
2282 {
2283 error_at (here,
2284 "%<__auto_type%> requires an initialized data declaration");
2285 c_parser_skip_to_end_of_block_or_statement (parser);
2286 return;
2287 }
2288 else if (!fndef_ok)
2289 {
2290 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, "
2291 "%<asm%> or %<__attribute__%>");
2292 c_parser_skip_to_end_of_block_or_statement (parser);
2293 return;
2294 }
2295 /* Function definition (nested or otherwise). */
2296 if (nested)
2297 {
2298 pedwarn (here, OPT_Wpedantic, "ISO C forbids nested functions");
2299 c_push_function_context ();
2300 }
2301 if (!start_function (specs, declarator, all_prefix_attrs))
2302 {
2303 /* At this point we've consumed:
2304 declaration-specifiers declarator
2305 and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
2306 RID_ASM, RID_ATTRIBUTE, or RID_IN,
2307 but the
2308 declaration-specifiers declarator
2309 aren't grokkable as a function definition, so we have
2310 an error. */
2311 gcc_assert (!c_parser_next_token_is (parser, CPP_SEMICOLON));
2312 if (c_parser_next_token_starts_declspecs (parser))
2313 {
2314 /* If we have
2315 declaration-specifiers declarator decl-specs
2316 then assume we have a missing semicolon, which would
2317 give us:
2318 declaration-specifiers declarator decl-specs
2319 ^
2320 ;
2321 <~~~~~~~~~ declaration ~~~~~~~~~~>
2322 Use c_parser_require to get an error with a fix-it hint. */
2323 c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>");
2324 parser->error = false;
2325 }
2326 else
2327 {
2328 /* This can appear in many cases looking nothing like a
2329 function definition, so we don't give a more specific
2330 error suggesting there was one. */
2331 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
2332 "or %<__attribute__%>");
2333 }
2334 if (nested)
2335 c_pop_function_context ();
2336 break;
2337 }
2338
2339 if (DECL_DECLARED_INLINE_P (current_function_decl))
2340 tv = TV_PARSE_INLINE;
2341 else
2342 tv = TV_PARSE_FUNC;
2343 auto_timevar at (g_timer, tv);
2344
2345 /* Parse old-style parameter declarations. ??? Attributes are
2346 not allowed to start declaration specifiers here because of a
2347 syntax conflict between a function declaration with attribute
2348 suffix and a function definition with an attribute prefix on
2349 first old-style parameter declaration. Following the old
2350 parser, they are not accepted on subsequent old-style
2351 parameter declarations either. However, there is no
2352 ambiguity after the first declaration, nor indeed on the
2353 first as long as we don't allow postfix attributes after a
2354 declarator with a nonempty identifier list in a definition;
2355 and postfix attributes have never been accepted here in
2356 function definitions either. */
2357 while (c_parser_next_token_is_not (parser, CPP_EOF)
2358 && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE))
2359 c_parser_declaration_or_fndef (parser, false, false, false,
2360 true, false, NULL, vNULL);
2361 store_parm_decls ();
2362 if (omp_declare_simd_clauses.exists ())
2363 c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE,
2364 omp_declare_simd_clauses);
2365 if (oacc_routine_data)
2366 c_finish_oacc_routine (oacc_routine_data, current_function_decl, true);
2367 DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
2368 = c_parser_peek_token (parser)->location;
2369
2370 /* If the definition was marked with __RTL, use the RTL parser now,
2371 consuming the function body. */
2372 if (specs->declspec_il == cdil_rtl)
2373 {
2374 c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass);
2375
2376 /* Normally, store_parm_decls sets next_is_function_body,
2377 anticipating a function body. We need a push_scope/pop_scope
2378 pair to flush out this state, or subsequent function parsing
2379 will go wrong. */
2380 push_scope ();
2381 pop_scope ();
2382
2383 finish_function ();
2384 return;
2385 }
2386 /* If the definition was marked with __GIMPLE then parse the
2387 function body as GIMPLE. */
2388 else if (specs->declspec_il != cdil_none)
2389 {
2390 bool saved = in_late_binary_op;
2391 in_late_binary_op = true;
2392 c_parser_parse_gimple_body (parser, specs->gimple_or_rtl_pass,
2393 specs->declspec_il,
2394 specs->entry_bb_count);
2395 in_late_binary_op = saved;
2396 }
2397 else
2398 fnbody = c_parser_compound_statement (parser);
2399 tree fndecl = current_function_decl;
2400 if (nested)
2401 {
2402 tree decl = current_function_decl;
2403 /* Mark nested functions as needing static-chain initially.
2404 lower_nested_functions will recompute it but the
2405 DECL_STATIC_CHAIN flag is also used before that happens,
2406 by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
2407 DECL_STATIC_CHAIN (decl) = 1;
2408 add_stmt (fnbody);
2409 finish_function ();
2410 c_pop_function_context ();
2411 add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));
2412 }
2413 else
2414 {
2415 if (fnbody)
2416 add_stmt (fnbody);
2417 finish_function ();
2418 }
2419 /* Get rid of the empty stmt list for GIMPLE/RTL. */
2420 if (specs->declspec_il != cdil_none)
2421 DECL_SAVED_TREE (fndecl) = NULL_TREE;
2422
2423 break;
2424 }
2425 }
2426
2427 /* Parse an asm-definition (asm() outside a function body). This is a
2428 GNU extension.
2429
2430 asm-definition:
2431 simple-asm-expr ;
2432 */
2433
2434 static void
2435 c_parser_asm_definition (c_parser *parser)
2436 {
2437 tree asm_str = c_parser_simple_asm_expr (parser);
2438 if (asm_str)
2439 symtab->finalize_toplevel_asm (asm_str);
2440 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
2441 }
2442
2443 /* Parse a static assertion (C11 6.7.10).
2444
2445 static_assert-declaration:
2446 static_assert-declaration-no-semi ;
2447 */
2448
2449 static void
2450 c_parser_static_assert_declaration (c_parser *parser)
2451 {
2452 c_parser_static_assert_declaration_no_semi (parser);
2453 if (parser->error
2454 || !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
2455 c_parser_skip_to_end_of_block_or_statement (parser);
2456 }
2457
2458 /* Parse a static assertion (C11 6.7.10), without the trailing
2459 semicolon.
2460
2461 static_assert-declaration-no-semi:
2462 _Static_assert ( constant-expression , string-literal )
2463
2464 C2X:
2465 static_assert-declaration-no-semi:
2466 _Static_assert ( constant-expression )
2467 */
2468
2469 static void
2470 c_parser_static_assert_declaration_no_semi (c_parser *parser)
2471 {
2472 location_t assert_loc, value_loc;
2473 tree value;
2474 tree string = NULL_TREE;
2475
2476 gcc_assert (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT));
2477 assert_loc = c_parser_peek_token (parser)->location;
2478 if (flag_isoc99)
2479 pedwarn_c99 (assert_loc, OPT_Wpedantic,
2480 "ISO C99 does not support %<_Static_assert%>");
2481 else
2482 pedwarn_c99 (assert_loc, OPT_Wpedantic,
2483 "ISO C90 does not support %<_Static_assert%>");
2484 c_parser_consume_token (parser);
2485 matching_parens parens;
2486 if (!parens.require_open (parser))
2487 return;
2488 location_t value_tok_loc = c_parser_peek_token (parser)->location;
2489 value = c_parser_expr_no_commas (parser, NULL).value;
2490 value_loc = EXPR_LOC_OR_LOC (value, value_tok_loc);
2491 if (c_parser_next_token_is (parser, CPP_COMMA))
2492 {
2493 c_parser_consume_token (parser);
2494 switch (c_parser_peek_token (parser)->type)
2495 {
2496 case CPP_STRING:
2497 case CPP_STRING16:
2498 case CPP_STRING32:
2499 case CPP_WSTRING:
2500 case CPP_UTF8STRING:
2501 string = c_parser_string_literal (parser, false, true).value;
2502 break;
2503 default:
2504 c_parser_error (parser, "expected string literal");
2505 return;
2506 }
2507 }
2508 else if (flag_isoc11)
2509 /* If pedantic for pre-C11, the use of _Static_assert itself will
2510 have been diagnosed, so do not also diagnose the use of this
2511 new C2X feature of _Static_assert. */
2512 pedwarn_c11 (assert_loc, OPT_Wpedantic,
2513 "ISO C11 does not support omitting the string in "
2514 "%<_Static_assert%>");
2515 parens.require_close (parser);
2516
2517 if (!INTEGRAL_TYPE_P (TREE_TYPE (value)))
2518 {
2519 error_at (value_loc, "expression in static assertion is not an integer");
2520 return;
2521 }
2522 if (TREE_CODE (value) != INTEGER_CST)
2523 {
2524 value = c_fully_fold (value, false, NULL);
2525 /* Strip no-op conversions. */
2526 STRIP_TYPE_NOPS (value);
2527 if (TREE_CODE (value) == INTEGER_CST)
2528 pedwarn (value_loc, OPT_Wpedantic, "expression in static assertion "
2529 "is not an integer constant expression");
2530 }
2531 if (TREE_CODE (value) != INTEGER_CST)
2532 {
2533 error_at (value_loc, "expression in static assertion is not constant");
2534 return;
2535 }
2536 constant_expression_warning (value);
2537 if (integer_zerop (value))
2538 {
2539 if (string)
2540 error_at (assert_loc, "static assertion failed: %E", string);
2541 else
2542 error_at (assert_loc, "static assertion failed");
2543 }
2544 }
2545
2546 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
2547 6.7, C11 6.7), adding them to SPECS (which may already include some).
2548 Storage class specifiers are accepted iff SCSPEC_OK; type
2549 specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
2550 accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start
2551 iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK.
2552
2553 declaration-specifiers:
2554 storage-class-specifier declaration-specifiers[opt]
2555 type-specifier declaration-specifiers[opt]
2556 type-qualifier declaration-specifiers[opt]
2557 function-specifier declaration-specifiers[opt]
2558 alignment-specifier declaration-specifiers[opt]
2559
2560 Function specifiers (inline) are from C99, and are currently
2561 handled as storage class specifiers, as is __thread. Alignment
2562 specifiers are from C11.
2563
2564 C90 6.5.1, C99 6.7.1, C11 6.7.1:
2565 storage-class-specifier:
2566 typedef
2567 extern
2568 static
2569 auto
2570 register
2571 _Thread_local
2572
2573 (_Thread_local is new in C11.)
2574
2575 C99 6.7.4, C11 6.7.4:
2576 function-specifier:
2577 inline
2578 _Noreturn
2579
2580 (_Noreturn is new in C11.)
2581
2582 C90 6.5.2, C99 6.7.2, C11 6.7.2:
2583 type-specifier:
2584 void
2585 char
2586 short
2587 int
2588 long
2589 float
2590 double
2591 signed
2592 unsigned
2593 _Bool
2594 _Complex
2595 [_Imaginary removed in C99 TC2]
2596 struct-or-union-specifier
2597 enum-specifier
2598 typedef-name
2599 atomic-type-specifier
2600
2601 (_Bool and _Complex are new in C99.)
2602 (atomic-type-specifier is new in C11.)
2603
2604 C90 6.5.3, C99 6.7.3, C11 6.7.3:
2605
2606 type-qualifier:
2607 const
2608 restrict
2609 volatile
2610 address-space-qualifier
2611 _Atomic
2612
2613 (restrict is new in C99.)
2614 (_Atomic is new in C11.)
2615
2616 GNU extensions:
2617
2618 declaration-specifiers:
2619 gnu-attributes declaration-specifiers[opt]
2620
2621 type-qualifier:
2622 address-space
2623
2624 address-space:
2625 identifier recognized by the target
2626
2627 storage-class-specifier:
2628 __thread
2629
2630 type-specifier:
2631 typeof-specifier
2632 __auto_type
2633 __intN
2634 _Decimal32
2635 _Decimal64
2636 _Decimal128
2637 _Fract
2638 _Accum
2639 _Sat
2640
2641 (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
2642 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
2643
2644 atomic-type-specifier
2645 _Atomic ( type-name )
2646
2647 Objective-C:
2648
2649 type-specifier:
2650 class-name objc-protocol-refs[opt]
2651 typedef-name objc-protocol-refs
2652 objc-protocol-refs
2653 */
2654
2655 void
2656 c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
2657 bool scspec_ok, bool typespec_ok, bool start_attr_ok,
2658 bool alignspec_ok, bool auto_type_ok,
2659 enum c_lookahead_kind la)
2660 {
2661 bool attrs_ok = start_attr_ok;
2662 bool seen_type = specs->typespec_kind != ctsk_none;
2663
2664 if (!typespec_ok)
2665 gcc_assert (la == cla_prefer_id);
2666
2667 while (c_parser_next_token_is (parser, CPP_NAME)
2668 || c_parser_next_token_is (parser, CPP_KEYWORD)
2669 || (c_dialect_objc () && c_parser_next_token_is (parser, CPP_LESS)))
2670 {
2671 struct c_typespec t;
2672 tree attrs;
2673 tree align;
2674 location_t loc = c_parser_peek_token (parser)->location;
2675
2676 /* If we cannot accept a type, exit if the next token must start
2677 one. Also, if we already have seen a tagged definition,
2678 a typename would be an error anyway and likely the user
2679 has simply forgotten a semicolon, so we exit. */
2680 if ((!typespec_ok || specs->typespec_kind == ctsk_tagdef)
2681 && c_parser_next_tokens_start_typename (parser, la)
2682 && !c_parser_next_token_is_qualifier (parser)
2683 && !c_parser_next_token_is_keyword (parser, RID_ALIGNAS))
2684 break;
2685
2686 if (c_parser_next_token_is (parser, CPP_NAME))
2687 {
2688 c_token *name_token = c_parser_peek_token (parser);
2689 tree value = name_token->value;
2690 c_id_kind kind = name_token->id_kind;
2691
2692 if (kind == C_ID_ADDRSPACE)
2693 {
2694 addr_space_t as
2695 = name_token->keyword - RID_FIRST_ADDR_SPACE;
2696 declspecs_add_addrspace (name_token->location, specs, as);
2697 c_parser_consume_token (parser);
2698 attrs_ok = true;
2699 continue;
2700 }
2701
2702 gcc_assert (!c_parser_next_token_is_qualifier (parser));
2703
2704 /* If we cannot accept a type, and the next token must start one,
2705 exit. Do the same if we already have seen a tagged definition,
2706 since it would be an error anyway and likely the user has simply
2707 forgotten a semicolon. */
2708 if (seen_type || !c_parser_next_tokens_start_typename (parser, la))
2709 break;
2710
2711 /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
2712 a C_ID_CLASSNAME. */
2713 c_parser_consume_token (parser);
2714 seen_type = true;
2715 attrs_ok = true;
2716 if (kind == C_ID_ID)
2717 {
2718 error_at (loc, "unknown type name %qE", value);
2719 t.kind = ctsk_typedef;
2720 t.spec = error_mark_node;
2721 }
2722 else if (kind == C_ID_TYPENAME
2723 && (!c_dialect_objc ()
2724 || c_parser_next_token_is_not (parser, CPP_LESS)))
2725 {
2726 t.kind = ctsk_typedef;
2727 /* For a typedef name, record the meaning, not the name.
2728 In case of 'foo foo, bar;'. */
2729 t.spec = lookup_name (value);
2730 }
2731 else
2732 {
2733 tree proto = NULL_TREE;
2734 gcc_assert (c_dialect_objc ());
2735 t.kind = ctsk_objc;
2736 if (c_parser_next_token_is (parser, CPP_LESS))
2737 proto = c_parser_objc_protocol_refs (parser);
2738 t.spec = objc_get_protocol_qualified_type (value, proto);
2739 }
2740 t.expr = NULL_TREE;
2741 t.expr_const_operands = true;
2742 declspecs_add_type (name_token->location, specs, t);
2743 continue;
2744 }
2745 if (c_parser_next_token_is (parser, CPP_LESS))
2746 {
2747 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
2748 nisse@lysator.liu.se. */
2749 tree proto;
2750 gcc_assert (c_dialect_objc ());
2751 if (!typespec_ok || seen_type)
2752 break;
2753 proto = c_parser_objc_protocol_refs (parser);
2754 t.kind = ctsk_objc;
2755 t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto);
2756 t.expr = NULL_TREE;
2757 t.expr_const_operands = true;
2758 declspecs_add_type (loc, specs, t);
2759 continue;
2760 }
2761 gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD));
2762 switch (c_parser_peek_token (parser)->keyword)
2763 {
2764 case RID_STATIC:
2765 case RID_EXTERN:
2766 case RID_REGISTER:
2767 case RID_TYPEDEF:
2768 case RID_INLINE:
2769 case RID_NORETURN:
2770 case RID_AUTO:
2771 case RID_THREAD:
2772 if (!scspec_ok)
2773 goto out;
2774 attrs_ok = true;
2775 /* TODO: Distinguish between function specifiers (inline, noreturn)
2776 and storage class specifiers, either here or in
2777 declspecs_add_scspec. */
2778 declspecs_add_scspec (loc, specs,
2779 c_parser_peek_token (parser)->value);
2780 c_parser_consume_token (parser);
2781 break;
2782 case RID_AUTO_TYPE:
2783 if (!auto_type_ok)
2784 goto out;
2785 /* Fall through. */
2786 case RID_UNSIGNED:
2787 case RID_LONG:
2788 case RID_SHORT:
2789 case RID_SIGNED:
2790 case RID_COMPLEX:
2791 case RID_INT:
2792 case RID_CHAR:
2793 case RID_FLOAT:
2794 case RID_DOUBLE:
2795 case RID_VOID:
2796 case RID_DFLOAT32:
2797 case RID_DFLOAT64:
2798 case RID_DFLOAT128:
2799 CASE_RID_FLOATN_NX:
2800 case RID_BOOL:
2801 case RID_FRACT:
2802 case RID_ACCUM:
2803 case RID_SAT:
2804 case RID_INT_N_0:
2805 case RID_INT_N_1:
2806 case RID_INT_N_2:
2807 case RID_INT_N_3:
2808 if (!typespec_ok)
2809 goto out;
2810 attrs_ok = true;
2811 seen_type = true;
2812 if (c_dialect_objc ())
2813 parser->objc_need_raw_identifier = true;
2814 t.kind = ctsk_resword;
2815 t.spec = c_parser_peek_token (parser)->value;
2816 t.expr = NULL_TREE;
2817 t.expr_const_operands = true;
2818 declspecs_add_type (loc, specs, t);
2819 c_parser_consume_token (parser);
2820 break;
2821 case RID_ENUM:
2822 if (!typespec_ok)
2823 goto out;
2824 attrs_ok = true;
2825 seen_type = true;
2826 t = c_parser_enum_specifier (parser);
2827 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
2828 declspecs_add_type (loc, specs, t);
2829 break;
2830 case RID_STRUCT:
2831 case RID_UNION:
2832 if (!typespec_ok)
2833 goto out;
2834 attrs_ok = true;
2835 seen_type = true;
2836 t = c_parser_struct_or_union_specifier (parser);
2837 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
2838 declspecs_add_type (loc, specs, t);
2839 break;
2840 case RID_TYPEOF:
2841 /* ??? The old parser rejected typeof after other type
2842 specifiers, but is a syntax error the best way of
2843 handling this? */
2844 if (!typespec_ok || seen_type)
2845 goto out;
2846 attrs_ok = true;
2847 seen_type = true;
2848 t = c_parser_typeof_specifier (parser);
2849 declspecs_add_type (loc, specs, t);
2850 break;
2851 case RID_ATOMIC:
2852 /* C parser handling of Objective-C constructs needs
2853 checking for correct lvalue-to-rvalue conversions, and
2854 the code in build_modify_expr handling various
2855 Objective-C cases, and that in build_unary_op handling
2856 Objective-C cases for increment / decrement, also needs
2857 updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
2858 and objc_types_are_equivalent may also need updates. */
2859 if (c_dialect_objc ())
2860 sorry ("%<_Atomic%> in Objective-C");
2861 if (flag_isoc99)
2862 pedwarn_c99 (loc, OPT_Wpedantic,
2863 "ISO C99 does not support the %<_Atomic%> qualifier");
2864 else
2865 pedwarn_c99 (loc, OPT_Wpedantic,
2866 "ISO C90 does not support the %<_Atomic%> qualifier");
2867 attrs_ok = true;
2868 tree value;
2869 value = c_parser_peek_token (parser)->value;
2870 c_parser_consume_token (parser);
2871 if (typespec_ok && c_parser_next_token_is (parser, CPP_OPEN_PAREN))
2872 {
2873 /* _Atomic ( type-name ). */
2874 seen_type = true;
2875 c_parser_consume_token (parser);
2876 struct c_type_name *type = c_parser_type_name (parser);
2877 t.kind = ctsk_typeof;
2878 t.spec = error_mark_node;
2879 t.expr = NULL_TREE;
2880 t.expr_const_operands = true;
2881 if (type != NULL)
2882 t.spec = groktypename (type, &t.expr,
2883 &t.expr_const_operands);
2884 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
2885 "expected %<)%>");
2886 if (t.spec != error_mark_node)
2887 {
2888 if (TREE_CODE (t.spec) == ARRAY_TYPE)
2889 error_at (loc, "%<_Atomic%>-qualified array type");
2890 else if (TREE_CODE (t.spec) == FUNCTION_TYPE)
2891 error_at (loc, "%<_Atomic%>-qualified function type");
2892 else if (TYPE_QUALS (t.spec) != TYPE_UNQUALIFIED)
2893 error_at (loc, "%<_Atomic%> applied to a qualified type");
2894 else
2895 t.spec = c_build_qualified_type (t.spec, TYPE_QUAL_ATOMIC);
2896 }
2897 declspecs_add_type (loc, specs, t);
2898 }
2899 else
2900 declspecs_add_qual (loc, specs, value);
2901 break;
2902 case RID_CONST:
2903 case RID_VOLATILE:
2904 case RID_RESTRICT:
2905 attrs_ok = true;
2906 declspecs_add_qual (loc, specs, c_parser_peek_token (parser)->value);
2907 c_parser_consume_token (parser);
2908 break;
2909 case RID_ATTRIBUTE:
2910 if (!attrs_ok)
2911 goto out;
2912 attrs = c_parser_gnu_attributes (parser);
2913 declspecs_add_attrs (loc, specs, attrs);
2914 break;
2915 case RID_ALIGNAS:
2916 if (!alignspec_ok)
2917 goto out;
2918 align = c_parser_alignas_specifier (parser);
2919 declspecs_add_alignas (loc, specs, align);
2920 break;
2921 case RID_GIMPLE:
2922 if (! flag_gimple)
2923 error_at (loc, "%<__GIMPLE%> only valid with %<-fgimple%>");
2924 c_parser_consume_token (parser);
2925 specs->declspec_il = cdil_gimple;
2926 specs->locations[cdw_gimple] = loc;
2927 c_parser_gimple_or_rtl_pass_list (parser, specs);
2928 break;
2929 case RID_RTL:
2930 c_parser_consume_token (parser);
2931 specs->declspec_il = cdil_rtl;
2932 specs->locations[cdw_rtl] = loc;
2933 c_parser_gimple_or_rtl_pass_list (parser, specs);
2934 break;
2935 default:
2936 goto out;
2937 }
2938 }
2939 out: ;
2940 }
2941
2942 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
2943
2944 enum-specifier:
2945 enum gnu-attributes[opt] identifier[opt] { enumerator-list }
2946 gnu-attributes[opt]
2947 enum gnu-attributes[opt] identifier[opt] { enumerator-list , }
2948 gnu-attributes[opt]
2949 enum gnu-attributes[opt] identifier
2950
2951 The form with trailing comma is new in C99. The forms with
2952 gnu-attributes are GNU extensions. In GNU C, we accept any expression
2953 without commas in the syntax (assignment expressions, not just
2954 conditional expressions); assignment expressions will be diagnosed
2955 as non-constant.
2956
2957 enumerator-list:
2958 enumerator
2959 enumerator-list , enumerator
2960
2961 enumerator:
2962 enumeration-constant
2963 enumeration-constant = constant-expression
2964
2965 GNU Extensions:
2966
2967 enumerator:
2968 enumeration-constant gnu-attributes[opt]
2969 enumeration-constant gnu-attributes[opt] = constant-expression
2970
2971 */
2972
2973 static struct c_typespec
2974 c_parser_enum_specifier (c_parser *parser)
2975 {
2976 struct c_typespec ret;
2977 tree attrs;
2978 tree ident = NULL_TREE;
2979 location_t enum_loc;
2980 location_t ident_loc = UNKNOWN_LOCATION; /* Quiet warning. */
2981 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ENUM));
2982 c_parser_consume_token (parser);
2983 attrs = c_parser_gnu_attributes (parser);
2984 enum_loc = c_parser_peek_token (parser)->location;
2985 /* Set the location in case we create a decl now. */
2986 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
2987 if (c_parser_next_token_is (parser, CPP_NAME))
2988 {
2989 ident = c_parser_peek_token (parser)->value;
2990 ident_loc = c_parser_peek_token (parser)->location;
2991 enum_loc = ident_loc;
2992 c_parser_consume_token (parser);
2993 }
2994 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
2995 {
2996 /* Parse an enum definition. */
2997 struct c_enum_contents the_enum;
2998 tree type;
2999 tree postfix_attrs;
3000 /* We chain the enumerators in reverse order, then put them in
3001 forward order at the end. */
3002 tree values;
3003 timevar_push (TV_PARSE_ENUM);
3004 type = start_enum (enum_loc, &the_enum, ident);
3005 values = NULL_TREE;
3006 c_parser_consume_token (parser);
3007 while (true)
3008 {
3009 tree enum_id;
3010 tree enum_value;
3011 tree enum_decl;
3012 bool seen_comma;
3013 c_token *token;
3014 location_t comma_loc = UNKNOWN_LOCATION; /* Quiet warning. */
3015 location_t decl_loc, value_loc;
3016 if (c_parser_next_token_is_not (parser, CPP_NAME))
3017 {
3018 /* Give a nicer error for "enum {}". */
3019 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3020 && !parser->error)
3021 {
3022 error_at (c_parser_peek_token (parser)->location,
3023 "empty enum is invalid");
3024 parser->error = true;
3025 }
3026 else
3027 c_parser_error (parser, "expected identifier");
3028 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3029 values = error_mark_node;
3030 break;
3031 }
3032 token = c_parser_peek_token (parser);
3033 enum_id = token->value;
3034 /* Set the location in case we create a decl now. */
3035 c_parser_set_source_position_from_token (token);
3036 decl_loc = value_loc = token->location;
3037 c_parser_consume_token (parser);
3038 /* Parse any specified attributes. */
3039 tree enum_attrs = c_parser_gnu_attributes (parser);
3040 if (c_parser_next_token_is (parser, CPP_EQ))
3041 {
3042 c_parser_consume_token (parser);
3043 value_loc = c_parser_peek_token (parser)->location;
3044 enum_value = c_parser_expr_no_commas (parser, NULL).value;
3045 }
3046 else
3047 enum_value = NULL_TREE;
3048 enum_decl = build_enumerator (decl_loc, value_loc,
3049 &the_enum, enum_id, enum_value);
3050 if (enum_attrs)
3051 decl_attributes (&TREE_PURPOSE (enum_decl), enum_attrs, 0);
3052 TREE_CHAIN (enum_decl) = values;
3053 values = enum_decl;
3054 seen_comma = false;
3055 if (c_parser_next_token_is (parser, CPP_COMMA))
3056 {
3057 comma_loc = c_parser_peek_token (parser)->location;
3058 seen_comma = true;
3059 c_parser_consume_token (parser);
3060 }
3061 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3062 {
3063 if (seen_comma)
3064 pedwarn_c90 (comma_loc, OPT_Wpedantic,
3065 "comma at end of enumerator list");
3066 c_parser_consume_token (parser);
3067 break;
3068 }
3069 if (!seen_comma)
3070 {
3071 c_parser_error (parser, "expected %<,%> or %<}%>");
3072 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3073 values = error_mark_node;
3074 break;
3075 }
3076 }
3077 postfix_attrs = c_parser_gnu_attributes (parser);
3078 ret.spec = finish_enum (type, nreverse (values),
3079 chainon (attrs, postfix_attrs));
3080 ret.kind = ctsk_tagdef;
3081 ret.expr = NULL_TREE;
3082 ret.expr_const_operands = true;
3083 timevar_pop (TV_PARSE_ENUM);
3084 return ret;
3085 }
3086 else if (!ident)
3087 {
3088 c_parser_error (parser, "expected %<{%>");
3089 ret.spec = error_mark_node;
3090 ret.kind = ctsk_tagref;
3091 ret.expr = NULL_TREE;
3092 ret.expr_const_operands = true;
3093 return ret;
3094 }
3095 ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident);
3096 /* In ISO C, enumerated types can be referred to only if already
3097 defined. */
3098 if (pedantic && !COMPLETE_TYPE_P (ret.spec))
3099 {
3100 gcc_assert (ident);
3101 pedwarn (enum_loc, OPT_Wpedantic,
3102 "ISO C forbids forward references to %<enum%> types");
3103 }
3104 return ret;
3105 }
3106
3107 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
3108
3109 struct-or-union-specifier:
3110 struct-or-union gnu-attributes[opt] identifier[opt]
3111 { struct-contents } gnu-attributes[opt]
3112 struct-or-union gnu-attributes[opt] identifier
3113
3114 struct-contents:
3115 struct-declaration-list
3116
3117 struct-declaration-list:
3118 struct-declaration ;
3119 struct-declaration-list struct-declaration ;
3120
3121 GNU extensions:
3122
3123 struct-contents:
3124 empty
3125 struct-declaration
3126 struct-declaration-list struct-declaration
3127
3128 struct-declaration-list:
3129 struct-declaration-list ;
3130 ;
3131
3132 (Note that in the syntax here, unlike that in ISO C, the semicolons
3133 are included here rather than in struct-declaration, in order to
3134 describe the syntax with extra semicolons and missing semicolon at
3135 end.)
3136
3137 Objective-C:
3138
3139 struct-declaration-list:
3140 @defs ( class-name )
3141
3142 (Note this does not include a trailing semicolon, but can be
3143 followed by further declarations, and gets a pedwarn-if-pedantic
3144 when followed by a semicolon.) */
3145
3146 static struct c_typespec
3147 c_parser_struct_or_union_specifier (c_parser *parser)
3148 {
3149 struct c_typespec ret;
3150 tree attrs;
3151 tree ident = NULL_TREE;
3152 location_t struct_loc;
3153 location_t ident_loc = UNKNOWN_LOCATION;
3154 enum tree_code code;
3155 switch (c_parser_peek_token (parser)->keyword)
3156 {
3157 case RID_STRUCT:
3158 code = RECORD_TYPE;
3159 break;
3160 case RID_UNION:
3161 code = UNION_TYPE;
3162 break;
3163 default:
3164 gcc_unreachable ();
3165 }
3166 struct_loc = c_parser_peek_token (parser)->location;
3167 c_parser_consume_token (parser);
3168 attrs = c_parser_gnu_attributes (parser);
3169
3170 /* Set the location in case we create a decl now. */
3171 c_parser_set_source_position_from_token (c_parser_peek_token (parser));
3172
3173 if (c_parser_next_token_is (parser, CPP_NAME))
3174 {
3175 ident = c_parser_peek_token (parser)->value;
3176 ident_loc = c_parser_peek_token (parser)->location;
3177 struct_loc = ident_loc;
3178 c_parser_consume_token (parser);
3179 }
3180 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
3181 {
3182 /* Parse a struct or union definition. Start the scope of the
3183 tag before parsing components. */
3184 class c_struct_parse_info *struct_info;
3185 tree type = start_struct (struct_loc, code, ident, &struct_info);
3186 tree postfix_attrs;
3187 /* We chain the components in reverse order, then put them in
3188 forward order at the end. Each struct-declaration may
3189 declare multiple components (comma-separated), so we must use
3190 chainon to join them, although when parsing each
3191 struct-declaration we can use TREE_CHAIN directly.
3192
3193 The theory behind all this is that there will be more
3194 semicolon separated fields than comma separated fields, and
3195 so we'll be minimizing the number of node traversals required
3196 by chainon. */
3197 tree contents;
3198 timevar_push (TV_PARSE_STRUCT);
3199 contents = NULL_TREE;
3200 c_parser_consume_token (parser);
3201 /* Handle the Objective-C @defs construct,
3202 e.g. foo(sizeof(struct{ @defs(ClassName) }));. */
3203 if (c_parser_next_token_is_keyword (parser, RID_AT_DEFS))
3204 {
3205 tree name;
3206 gcc_assert (c_dialect_objc ());
3207 c_parser_consume_token (parser);
3208 matching_parens parens;
3209 if (!parens.require_open (parser))
3210 goto end_at_defs;
3211 if (c_parser_next_token_is (parser, CPP_NAME)
3212 && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)
3213 {
3214 name = c_parser_peek_token (parser)->value;
3215 c_parser_consume_token (parser);
3216 }
3217 else
3218 {
3219 c_parser_error (parser, "expected class name");
3220 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
3221 goto end_at_defs;
3222 }
3223 parens.skip_until_found_close (parser);
3224 contents = nreverse (objc_get_class_ivars (name));
3225 }
3226 end_at_defs:
3227 /* Parse the struct-declarations and semicolons. Problems with
3228 semicolons are diagnosed here; empty structures are diagnosed
3229 elsewhere. */
3230 while (true)
3231 {
3232 tree decls;
3233 /* Parse any stray semicolon. */
3234 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3235 {
3236 location_t semicolon_loc
3237 = c_parser_peek_token (parser)->location;
3238 gcc_rich_location richloc (semicolon_loc);
3239 richloc.add_fixit_remove ();
3240 pedwarn (&richloc, OPT_Wpedantic,
3241 "extra semicolon in struct or union specified");
3242 c_parser_consume_token (parser);
3243 continue;
3244 }
3245 /* Stop if at the end of the struct or union contents. */
3246 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3247 {
3248 c_parser_consume_token (parser);
3249 break;
3250 }
3251 /* Accept #pragmas at struct scope. */
3252 if (c_parser_next_token_is (parser, CPP_PRAGMA))
3253 {
3254 c_parser_pragma (parser, pragma_struct, NULL);
3255 continue;
3256 }
3257 /* Parse some comma-separated declarations, but not the
3258 trailing semicolon if any. */
3259 decls = c_parser_struct_declaration (parser);
3260 contents = chainon (decls, contents);
3261 /* If no semicolon follows, either we have a parse error or
3262 are at the end of the struct or union and should
3263 pedwarn. */
3264 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
3265 c_parser_consume_token (parser);
3266 else
3267 {
3268 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3269 pedwarn (c_parser_peek_token (parser)->location, 0,
3270 "no semicolon at end of struct or union");
3271 else if (parser->error
3272 || !c_parser_next_token_starts_declspecs (parser))
3273 {
3274 c_parser_error (parser, "expected %<;%>");
3275 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
3276 break;
3277 }
3278
3279 /* If we come here, we have already emitted an error
3280 for an expected `;', identifier or `(', and we also
3281 recovered already. Go on with the next field. */
3282 }
3283 }
3284 postfix_attrs = c_parser_gnu_attributes (parser);
3285 ret.spec = finish_struct (struct_loc, type, nreverse (contents),
3286 chainon (attrs, postfix_attrs), struct_info);
3287 ret.kind = ctsk_tagdef;
3288 ret.expr = NULL_TREE;
3289 ret.expr_const_operands = true;
3290 timevar_pop (TV_PARSE_STRUCT);
3291 return ret;
3292 }
3293 else if (!ident)
3294 {
3295 c_parser_error (parser, "expected %<{%>");
3296 ret.spec = error_mark_node;
3297 ret.kind = ctsk_tagref;
3298 ret.expr = NULL_TREE;
3299 ret.expr_const_operands = true;
3300 return ret;
3301 }
3302 ret = parser_xref_tag (ident_loc, code, ident);
3303 return ret;
3304 }
3305
3306 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
3307 *without* the trailing semicolon.
3308
3309 struct-declaration:
3310 specifier-qualifier-list struct-declarator-list
3311 static_assert-declaration-no-semi
3312
3313 specifier-qualifier-list:
3314 type-specifier specifier-qualifier-list[opt]
3315 type-qualifier specifier-qualifier-list[opt]
3316 alignment-specifier specifier-qualifier-list[opt]
3317 gnu-attributes specifier-qualifier-list[opt]
3318
3319 struct-declarator-list:
3320 struct-declarator
3321 struct-declarator-list , gnu-attributes[opt] struct-declarator
3322
3323 struct-declarator:
3324 declarator gnu-attributes[opt]
3325 declarator[opt] : constant-expression gnu-attributes[opt]
3326
3327 GNU extensions:
3328
3329 struct-declaration:
3330 __extension__ struct-declaration
3331 specifier-qualifier-list
3332
3333 Unlike the ISO C syntax, semicolons are handled elsewhere. The use
3334 of gnu-attributes where shown is a GNU extension. In GNU C, we accept
3335 any expression without commas in the syntax (assignment
3336 expressions, not just conditional expressions); assignment
3337 expressions will be diagnosed as non-constant. */
3338
3339 static tree
3340 c_parser_struct_declaration (c_parser *parser)
3341 {
3342 struct c_declspecs *specs;
3343 tree prefix_attrs;
3344 tree all_prefix_attrs;
3345 tree decls;
3346 location_t decl_loc;
3347 if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
3348 {
3349 int ext;
3350 tree decl;
3351 ext = disable_extension_diagnostics ();
3352 c_parser_consume_token (parser);
3353 decl = c_parser_struct_declaration (parser);
3354 restore_extension_diagnostics (ext);
3355 return decl;
3356 }
3357 if (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
3358 {
3359 c_parser_static_assert_declaration_no_semi (parser);
3360 return NULL_TREE;
3361 }
3362 specs = build_null_declspecs ();
3363 decl_loc = c_parser_peek_token (parser)->location;
3364 /* Strictly by the standard, we shouldn't allow _Alignas here,
3365 but it appears to have been intended to allow it there, so
3366 we're keeping it as it is until WG14 reaches a conclusion
3367 of N1731.
3368 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */
3369 c_parser_declspecs (parser, specs, false, true, true,
3370 true, false, cla_nonabstract_decl);
3371 if (parser->error)
3372 return NULL_TREE;
3373 if (!specs->declspecs_seen_p)
3374 {
3375 c_parser_error (parser, "expected specifier-qualifier-list");
3376 return NULL_TREE;
3377 }
3378 finish_declspecs (specs);
3379 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3380 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3381 {
3382 tree ret;
3383 if (specs->typespec_kind == ctsk_none)
3384 {
3385 pedwarn (decl_loc, OPT_Wpedantic,
3386 "ISO C forbids member declarations with no members");
3387 shadow_tag_warned (specs, pedantic);
3388 ret = NULL_TREE;
3389 }
3390 else
3391 {
3392 /* Support for unnamed structs or unions as members of
3393 structs or unions (which is [a] useful and [b] supports
3394 MS P-SDK). */
3395 tree attrs = NULL;
3396
3397 ret = grokfield (c_parser_peek_token (parser)->location,
3398 build_id_declarator (NULL_TREE), specs,
3399 NULL_TREE, &attrs);
3400 if (ret)
3401 decl_attributes (&ret, attrs, 0);
3402 }
3403 return ret;
3404 }
3405
3406 /* Provide better error recovery. Note that a type name here is valid,
3407 and will be treated as a field name. */
3408 if (specs->typespec_kind == ctsk_tagdef
3409 && TREE_CODE (specs->type) != ENUMERAL_TYPE
3410 && c_parser_next_token_starts_declspecs (parser)
3411 && !c_parser_next_token_is (parser, CPP_NAME))
3412 {
3413 c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
3414 parser->error = false;
3415 return NULL_TREE;
3416 }
3417
3418 pending_xref_error ();
3419 prefix_attrs = specs->attrs;
3420 all_prefix_attrs = prefix_attrs;
3421 specs->attrs = NULL_TREE;
3422 decls = NULL_TREE;
3423 while (true)
3424 {
3425 /* Declaring one or more declarators or un-named bit-fields. */
3426 struct c_declarator *declarator;
3427 bool dummy = false;
3428 if (c_parser_next_token_is (parser, CPP_COLON))
3429 declarator = build_id_declarator (NULL_TREE);
3430 else
3431 declarator = c_parser_declarator (parser,
3432 specs->typespec_kind != ctsk_none,
3433 C_DTR_NORMAL, &dummy);
3434 if (declarator == NULL)
3435 {
3436 c_parser_skip_to_end_of_block_or_statement (parser);
3437 break;
3438 }
3439 if (c_parser_next_token_is (parser, CPP_COLON)
3440 || c_parser_next_token_is (parser, CPP_COMMA)
3441 || c_parser_next_token_is (parser, CPP_SEMICOLON)
3442 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
3443 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3444 {
3445 tree postfix_attrs = NULL_TREE;
3446 tree width = NULL_TREE;
3447 tree d;
3448 if (c_parser_next_token_is (parser, CPP_COLON))
3449 {
3450 c_parser_consume_token (parser);
3451 width = c_parser_expr_no_commas (parser, NULL).value;
3452 }
3453 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3454 postfix_attrs = c_parser_gnu_attributes (parser);
3455 d = grokfield (c_parser_peek_token (parser)->location,
3456 declarator, specs, width, &all_prefix_attrs);
3457 decl_attributes (&d, chainon (postfix_attrs,
3458 all_prefix_attrs), 0);
3459 DECL_CHAIN (d) = decls;
3460 decls = d;
3461 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
3462 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
3463 prefix_attrs);
3464 else
3465 all_prefix_attrs = prefix_attrs;
3466 if (c_parser_next_token_is (parser, CPP_COMMA))
3467 c_parser_consume_token (parser);
3468 else if (c_parser_next_token_is (parser, CPP_SEMICOLON)
3469 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
3470 {
3471 /* Semicolon consumed in caller. */
3472 break;
3473 }
3474 else
3475 {
3476 c_parser_error (parser, "expected %<,%>, %<;%> or %<}%>");
3477 break;
3478 }
3479 }
3480 else
3481 {
3482 c_parser_error (parser,
3483 "expected %<:%>, %<,%>, %<;%>, %<}%> or "
3484 "%<__attribute__%>");
3485 break;
3486 }
3487 }
3488 return decls;
3489 }
3490
3491 /* Parse a typeof specifier (a GNU extension).
3492
3493 typeof-specifier:
3494 typeof ( expression )
3495 typeof ( type-name )
3496 */
3497
3498 static struct c_typespec
3499 c_parser_typeof_specifier (c_parser *parser)
3500 {
3501 struct c_typespec ret;
3502 ret.kind = ctsk_typeof;
3503 ret.spec = error_mark_node;
3504 ret.expr = NULL_TREE;
3505 ret.expr_const_operands = true;
3506 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF));
3507 c_parser_consume_token (parser);
3508 c_inhibit_evaluation_warnings++;
3509 in_typeof++;
3510 matching_parens parens;
3511 if (!parens.require_open (parser))
3512 {
3513 c_inhibit_evaluation_warnings--;
3514 in_typeof--;
3515 return ret;
3516 }
3517 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
3518 {
3519 struct c_type_name *type = c_parser_type_name (parser);
3520 c_inhibit_evaluation_warnings--;
3521 in_typeof--;
3522 if (type != NULL)
3523 {
3524 ret.spec = groktypename (type, &ret.expr, &ret.expr_const_operands);
3525 pop_maybe_used (variably_modified_type_p (ret.spec, NULL_TREE));
3526 }
3527 }
3528 else
3529 {
3530 bool was_vm;
3531 location_t here = c_parser_peek_token (parser)->location;
3532 struct c_expr expr = c_parser_expression (parser);
3533 c_inhibit_evaluation_warnings--;
3534 in_typeof--;
3535 if (TREE_CODE (expr.value) == COMPONENT_REF
3536 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
3537 error_at (here, "%<typeof%> applied to a bit-field");
3538 mark_exp_read (expr.value);
3539 ret.spec = TREE_TYPE (expr.value);
3540 was_vm = variably_modified_type_p (ret.spec, NULL_TREE);
3541 /* This is returned with the type so that when the type is
3542 evaluated, this can be evaluated. */
3543 if (was_vm)
3544 ret.expr = c_fully_fold (expr.value, false, &ret.expr_const_operands);
3545 pop_maybe_used (was_vm);
3546 /* For use in macros such as those in <stdatomic.h>, remove all
3547 qualifiers from atomic types. (const can be an issue for more macros
3548 using typeof than just the <stdatomic.h> ones.) */
3549 if (ret.spec != error_mark_node && TYPE_ATOMIC (ret.spec))
3550 ret.spec = c_build_qualified_type (ret.spec, TYPE_UNQUALIFIED);
3551 }
3552 parens.skip_until_found_close (parser);
3553 return ret;
3554 }
3555
3556 /* Parse an alignment-specifier.
3557
3558 C11 6.7.5:
3559
3560 alignment-specifier:
3561 _Alignas ( type-name )
3562 _Alignas ( constant-expression )
3563 */
3564
3565 static tree
3566 c_parser_alignas_specifier (c_parser * parser)
3567 {
3568 tree ret = error_mark_node;
3569 location_t loc = c_parser_peek_token (parser)->location;
3570 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNAS));
3571 c_parser_consume_token (parser);
3572 if (flag_isoc99)
3573 pedwarn_c99 (loc, OPT_Wpedantic,
3574 "ISO C99 does not support %<_Alignas%>");
3575 else
3576 pedwarn_c99 (loc, OPT_Wpedantic,
3577 "ISO C90 does not support %<_Alignas%>");
3578 matching_parens parens;
3579 if (!parens.require_open (parser))
3580 return ret;
3581 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
3582 {
3583 struct c_type_name *type = c_parser_type_name (parser);
3584 if (type != NULL)
3585 ret = c_sizeof_or_alignof_type (loc, groktypename (type, NULL, NULL),
3586 false, true, 1);
3587 }
3588 else
3589 ret = c_parser_expr_no_commas (parser, NULL).value;
3590 parens.skip_until_found_close (parser);
3591 return ret;
3592 }
3593
3594 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
3595 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then
3596 a typedef name may be redeclared; otherwise it may not. KIND
3597 indicates which kind of declarator is wanted. Returns a valid
3598 declarator except in the case of a syntax error in which case NULL is
3599 returned. *SEEN_ID is set to true if an identifier being declared is
3600 seen; this is used to diagnose bad forms of abstract array declarators
3601 and to determine whether an identifier list is syntactically permitted.
3602
3603 declarator:
3604 pointer[opt] direct-declarator
3605
3606 direct-declarator:
3607 identifier
3608 ( gnu-attributes[opt] declarator )
3609 direct-declarator array-declarator
3610 direct-declarator ( parameter-type-list )
3611 direct-declarator ( identifier-list[opt] )
3612
3613 pointer:
3614 * type-qualifier-list[opt]
3615 * type-qualifier-list[opt] pointer
3616
3617 type-qualifier-list:
3618 type-qualifier
3619 gnu-attributes
3620 type-qualifier-list type-qualifier
3621 type-qualifier-list gnu-attributes
3622
3623 array-declarator:
3624 [ type-qualifier-list[opt] assignment-expression[opt] ]
3625 [ static type-qualifier-list[opt] assignment-expression ]
3626 [ type-qualifier-list static assignment-expression ]
3627 [ type-qualifier-list[opt] * ]
3628
3629 parameter-type-list:
3630 parameter-list
3631 parameter-list , ...
3632
3633 parameter-list:
3634 parameter-declaration
3635 parameter-list , parameter-declaration
3636
3637 parameter-declaration:
3638 declaration-specifiers declarator gnu-attributes[opt]
3639 declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
3640
3641 identifier-list:
3642 identifier
3643 identifier-list , identifier
3644
3645 abstract-declarator:
3646 pointer
3647 pointer[opt] direct-abstract-declarator
3648
3649 direct-abstract-declarator:
3650 ( gnu-attributes[opt] abstract-declarator )
3651 direct-abstract-declarator[opt] array-declarator
3652 direct-abstract-declarator[opt] ( parameter-type-list[opt] )
3653
3654 GNU extensions:
3655
3656 direct-declarator:
3657 direct-declarator ( parameter-forward-declarations
3658 parameter-type-list[opt] )
3659
3660 direct-abstract-declarator:
3661 direct-abstract-declarator[opt] ( parameter-forward-declarations
3662 parameter-type-list[opt] )
3663
3664 parameter-forward-declarations:
3665 parameter-list ;
3666 parameter-forward-declarations parameter-list ;
3667
3668 The uses of gnu-attributes shown above are GNU extensions.
3669
3670 Some forms of array declarator are not included in C99 in the
3671 syntax for abstract declarators; these are disallowed elsewhere.
3672 This may be a defect (DR#289).
3673
3674 This function also accepts an omitted abstract declarator as being
3675 an abstract declarator, although not part of the formal syntax. */
3676
3677 struct c_declarator *
3678 c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
3679 bool *seen_id)
3680 {
3681 /* Parse any initial pointer part. */
3682 if (c_parser_next_token_is (parser, CPP_MULT))
3683 {
3684 struct c_declspecs *quals_attrs = build_null_declspecs ();
3685 struct c_declarator *inner;
3686 c_parser_consume_token (parser);
3687 c_parser_declspecs (parser, quals_attrs, false, false, true,
3688 false, false, cla_prefer_id);
3689 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
3690 if (inner == NULL)
3691 return NULL;
3692 else
3693 return make_pointer_declarator (quals_attrs, inner);
3694 }
3695 /* Now we have a direct declarator, direct abstract declarator or
3696 nothing (which counts as a direct abstract declarator here). */
3697 return c_parser_direct_declarator (parser, type_seen_p, kind, seen_id);
3698 }
3699
3700 /* Parse a direct declarator or direct abstract declarator; arguments
3701 as c_parser_declarator. */
3702
3703 static struct c_declarator *
3704 c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
3705 bool *seen_id)
3706 {
3707 /* The direct declarator must start with an identifier (possibly
3708 omitted) or a parenthesized declarator (possibly abstract). In
3709 an ordinary declarator, initial parentheses must start a
3710 parenthesized declarator. In an abstract declarator or parameter
3711 declarator, they could start a parenthesized declarator or a
3712 parameter list. To tell which, the open parenthesis and any
3713 following gnu-attributes must be read. If a declaration specifier
3714 follows, then it is a parameter list; if the specifier is a
3715 typedef name, there might be an ambiguity about redeclaring it,
3716 which is resolved in the direction of treating it as a typedef
3717 name. If a close parenthesis follows, it is also an empty
3718 parameter list, as the syntax does not permit empty abstract
3719 declarators. Otherwise, it is a parenthesized declarator (in
3720 which case the analysis may be repeated inside it, recursively).
3721
3722 ??? There is an ambiguity in a parameter declaration "int
3723 (__attribute__((foo)) x)", where x is not a typedef name: it
3724 could be an abstract declarator for a function, or declare x with
3725 parentheses. The proper resolution of this ambiguity needs
3726 documenting. At present we follow an accident of the old
3727 parser's implementation, whereby the first parameter must have
3728 some declaration specifiers other than just gnu-attributes. Thus as
3729 a parameter declaration it is treated as a parenthesized
3730 parameter named x, and as an abstract declarator it is
3731 rejected.
3732
3733 ??? Also following the old parser, gnu-attributes inside an empty
3734 parameter list are ignored, making it a list not yielding a
3735 prototype, rather than giving an error or making it have one
3736 parameter with implicit type int.
3737
3738 ??? Also following the old parser, typedef names may be
3739 redeclared in declarators, but not Objective-C class names. */
3740
3741 if (kind != C_DTR_ABSTRACT
3742 && c_parser_next_token_is (parser, CPP_NAME)
3743 && ((type_seen_p
3744 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
3745 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
3746 || c_parser_peek_token (parser)->id_kind == C_ID_ID))
3747 {
3748 struct c_declarator *inner
3749 = build_id_declarator (c_parser_peek_token (parser)->value);
3750 *seen_id = true;
3751 inner->id_loc = c_parser_peek_token (parser)->location;
3752 c_parser_consume_token (parser);
3753 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3754 }
3755
3756 if (kind != C_DTR_NORMAL
3757 && c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
3758 {
3759 struct c_declarator *inner = build_id_declarator (NULL_TREE);
3760 inner->id_loc = c_parser_peek_token (parser)->location;
3761 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3762 }
3763
3764 /* Either we are at the end of an abstract declarator, or we have
3765 parentheses. */
3766
3767 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3768 {
3769 tree attrs;
3770 struct c_declarator *inner;
3771 c_parser_consume_token (parser);
3772 attrs = c_parser_gnu_attributes (parser);
3773 if (kind != C_DTR_NORMAL
3774 && (c_parser_next_token_starts_declspecs (parser)
3775 || c_parser_next_token_is (parser, CPP_CLOSE_PAREN)))
3776 {
3777 struct c_arg_info *args
3778 = c_parser_parms_declarator (parser, kind == C_DTR_NORMAL,
3779 attrs);
3780 if (args == NULL)
3781 return NULL;
3782 else
3783 {
3784 inner
3785 = build_function_declarator (args,
3786 build_id_declarator (NULL_TREE));
3787 return c_parser_direct_declarator_inner (parser, *seen_id,
3788 inner);
3789 }
3790 }
3791 /* A parenthesized declarator. */
3792 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
3793 if (inner != NULL && attrs != NULL)
3794 inner = build_attrs_declarator (attrs, inner);
3795 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3796 {
3797 c_parser_consume_token (parser);
3798 if (inner == NULL)
3799 return NULL;
3800 else
3801 return c_parser_direct_declarator_inner (parser, *seen_id, inner);
3802 }
3803 else
3804 {
3805 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3806 "expected %<)%>");
3807 return NULL;
3808 }
3809 }
3810 else
3811 {
3812 if (kind == C_DTR_NORMAL)
3813 {
3814 c_parser_error (parser, "expected identifier or %<(%>");
3815 return NULL;
3816 }
3817 else
3818 return build_id_declarator (NULL_TREE);
3819 }
3820 }
3821
3822 /* Parse part of a direct declarator or direct abstract declarator,
3823 given that some (in INNER) has already been parsed; ID_PRESENT is
3824 true if an identifier is present, false for an abstract
3825 declarator. */
3826
3827 static struct c_declarator *
3828 c_parser_direct_declarator_inner (c_parser *parser, bool id_present,
3829 struct c_declarator *inner)
3830 {
3831 /* Parse a sequence of array declarators and parameter lists. */
3832 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
3833 {
3834 location_t brace_loc = c_parser_peek_token (parser)->location;
3835 struct c_declarator *declarator;
3836 struct c_declspecs *quals_attrs = build_null_declspecs ();
3837 bool static_seen;
3838 bool star_seen;
3839 struct c_expr dimen;
3840 dimen.value = NULL_TREE;
3841 dimen.original_code = ERROR_MARK;
3842 dimen.original_type = NULL_TREE;
3843 c_parser_consume_token (parser);
3844 c_parser_declspecs (parser, quals_attrs, false, false, true,
3845 false, false, cla_prefer_id);
3846 static_seen = c_parser_next_token_is_keyword (parser, RID_STATIC);
3847 if (static_seen)
3848 c_parser_consume_token (parser);
3849 if (static_seen && !quals_attrs->declspecs_seen_p)
3850 c_parser_declspecs (parser, quals_attrs, false, false, true,
3851 false, false, cla_prefer_id);
3852 if (!quals_attrs->declspecs_seen_p)
3853 quals_attrs = NULL;
3854 /* If "static" is present, there must be an array dimension.
3855 Otherwise, there may be a dimension, "*", or no
3856 dimension. */
3857 if (static_seen)
3858 {
3859 star_seen = false;
3860 dimen = c_parser_expr_no_commas (parser, NULL);
3861 }
3862 else
3863 {
3864 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
3865 {
3866 dimen.value = NULL_TREE;
3867 star_seen = false;
3868 }
3869 else if (c_parser_next_token_is (parser, CPP_MULT))
3870 {
3871 if (c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_SQUARE)
3872 {
3873 dimen.value = NULL_TREE;
3874 star_seen = true;
3875 c_parser_consume_token (parser);
3876 }
3877 else
3878 {
3879 star_seen = false;
3880 dimen = c_parser_expr_no_commas (parser, NULL);
3881 }
3882 }
3883 else
3884 {
3885 star_seen = false;
3886 dimen = c_parser_expr_no_commas (parser, NULL);
3887 }
3888 }
3889 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
3890 c_parser_consume_token (parser);
3891 else
3892 {
3893 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
3894 "expected %<]%>");
3895 return NULL;
3896 }
3897 if (dimen.value)
3898 dimen = convert_lvalue_to_rvalue (brace_loc, dimen, true, true);
3899 declarator = build_array_declarator (brace_loc, dimen.value, quals_attrs,
3900 static_seen, star_seen);
3901 if (declarator == NULL)
3902 return NULL;
3903 inner = set_array_declarator_inner (declarator, inner);
3904 return c_parser_direct_declarator_inner (parser, id_present, inner);
3905 }
3906 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
3907 {
3908 tree attrs;
3909 struct c_arg_info *args;
3910 c_parser_consume_token (parser);
3911 attrs = c_parser_gnu_attributes (parser);
3912 args = c_parser_parms_declarator (parser, id_present, attrs);
3913 if (args == NULL)
3914 return NULL;
3915 else
3916 {
3917 inner = build_function_declarator (args, inner);
3918 return c_parser_direct_declarator_inner (parser, id_present, inner);
3919 }
3920 }
3921 return inner;
3922 }
3923
3924 /* Parse a parameter list or identifier list, including the closing
3925 parenthesis but not the opening one. ATTRS are the attributes at
3926 the start of the list. ID_LIST_OK is true if an identifier list is
3927 acceptable; such a list must not have attributes at the start. */
3928
3929 static struct c_arg_info *
3930 c_parser_parms_declarator (c_parser *parser, bool id_list_ok, tree attrs)
3931 {
3932 push_scope ();
3933 declare_parm_level ();
3934 /* If the list starts with an identifier, it is an identifier list.
3935 Otherwise, it is either a prototype list or an empty list. */
3936 if (id_list_ok
3937 && !attrs
3938 && c_parser_next_token_is (parser, CPP_NAME)
3939 && c_parser_peek_token (parser)->id_kind == C_ID_ID
3940
3941 /* Look ahead to detect typos in type names. */
3942 && c_parser_peek_2nd_token (parser)->type != CPP_NAME
3943 && c_parser_peek_2nd_token (parser)->type != CPP_MULT
3944 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
3945 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_SQUARE
3946 && c_parser_peek_2nd_token (parser)->type != CPP_KEYWORD)
3947 {
3948 tree list = NULL_TREE, *nextp = &list;
3949 while (c_parser_next_token_is (parser, CPP_NAME)
3950 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
3951 {
3952 *nextp = build_tree_list (NULL_TREE,
3953 c_parser_peek_token (parser)->value);
3954 nextp = & TREE_CHAIN (*nextp);
3955 c_parser_consume_token (parser);
3956 if (c_parser_next_token_is_not (parser, CPP_COMMA))
3957 break;
3958 c_parser_consume_token (parser);
3959 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3960 {
3961 c_parser_error (parser, "expected identifier");
3962 break;
3963 }
3964 }
3965 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
3966 {
3967 struct c_arg_info *ret = build_arg_info ();
3968 ret->types = list;
3969 c_parser_consume_token (parser);
3970 pop_scope ();
3971 return ret;
3972 }
3973 else
3974 {
3975 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
3976 "expected %<)%>");
3977 pop_scope ();
3978 return NULL;
3979 }
3980 }
3981 else
3982 {
3983 struct c_arg_info *ret = c_parser_parms_list_declarator (parser, attrs,
3984 NULL);
3985 pop_scope ();
3986 return ret;
3987 }
3988 }
3989
3990 /* Parse a parameter list (possibly empty), including the closing
3991 parenthesis but not the opening one. ATTRS are the attributes at
3992 the start of the list. EXPR is NULL or an expression that needs to
3993 be evaluated for the side effects of array size expressions in the
3994 parameters. */
3995
3996 static struct c_arg_info *
3997 c_parser_parms_list_declarator (c_parser *parser, tree attrs, tree expr)
3998 {
3999 bool bad_parm = false;
4000
4001 /* ??? Following the old parser, forward parameter declarations may
4002 use abstract declarators, and if no real parameter declarations
4003 follow the forward declarations then this is not diagnosed. Also
4004 note as above that attributes are ignored as the only contents of
4005 the parentheses, or as the only contents after forward
4006 declarations. */
4007 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4008 {
4009 struct c_arg_info *ret = build_arg_info ();
4010 c_parser_consume_token (parser);
4011 return ret;
4012 }
4013 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4014 {
4015 struct c_arg_info *ret = build_arg_info ();
4016
4017 if (flag_allow_parameterless_variadic_functions)
4018 {
4019 /* F (...) is allowed. */
4020 ret->types = NULL_TREE;
4021 }
4022 else
4023 {
4024 /* Suppress -Wold-style-definition for this case. */
4025 ret->types = error_mark_node;
4026 error_at (c_parser_peek_token (parser)->location,
4027 "ISO C requires a named argument before %<...%>");
4028 }
4029 c_parser_consume_token (parser);
4030 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4031 {
4032 c_parser_consume_token (parser);
4033 return ret;
4034 }
4035 else
4036 {
4037 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4038 "expected %<)%>");
4039 return NULL;
4040 }
4041 }
4042 /* Nonempty list of parameters, either terminated with semicolon
4043 (forward declarations; recurse) or with close parenthesis (normal
4044 function) or with ", ... )" (variadic function). */
4045 while (true)
4046 {
4047 /* Parse a parameter. */
4048 struct c_parm *parm = c_parser_parameter_declaration (parser, attrs);
4049 attrs = NULL_TREE;
4050 if (parm == NULL)
4051 bad_parm = true;
4052 else
4053 push_parm_decl (parm, &expr);
4054 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
4055 {
4056 tree new_attrs;
4057 c_parser_consume_token (parser);
4058 mark_forward_parm_decls ();
4059 new_attrs = c_parser_gnu_attributes (parser);
4060 return c_parser_parms_list_declarator (parser, new_attrs, expr);
4061 }
4062 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4063 {
4064 c_parser_consume_token (parser);
4065 if (bad_parm)
4066 return NULL;
4067 else
4068 return get_parm_info (false, expr);
4069 }
4070 if (!c_parser_require (parser, CPP_COMMA,
4071 "expected %<;%>, %<,%> or %<)%>",
4072 UNKNOWN_LOCATION, false))
4073 {
4074 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4075 return NULL;
4076 }
4077 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4078 {
4079 c_parser_consume_token (parser);
4080 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4081 {
4082 c_parser_consume_token (parser);
4083 if (bad_parm)
4084 return NULL;
4085 else
4086 return get_parm_info (true, expr);
4087 }
4088 else
4089 {
4090 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4091 "expected %<)%>");
4092 return NULL;
4093 }
4094 }
4095 }
4096 }
4097
4098 /* Parse a parameter declaration. ATTRS are the attributes at the
4099 start of the declaration if it is the first parameter. */
4100
4101 static struct c_parm *
4102 c_parser_parameter_declaration (c_parser *parser, tree attrs)
4103 {
4104 struct c_declspecs *specs;
4105 struct c_declarator *declarator;
4106 tree prefix_attrs;
4107 tree postfix_attrs = NULL_TREE;
4108 bool dummy = false;
4109
4110 /* Accept #pragmas between parameter declarations. */
4111 while (c_parser_next_token_is (parser, CPP_PRAGMA))
4112 c_parser_pragma (parser, pragma_param, NULL);
4113
4114 if (!c_parser_next_token_starts_declspecs (parser))
4115 {
4116 c_token *token = c_parser_peek_token (parser);
4117 if (parser->error)
4118 return NULL;
4119 c_parser_set_source_position_from_token (token);
4120 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
4121 {
4122 auto_diagnostic_group d;
4123 name_hint hint = lookup_name_fuzzy (token->value,
4124 FUZZY_LOOKUP_TYPENAME,
4125 token->location);
4126 if (const char *suggestion = hint.suggestion ())
4127 {
4128 gcc_rich_location richloc (token->location);
4129 richloc.add_fixit_replace (suggestion);
4130 error_at (&richloc,
4131 "unknown type name %qE; did you mean %qs?",
4132 token->value, suggestion);
4133 }
4134 else
4135 error_at (token->location, "unknown type name %qE", token->value);
4136 parser->error = true;
4137 }
4138 /* ??? In some Objective-C cases '...' isn't applicable so there
4139 should be a different message. */
4140 else
4141 c_parser_error (parser,
4142 "expected declaration specifiers or %<...%>");
4143 c_parser_skip_to_end_of_parameter (parser);
4144 return NULL;
4145 }
4146
4147 location_t start_loc = c_parser_peek_token (parser)->location;
4148
4149 specs = build_null_declspecs ();
4150 if (attrs)
4151 {
4152 declspecs_add_attrs (input_location, specs, attrs);
4153 attrs = NULL_TREE;
4154 }
4155 c_parser_declspecs (parser, specs, true, true, true, true, false,
4156 cla_nonabstract_decl);
4157 finish_declspecs (specs);
4158 pending_xref_error ();
4159 prefix_attrs = specs->attrs;
4160 specs->attrs = NULL_TREE;
4161 declarator = c_parser_declarator (parser,
4162 specs->typespec_kind != ctsk_none,
4163 C_DTR_PARM, &dummy);
4164 if (declarator == NULL)
4165 {
4166 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
4167 return NULL;
4168 }
4169 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4170 postfix_attrs = c_parser_gnu_attributes (parser);
4171
4172 /* Generate a location for the parameter, ranging from the start of the
4173 initial token to the end of the final token.
4174
4175 If we have a identifier, then use it for the caret location, e.g.
4176
4177 extern int callee (int one, int (*two)(int, int), float three);
4178 ~~~~~~^~~~~~~~~~~~~~
4179
4180 otherwise, reuse the start location for the caret location e.g.:
4181
4182 extern int callee (int one, int (*)(int, int), float three);
4183 ^~~~~~~~~~~~~~~~~
4184 */
4185 location_t end_loc = parser->last_token_location;
4186
4187 /* Find any cdk_id declarator; determine if we have an identifier. */
4188 c_declarator *id_declarator = declarator;
4189 while (id_declarator && id_declarator->kind != cdk_id)
4190 id_declarator = id_declarator->declarator;
4191 location_t caret_loc = (id_declarator->u.id
4192 ? id_declarator->id_loc
4193 : start_loc);
4194 location_t param_loc = make_location (caret_loc, start_loc, end_loc);
4195
4196 return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
4197 declarator, param_loc);
4198 }
4199
4200 /* Parse a string literal in an asm expression. It should not be
4201 translated, and wide string literals are an error although
4202 permitted by the syntax. This is a GNU extension.
4203
4204 asm-string-literal:
4205 string-literal
4206 */
4207
4208 static tree
4209 c_parser_asm_string_literal (c_parser *parser)
4210 {
4211 tree str;
4212 int save_flag = warn_overlength_strings;
4213 warn_overlength_strings = 0;
4214 str = c_parser_string_literal (parser, false, false).value;
4215 warn_overlength_strings = save_flag;
4216 return str;
4217 }
4218
4219 /* Parse a simple asm expression. This is used in restricted
4220 contexts, where a full expression with inputs and outputs does not
4221 make sense. This is a GNU extension.
4222
4223 simple-asm-expr:
4224 asm ( asm-string-literal )
4225 */
4226
4227 static tree
4228 c_parser_simple_asm_expr (c_parser *parser)
4229 {
4230 tree str;
4231 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
4232 c_parser_consume_token (parser);
4233 matching_parens parens;
4234 if (!parens.require_open (parser))
4235 return NULL_TREE;
4236 str = c_parser_asm_string_literal (parser);
4237 if (!parens.require_close (parser))
4238 {
4239 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4240 return NULL_TREE;
4241 }
4242 return str;
4243 }
4244
4245 static tree
4246 c_parser_gnu_attribute_any_word (c_parser *parser)
4247 {
4248 tree attr_name = NULL_TREE;
4249
4250 if (c_parser_next_token_is (parser, CPP_KEYWORD))
4251 {
4252 /* ??? See comment above about what keywords are accepted here. */
4253 bool ok;
4254 switch (c_parser_peek_token (parser)->keyword)
4255 {
4256 case RID_STATIC:
4257 case RID_UNSIGNED:
4258 case RID_LONG:
4259 case RID_CONST:
4260 case RID_EXTERN:
4261 case RID_REGISTER:
4262 case RID_TYPEDEF:
4263 case RID_SHORT:
4264 case RID_INLINE:
4265 case RID_NORETURN:
4266 case RID_VOLATILE:
4267 case RID_SIGNED:
4268 case RID_AUTO:
4269 case RID_RESTRICT:
4270 case RID_COMPLEX:
4271 case RID_THREAD:
4272 case RID_INT:
4273 case RID_CHAR:
4274 case RID_FLOAT:
4275 case RID_DOUBLE:
4276 case RID_VOID:
4277 case RID_DFLOAT32:
4278 case RID_DFLOAT64:
4279 case RID_DFLOAT128:
4280 CASE_RID_FLOATN_NX:
4281 case RID_BOOL:
4282 case RID_FRACT:
4283 case RID_ACCUM:
4284 case RID_SAT:
4285 case RID_TRANSACTION_ATOMIC:
4286 case RID_TRANSACTION_CANCEL:
4287 case RID_ATOMIC:
4288 case RID_AUTO_TYPE:
4289 case RID_INT_N_0:
4290 case RID_INT_N_1:
4291 case RID_INT_N_2:
4292 case RID_INT_N_3:
4293 ok = true;
4294 break;
4295 default:
4296 ok = false;
4297 break;
4298 }
4299 if (!ok)
4300 return NULL_TREE;
4301
4302 /* Accept __attribute__((__const)) as __attribute__((const)) etc. */
4303 attr_name = ridpointers[(int) c_parser_peek_token (parser)->keyword];
4304 }
4305 else if (c_parser_next_token_is (parser, CPP_NAME))
4306 attr_name = c_parser_peek_token (parser)->value;
4307
4308 return attr_name;
4309 }
4310
4311 /* Parse (possibly empty) gnu-attributes. This is a GNU extension.
4312
4313 gnu-attributes:
4314 empty
4315 gnu-attributes gnu-attribute
4316
4317 gnu-attribute:
4318 __attribute__ ( ( gnu-attribute-list ) )
4319
4320 gnu-attribute-list:
4321 gnu-attrib
4322 gnu-attribute_list , gnu-attrib
4323
4324 gnu-attrib:
4325 empty
4326 any-word
4327 any-word ( identifier )
4328 any-word ( identifier , nonempty-expr-list )
4329 any-word ( expr-list )
4330
4331 where the "identifier" must not be declared as a type, and
4332 "any-word" may be any identifier (including one declared as a
4333 type), a reserved word storage class specifier, type specifier or
4334 type qualifier. ??? This still leaves out most reserved keywords
4335 (following the old parser), shouldn't we include them, and why not
4336 allow identifiers declared as types to start the arguments?
4337 When EXPECT_COMMA is true, expect the attribute to be preceded
4338 by a comma and fail if it isn't.
4339 When EMPTY_OK is true, allow and consume any number of consecutive
4340 commas with no attributes in between. */
4341
4342 static tree
4343 c_parser_gnu_attribute (c_parser *parser, tree attrs,
4344 bool expect_comma = false, bool empty_ok = true)
4345 {
4346 bool comma_first = c_parser_next_token_is (parser, CPP_COMMA);
4347 if (!comma_first
4348 && !c_parser_next_token_is (parser, CPP_NAME)
4349 && !c_parser_next_token_is (parser, CPP_KEYWORD))
4350 return NULL_TREE;
4351
4352 while (c_parser_next_token_is (parser, CPP_COMMA))
4353 {
4354 c_parser_consume_token (parser);
4355 if (!empty_ok)
4356 return attrs;
4357 }
4358
4359 tree attr_name = c_parser_gnu_attribute_any_word (parser);
4360 if (attr_name == NULL_TREE)
4361 return NULL_TREE;
4362
4363 attr_name = canonicalize_attr_name (attr_name);
4364 c_parser_consume_token (parser);
4365
4366 tree attr;
4367 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
4368 {
4369 if (expect_comma && !comma_first)
4370 {
4371 /* A comma is missing between the last attribute on the chain
4372 and this one. */
4373 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4374 "expected %<)%>");
4375 return error_mark_node;
4376 }
4377 attr = build_tree_list (attr_name, NULL_TREE);
4378 /* Add this attribute to the list. */
4379 attrs = chainon (attrs, attr);
4380 return attrs;
4381 }
4382 c_parser_consume_token (parser);
4383
4384 vec<tree, va_gc> *expr_list;
4385 tree attr_args;
4386 /* Parse the attribute contents. If they start with an
4387 identifier which is followed by a comma or close
4388 parenthesis, then the arguments start with that
4389 identifier; otherwise they are an expression list.
4390 In objective-c the identifier may be a classname. */
4391 if (c_parser_next_token_is (parser, CPP_NAME)
4392 && (c_parser_peek_token (parser)->id_kind == C_ID_ID
4393 || (c_dialect_objc ()
4394 && c_parser_peek_token (parser)->id_kind
4395 == C_ID_CLASSNAME))
4396 && ((c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
4397 || (c_parser_peek_2nd_token (parser)->type
4398 == CPP_CLOSE_PAREN))
4399 && (attribute_takes_identifier_p (attr_name)
4400 || (c_dialect_objc ()
4401 && c_parser_peek_token (parser)->id_kind
4402 == C_ID_CLASSNAME)))
4403 {
4404 tree arg1 = c_parser_peek_token (parser)->value;
4405 c_parser_consume_token (parser);
4406 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4407 attr_args = build_tree_list (NULL_TREE, arg1);
4408 else
4409 {
4410 tree tree_list;
4411 c_parser_consume_token (parser);
4412 expr_list = c_parser_expr_list (parser, false, true,
4413 NULL, NULL, NULL, NULL);
4414 tree_list = build_tree_list_vec (expr_list);
4415 attr_args = tree_cons (NULL_TREE, arg1, tree_list);
4416 release_tree_vector (expr_list);
4417 }
4418 }
4419 else
4420 {
4421 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4422 attr_args = NULL_TREE;
4423 else
4424 {
4425 expr_list = c_parser_expr_list (parser, false, true,
4426 NULL, NULL, NULL, NULL);
4427 attr_args = build_tree_list_vec (expr_list);
4428 release_tree_vector (expr_list);
4429 }
4430 }
4431
4432 attr = build_tree_list (attr_name, attr_args);
4433 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4434 c_parser_consume_token (parser);
4435 else
4436 {
4437 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4438 "expected %<)%>");
4439 return error_mark_node;
4440 }
4441
4442 if (expect_comma && !comma_first)
4443 {
4444 /* A comma is missing between the last attribute on the chain
4445 and this one. */
4446 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4447 "expected %<)%>");
4448 return error_mark_node;
4449 }
4450
4451 /* Add this attribute to the list. */
4452 attrs = chainon (attrs, attr);
4453 return attrs;
4454 }
4455
4456 static tree
4457 c_parser_gnu_attributes (c_parser *parser)
4458 {
4459 tree attrs = NULL_TREE;
4460 while (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
4461 {
4462 bool save_translate_strings_p = parser->translate_strings_p;
4463 parser->translate_strings_p = false;
4464 /* Consume the `__attribute__' keyword. */
4465 c_parser_consume_token (parser);
4466 /* Look for the two `(' tokens. */
4467 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4468 {
4469 parser->translate_strings_p = save_translate_strings_p;
4470 return attrs;
4471 }
4472 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
4473 {
4474 parser->translate_strings_p = save_translate_strings_p;
4475 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
4476 return attrs;
4477 }
4478 /* Parse the attribute list. Require a comma between successive
4479 (possibly empty) attributes. */
4480 for (bool expect_comma = false; ; expect_comma = true)
4481 {
4482 /* Parse a single attribute. */
4483 tree attr = c_parser_gnu_attribute (parser, attrs, expect_comma);
4484 if (attr == error_mark_node)
4485 return attrs;
4486 if (!attr)
4487 break;
4488 attrs = attr;
4489 }
4490
4491 /* Look for the two `)' tokens. */
4492 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4493 c_parser_consume_token (parser);
4494 else
4495 {
4496 parser->translate_strings_p = save_translate_strings_p;
4497 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4498 "expected %<)%>");
4499 return attrs;
4500 }
4501 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
4502 c_parser_consume_token (parser);
4503 else
4504 {
4505 parser->translate_strings_p = save_translate_strings_p;
4506 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
4507 "expected %<)%>");
4508 return attrs;
4509 }
4510 parser->translate_strings_p = save_translate_strings_p;
4511 }
4512
4513 return attrs;
4514 }
4515
4516 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK
4517 says whether alignment specifiers are OK (only in cases that might
4518 be the type name of a compound literal).
4519
4520 type-name:
4521 specifier-qualifier-list abstract-declarator[opt]
4522 */
4523
4524 struct c_type_name *
4525 c_parser_type_name (c_parser *parser, bool alignas_ok)
4526 {
4527 struct c_declspecs *specs = build_null_declspecs ();
4528 struct c_declarator *declarator;
4529 struct c_type_name *ret;
4530 bool dummy = false;
4531 c_parser_declspecs (parser, specs, false, true, true, alignas_ok, false,
4532 cla_prefer_type);
4533 if (!specs->declspecs_seen_p)
4534 {
4535 c_parser_error (parser, "expected specifier-qualifier-list");
4536 return NULL;
4537 }
4538 if (specs->type != error_mark_node)
4539 {
4540 pending_xref_error ();
4541 finish_declspecs (specs);
4542 }
4543 declarator = c_parser_declarator (parser,
4544 specs->typespec_kind != ctsk_none,
4545 C_DTR_ABSTRACT, &dummy);
4546 if (declarator == NULL)
4547 return NULL;
4548 ret = XOBNEW (&parser_obstack, struct c_type_name);
4549 ret->specs = specs;
4550 ret->declarator = declarator;
4551 return ret;
4552 }
4553
4554 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
4555
4556 initializer:
4557 assignment-expression
4558 { initializer-list }
4559 { initializer-list , }
4560
4561 initializer-list:
4562 designation[opt] initializer
4563 initializer-list , designation[opt] initializer
4564
4565 designation:
4566 designator-list =
4567
4568 designator-list:
4569 designator
4570 designator-list designator
4571
4572 designator:
4573 array-designator
4574 . identifier
4575
4576 array-designator:
4577 [ constant-expression ]
4578
4579 GNU extensions:
4580
4581 initializer:
4582 { }
4583
4584 designation:
4585 array-designator
4586 identifier :
4587
4588 array-designator:
4589 [ constant-expression ... constant-expression ]
4590
4591 Any expression without commas is accepted in the syntax for the
4592 constant-expressions, with non-constant expressions rejected later.
4593
4594 This function is only used for top-level initializers; for nested
4595 ones, see c_parser_initval. */
4596
4597 static struct c_expr
4598 c_parser_initializer (c_parser *parser)
4599 {
4600 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
4601 return c_parser_braced_init (parser, NULL_TREE, false, NULL);
4602 else
4603 {
4604 struct c_expr ret;
4605 location_t loc = c_parser_peek_token (parser)->location;
4606 ret = c_parser_expr_no_commas (parser, NULL);
4607 if (TREE_CODE (ret.value) != STRING_CST
4608 && TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR)
4609 ret = convert_lvalue_to_rvalue (loc, ret, true, true);
4610 return ret;
4611 }
4612 }
4613
4614 /* The location of the last comma within the current initializer list,
4615 or UNKNOWN_LOCATION if not within one. */
4616
4617 location_t last_init_list_comma;
4618
4619 /* Parse a braced initializer list. TYPE is the type specified for a
4620 compound literal, and NULL_TREE for other initializers and for
4621 nested braced lists. NESTED_P is true for nested braced lists,
4622 false for the list of a compound literal or the list that is the
4623 top-level initializer in a declaration. */
4624
4625 static struct c_expr
4626 c_parser_braced_init (c_parser *parser, tree type, bool nested_p,
4627 struct obstack *outer_obstack)
4628 {
4629 struct c_expr ret;
4630 struct obstack braced_init_obstack;
4631 location_t brace_loc = c_parser_peek_token (parser)->location;
4632 gcc_obstack_init (&braced_init_obstack);
4633 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
4634 matching_braces braces;
4635 braces.consume_open (parser);
4636 if (nested_p)
4637 {
4638 finish_implicit_inits (brace_loc, outer_obstack);
4639 push_init_level (brace_loc, 0, &braced_init_obstack);
4640 }
4641 else
4642 really_start_incremental_init (type);
4643 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
4644 {
4645 pedwarn (brace_loc, OPT_Wpedantic, "ISO C forbids empty initializer braces");
4646 }
4647 else
4648 {
4649 /* Parse a non-empty initializer list, possibly with a trailing
4650 comma. */
4651 while (true)
4652 {
4653 c_parser_initelt (parser, &braced_init_obstack);
4654 if (parser->error)
4655 break;
4656 if (c_parser_next_token_is (parser, CPP_COMMA))
4657 {
4658 last_init_list_comma = c_parser_peek_token (parser)->location;
4659 c_parser_consume_token (parser);
4660 }
4661 else
4662 break;
4663 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
4664 break;
4665 }
4666 }
4667 c_token *next_tok = c_parser_peek_token (parser);
4668 if (next_tok->type != CPP_CLOSE_BRACE)
4669 {
4670 ret.set_error ();
4671 ret.original_code = ERROR_MARK;
4672 ret.original_type = NULL;
4673 braces.skip_until_found_close (parser);
4674 pop_init_level (brace_loc, 0, &braced_init_obstack, last_init_list_comma);
4675 obstack_free (&braced_init_obstack, NULL);
4676 return ret;
4677 }
4678 location_t close_loc = next_tok->location;
4679 c_parser_consume_token (parser);
4680 ret = pop_init_level (brace_loc, 0, &braced_init_obstack, close_loc);
4681 obstack_free (&braced_init_obstack, NULL);
4682 set_c_expr_source_range (&ret, brace_loc, close_loc);
4683 return ret;
4684 }
4685
4686 /* Parse a nested initializer, including designators. */
4687
4688 static void
4689 c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
4690 {
4691 /* Parse any designator or designator list. A single array
4692 designator may have the subsequent "=" omitted in GNU C, but a
4693 longer list or a structure member designator may not. */
4694 if (c_parser_next_token_is (parser, CPP_NAME)
4695 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
4696 {
4697 /* Old-style structure member designator. */
4698 set_init_label (c_parser_peek_token (parser)->location,
4699 c_parser_peek_token (parser)->value,
4700 c_parser_peek_token (parser)->location,
4701 braced_init_obstack);
4702 /* Use the colon as the error location. */
4703 pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_Wpedantic,
4704 "obsolete use of designated initializer with %<:%>");
4705 c_parser_consume_token (parser);
4706 c_parser_consume_token (parser);
4707 }
4708 else
4709 {
4710 /* des_seen is 0 if there have been no designators, 1 if there
4711 has been a single array designator and 2 otherwise. */
4712 int des_seen = 0;
4713 /* Location of a designator. */
4714 location_t des_loc = UNKNOWN_LOCATION; /* Quiet warning. */
4715 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
4716 || c_parser_next_token_is (parser, CPP_DOT))
4717 {
4718 int des_prev = des_seen;
4719 if (!des_seen)
4720 des_loc = c_parser_peek_token (parser)->location;
4721 if (des_seen < 2)
4722 des_seen++;
4723 if (c_parser_next_token_is (parser, CPP_DOT))
4724 {
4725 des_seen = 2;
4726 c_parser_consume_token (parser);
4727 if (c_parser_next_token_is (parser, CPP_NAME))
4728 {
4729 set_init_label (des_loc, c_parser_peek_token (parser)->value,
4730 c_parser_peek_token (parser)->location,
4731 braced_init_obstack);
4732 c_parser_consume_token (parser);
4733 }
4734 else
4735 {
4736 struct c_expr init;
4737 init.set_error ();
4738 init.original_code = ERROR_MARK;
4739 init.original_type = NULL;
4740 c_parser_error (parser, "expected identifier");
4741 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
4742 process_init_element (input_location, init, false,
4743 braced_init_obstack);
4744 return;
4745 }
4746 }
4747 else
4748 {
4749 tree first, second;
4750 location_t ellipsis_loc = UNKNOWN_LOCATION; /* Quiet warning. */
4751 location_t array_index_loc = UNKNOWN_LOCATION;
4752 /* ??? Following the old parser, [ objc-receiver
4753 objc-message-args ] is accepted as an initializer,
4754 being distinguished from a designator by what follows
4755 the first assignment expression inside the square
4756 brackets, but after a first array designator a
4757 subsequent square bracket is for Objective-C taken to
4758 start an expression, using the obsolete form of
4759 designated initializer without '=', rather than
4760 possibly being a second level of designation: in LALR
4761 terms, the '[' is shifted rather than reducing
4762 designator to designator-list. */
4763 if (des_prev == 1 && c_dialect_objc ())
4764 {
4765 des_seen = des_prev;
4766 break;
4767 }
4768 if (des_prev == 0 && c_dialect_objc ())
4769 {
4770 /* This might be an array designator or an
4771 Objective-C message expression. If the former,
4772 continue parsing here; if the latter, parse the
4773 remainder of the initializer given the starting
4774 primary-expression. ??? It might make sense to
4775 distinguish when des_prev == 1 as well; see
4776 previous comment. */
4777 tree rec, args;
4778 struct c_expr mexpr;
4779 c_parser_consume_token (parser);
4780 if (c_parser_peek_token (parser)->type == CPP_NAME
4781 && ((c_parser_peek_token (parser)->id_kind
4782 == C_ID_TYPENAME)
4783 || (c_parser_peek_token (parser)->id_kind
4784 == C_ID_CLASSNAME)))
4785 {
4786 /* Type name receiver. */
4787 tree id = c_parser_peek_token (parser)->value;
4788 c_parser_consume_token (parser);
4789 rec = objc_get_class_reference (id);
4790 goto parse_message_args;
4791 }
4792 first = c_parser_expr_no_commas (parser, NULL).value;
4793 mark_exp_read (first);
4794 if (c_parser_next_token_is (parser, CPP_ELLIPSIS)
4795 || c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4796 goto array_desig_after_first;
4797 /* Expression receiver. So far only one part
4798 without commas has been parsed; there might be
4799 more of the expression. */
4800 rec = first;
4801 while (c_parser_next_token_is (parser, CPP_COMMA))
4802 {
4803 struct c_expr next;
4804 location_t comma_loc, exp_loc;
4805 comma_loc = c_parser_peek_token (parser)->location;
4806 c_parser_consume_token (parser);
4807 exp_loc = c_parser_peek_token (parser)->location;
4808 next = c_parser_expr_no_commas (parser, NULL);
4809 next = convert_lvalue_to_rvalue (exp_loc, next,
4810 true, true);
4811 rec = build_compound_expr (comma_loc, rec, next.value);
4812 }
4813 parse_message_args:
4814 /* Now parse the objc-message-args. */
4815 args = c_parser_objc_message_args (parser);
4816 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
4817 "expected %<]%>");
4818 mexpr.value
4819 = objc_build_message_expr (rec, args);
4820 mexpr.original_code = ERROR_MARK;
4821 mexpr.original_type = NULL;
4822 /* Now parse and process the remainder of the
4823 initializer, starting with this message
4824 expression as a primary-expression. */
4825 c_parser_initval (parser, &mexpr, braced_init_obstack);
4826 return;
4827 }
4828 c_parser_consume_token (parser);
4829 array_index_loc = c_parser_peek_token (parser)->location;
4830 first = c_parser_expr_no_commas (parser, NULL).value;
4831 mark_exp_read (first);
4832 array_desig_after_first:
4833 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
4834 {
4835 ellipsis_loc = c_parser_peek_token (parser)->location;
4836 c_parser_consume_token (parser);
4837 second = c_parser_expr_no_commas (parser, NULL).value;
4838 mark_exp_read (second);
4839 }
4840 else
4841 second = NULL_TREE;
4842 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
4843 {
4844 c_parser_consume_token (parser);
4845 set_init_index (array_index_loc, first, second,
4846 braced_init_obstack);
4847 if (second)
4848 pedwarn (ellipsis_loc, OPT_Wpedantic,
4849 "ISO C forbids specifying range of elements to initialize");
4850 }
4851 else
4852 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
4853 "expected %<]%>");
4854 }
4855 }
4856 if (des_seen >= 1)
4857 {
4858 if (c_parser_next_token_is (parser, CPP_EQ))
4859 {
4860 pedwarn_c90 (des_loc, OPT_Wpedantic,
4861 "ISO C90 forbids specifying subobject "
4862 "to initialize");
4863 c_parser_consume_token (parser);
4864 }
4865 else
4866 {
4867 if (des_seen == 1)
4868 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
4869 "obsolete use of designated initializer without %<=%>");
4870 else
4871 {
4872 struct c_expr init;
4873 init.set_error ();
4874 init.original_code = ERROR_MARK;
4875 init.original_type = NULL;
4876 c_parser_error (parser, "expected %<=%>");
4877 c_parser_skip_until_found (parser, CPP_COMMA, NULL);
4878 process_init_element (input_location, init, false,
4879 braced_init_obstack);
4880 return;
4881 }
4882 }
4883 }
4884 }
4885 c_parser_initval (parser, NULL, braced_init_obstack);
4886 }
4887
4888 /* Parse a nested initializer; as c_parser_initializer but parses
4889 initializers within braced lists, after any designators have been
4890 applied. If AFTER is not NULL then it is an Objective-C message
4891 expression which is the primary-expression starting the
4892 initializer. */
4893
4894 static void
4895 c_parser_initval (c_parser *parser, struct c_expr *after,
4896 struct obstack * braced_init_obstack)
4897 {
4898 struct c_expr init;
4899 gcc_assert (!after || c_dialect_objc ());
4900 location_t loc = c_parser_peek_token (parser)->location;
4901
4902 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after)
4903 init = c_parser_braced_init (parser, NULL_TREE, true,
4904 braced_init_obstack);
4905 else
4906 {
4907 init = c_parser_expr_no_commas (parser, after);
4908 if (init.value != NULL_TREE
4909 && TREE_CODE (init.value) != STRING_CST
4910 && TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR)
4911 init = convert_lvalue_to_rvalue (loc, init, true, true);
4912 }
4913 process_init_element (loc, init, false, braced_init_obstack);
4914 }
4915
4916 /* Parse a compound statement (possibly a function body) (C90 6.6.2,
4917 C99 6.8.2, C11 6.8.2).
4918
4919 compound-statement:
4920 { block-item-list[opt] }
4921 { label-declarations block-item-list }
4922
4923 block-item-list:
4924 block-item
4925 block-item-list block-item
4926
4927 block-item:
4928 nested-declaration
4929 statement
4930
4931 nested-declaration:
4932 declaration
4933
4934 GNU extensions:
4935
4936 compound-statement:
4937 { label-declarations block-item-list }
4938
4939 nested-declaration:
4940 __extension__ nested-declaration
4941 nested-function-definition
4942
4943 label-declarations:
4944 label-declaration
4945 label-declarations label-declaration
4946
4947 label-declaration:
4948 __label__ identifier-list ;
4949
4950 Allowing the mixing of declarations and code is new in C99. The
4951 GNU syntax also permits (not shown above) labels at the end of
4952 compound statements, which yield an error. We don't allow labels
4953 on declarations; this might seem like a natural extension, but
4954 there would be a conflict between gnu-attributes on the label and
4955 prefix gnu-attributes on the declaration. ??? The syntax follows the
4956 old parser in requiring something after label declarations.
4957 Although they are erroneous if the labels declared aren't defined,
4958 is it useful for the syntax to be this way?
4959
4960 OpenACC:
4961
4962 block-item:
4963 openacc-directive
4964
4965 openacc-directive:
4966 update-directive
4967
4968 OpenMP:
4969
4970 block-item:
4971 openmp-directive
4972
4973 openmp-directive:
4974 barrier-directive
4975 flush-directive
4976 taskwait-directive
4977 taskyield-directive
4978 cancel-directive
4979 cancellation-point-directive */
4980
4981 static tree
4982 c_parser_compound_statement (c_parser *parser)
4983 {
4984 tree stmt;
4985 location_t brace_loc;
4986 brace_loc = c_parser_peek_token (parser)->location;
4987 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
4988 {
4989 /* Ensure a scope is entered and left anyway to avoid confusion
4990 if we have just prepared to enter a function body. */
4991 stmt = c_begin_compound_stmt (true);
4992 c_end_compound_stmt (brace_loc, stmt, true);
4993 return error_mark_node;
4994 }
4995 stmt = c_begin_compound_stmt (true);
4996 c_parser_compound_statement_nostart (parser);
4997
4998 return c_end_compound_stmt (brace_loc, stmt, true);
4999 }
5000
5001 /* Parse a compound statement except for the opening brace. This is
5002 used for parsing both compound statements and statement expressions
5003 (which follow different paths to handling the opening). */
5004
5005 static void
5006 c_parser_compound_statement_nostart (c_parser *parser)
5007 {
5008 bool last_stmt = false;
5009 bool last_label = false;
5010 bool save_valid_for_pragma = valid_location_for_stdc_pragma_p ();
5011 location_t label_loc = UNKNOWN_LOCATION; /* Quiet warning. */
5012 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5013 {
5014 add_debug_begin_stmt (c_parser_peek_token (parser)->location);
5015 c_parser_consume_token (parser);
5016 return;
5017 }
5018 mark_valid_location_for_stdc_pragma (true);
5019 if (c_parser_next_token_is_keyword (parser, RID_LABEL))
5020 {
5021 /* Read zero or more forward-declarations for labels that nested
5022 functions can jump to. */
5023 mark_valid_location_for_stdc_pragma (false);
5024 while (c_parser_next_token_is_keyword (parser, RID_LABEL))
5025 {
5026 label_loc = c_parser_peek_token (parser)->location;
5027 c_parser_consume_token (parser);
5028 /* Any identifiers, including those declared as type names,
5029 are OK here. */
5030 while (true)
5031 {
5032 tree label;
5033 if (c_parser_next_token_is_not (parser, CPP_NAME))
5034 {
5035 c_parser_error (parser, "expected identifier");
5036 break;
5037 }
5038 label
5039 = declare_label (c_parser_peek_token (parser)->value);
5040 C_DECLARED_LABEL_FLAG (label) = 1;
5041 add_stmt (build_stmt (label_loc, DECL_EXPR, label));
5042 c_parser_consume_token (parser);
5043 if (c_parser_next_token_is (parser, CPP_COMMA))
5044 c_parser_consume_token (parser);
5045 else
5046 break;
5047 }
5048 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
5049 }
5050 pedwarn (label_loc, OPT_Wpedantic, "ISO C forbids label declarations");
5051 }
5052 /* We must now have at least one statement, label or declaration. */
5053 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
5054 {
5055 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5056 c_parser_error (parser, "expected declaration or statement");
5057 c_parser_consume_token (parser);
5058 return;
5059 }
5060 while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
5061 {
5062 location_t loc = c_parser_peek_token (parser)->location;
5063 loc = expansion_point_location_if_in_system_header (loc);
5064 if (c_parser_next_token_is_keyword (parser, RID_CASE)
5065 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
5066 || (c_parser_next_token_is (parser, CPP_NAME)
5067 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5068 {
5069 if (c_parser_next_token_is_keyword (parser, RID_CASE))
5070 label_loc = c_parser_peek_2nd_token (parser)->location;
5071 else
5072 label_loc = c_parser_peek_token (parser)->location;
5073 last_label = true;
5074 last_stmt = false;
5075 mark_valid_location_for_stdc_pragma (false);
5076 c_parser_label (parser);
5077 }
5078 else if (!last_label
5079 && c_parser_next_tokens_start_declaration (parser))
5080 {
5081 last_label = false;
5082 mark_valid_location_for_stdc_pragma (false);
5083 bool fallthru_attr_p = false;
5084 c_parser_declaration_or_fndef (parser, true, true, true, true,
5085 true, NULL, vNULL, NULL,
5086 &fallthru_attr_p);
5087 if (last_stmt && !fallthru_attr_p)
5088 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
5089 "ISO C90 forbids mixed declarations and code");
5090 last_stmt = fallthru_attr_p;
5091 }
5092 else if (!last_label
5093 && c_parser_next_token_is_keyword (parser, RID_EXTENSION))
5094 {
5095 /* __extension__ can start a declaration, but is also an
5096 unary operator that can start an expression. Consume all
5097 but the last of a possible series of __extension__ to
5098 determine which. */
5099 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
5100 && (c_parser_peek_2nd_token (parser)->keyword
5101 == RID_EXTENSION))
5102 c_parser_consume_token (parser);
5103 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser)))
5104 {
5105 int ext;
5106 ext = disable_extension_diagnostics ();
5107 c_parser_consume_token (parser);
5108 last_label = false;
5109 mark_valid_location_for_stdc_pragma (false);
5110 c_parser_declaration_or_fndef (parser, true, true, true, true,
5111 true, NULL, vNULL);
5112 /* Following the old parser, __extension__ does not
5113 disable this diagnostic. */
5114 restore_extension_diagnostics (ext);
5115 if (last_stmt)
5116 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
5117 "ISO C90 forbids mixed declarations and code");
5118 last_stmt = false;
5119 }
5120 else
5121 goto statement;
5122 }
5123 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
5124 {
5125 /* External pragmas, and some omp pragmas, are not associated
5126 with regular c code, and so are not to be considered statements
5127 syntactically. This ensures that the user doesn't put them
5128 places that would turn into syntax errors if the directive
5129 were ignored. */
5130 if (c_parser_pragma (parser,
5131 last_label ? pragma_stmt : pragma_compound,
5132 NULL))
5133 last_label = false, last_stmt = true;
5134 }
5135 else if (c_parser_next_token_is (parser, CPP_EOF))
5136 {
5137 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5138 c_parser_error (parser, "expected declaration or statement");
5139 return;
5140 }
5141 else if (c_parser_next_token_is_keyword (parser, RID_ELSE))
5142 {
5143 if (parser->in_if_block)
5144 {
5145 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5146 error_at (loc, "expected %<}%> before %<else%>");
5147 return;
5148 }
5149 else
5150 {
5151 error_at (loc, "%<else%> without a previous %<if%>");
5152 c_parser_consume_token (parser);
5153 continue;
5154 }
5155 }
5156 else
5157 {
5158 statement:
5159 last_label = false;
5160 last_stmt = true;
5161 mark_valid_location_for_stdc_pragma (false);
5162 c_parser_statement_after_labels (parser, NULL);
5163 }
5164
5165 parser->error = false;
5166 }
5167 if (last_label)
5168 error_at (label_loc, "label at end of compound statement");
5169 c_parser_consume_token (parser);
5170 /* Restore the value we started with. */
5171 mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
5172 }
5173
5174 /* Parse all consecutive labels. */
5175
5176 static void
5177 c_parser_all_labels (c_parser *parser)
5178 {
5179 while (c_parser_next_token_is_keyword (parser, RID_CASE)
5180 || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
5181 || (c_parser_next_token_is (parser, CPP_NAME)
5182 && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
5183 c_parser_label (parser);
5184 }
5185
5186 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
5187
5188 label:
5189 identifier : gnu-attributes[opt]
5190 case constant-expression :
5191 default :
5192
5193 GNU extensions:
5194
5195 label:
5196 case constant-expression ... constant-expression :
5197
5198 The use of gnu-attributes on labels is a GNU extension. The syntax in
5199 GNU C accepts any expressions without commas, non-constant
5200 expressions being rejected later. */
5201
5202 static void
5203 c_parser_label (c_parser *parser)
5204 {
5205 location_t loc1 = c_parser_peek_token (parser)->location;
5206 tree label = NULL_TREE;
5207
5208 /* Remember whether this case or a user-defined label is allowed to fall
5209 through to. */
5210 bool fallthrough_p = c_parser_peek_token (parser)->flags & PREV_FALLTHROUGH;
5211
5212 if (c_parser_next_token_is_keyword (parser, RID_CASE))
5213 {
5214 tree exp1, exp2;
5215 c_parser_consume_token (parser);
5216 exp1 = c_parser_expr_no_commas (parser, NULL).value;
5217 if (c_parser_next_token_is (parser, CPP_COLON))
5218 {
5219 c_parser_consume_token (parser);
5220 label = do_case (loc1, exp1, NULL_TREE);
5221 }
5222 else if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
5223 {
5224 c_parser_consume_token (parser);
5225 exp2 = c_parser_expr_no_commas (parser, NULL).value;
5226 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
5227 label = do_case (loc1, exp1, exp2);
5228 }
5229 else
5230 c_parser_error (parser, "expected %<:%> or %<...%>");
5231 }
5232 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
5233 {
5234 c_parser_consume_token (parser);
5235 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
5236 label = do_case (loc1, NULL_TREE, NULL_TREE);
5237 }
5238 else
5239 {
5240 tree name = c_parser_peek_token (parser)->value;
5241 tree tlab;
5242 tree attrs;
5243 location_t loc2 = c_parser_peek_token (parser)->location;
5244 gcc_assert (c_parser_next_token_is (parser, CPP_NAME));
5245 c_parser_consume_token (parser);
5246 gcc_assert (c_parser_next_token_is (parser, CPP_COLON));
5247 c_parser_consume_token (parser);
5248 attrs = c_parser_gnu_attributes (parser);
5249 tlab = define_label (loc2, name);
5250 if (tlab)
5251 {
5252 decl_attributes (&tlab, attrs, 0);
5253 label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab));
5254 }
5255 }
5256 if (label)
5257 {
5258 if (TREE_CODE (label) == LABEL_EXPR)
5259 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label)) = fallthrough_p;
5260 else
5261 FALLTHROUGH_LABEL_P (CASE_LABEL (label)) = fallthrough_p;
5262
5263 /* Allow '__attribute__((fallthrough));'. */
5264 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
5265 {
5266 location_t loc = c_parser_peek_token (parser)->location;
5267 tree attrs = c_parser_gnu_attributes (parser);
5268 if (attribute_fallthrough_p (attrs))
5269 {
5270 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5271 {
5272 tree fn = build_call_expr_internal_loc (loc,
5273 IFN_FALLTHROUGH,
5274 void_type_node, 0);
5275 add_stmt (fn);
5276 }
5277 else
5278 warning_at (loc, OPT_Wattributes, "%<fallthrough%> attribute "
5279 "not followed by %<;%>");
5280 }
5281 else if (attrs != NULL_TREE)
5282 warning_at (loc, OPT_Wattributes, "only attribute %<fallthrough%>"
5283 " can be applied to a null statement");
5284 }
5285 if (c_parser_next_tokens_start_declaration (parser))
5286 {
5287 error_at (c_parser_peek_token (parser)->location,
5288 "a label can only be part of a statement and "
5289 "a declaration is not a statement");
5290 c_parser_declaration_or_fndef (parser, /*fndef_ok*/ false,
5291 /*static_assert_ok*/ true,
5292 /*empty_ok*/ true, /*nested*/ true,
5293 /*start_attr_ok*/ true, NULL,
5294 vNULL);
5295 }
5296 }
5297 }
5298
5299 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
5300
5301 statement:
5302 labeled-statement
5303 compound-statement
5304 expression-statement
5305 selection-statement
5306 iteration-statement
5307 jump-statement
5308
5309 labeled-statement:
5310 label statement
5311
5312 expression-statement:
5313 expression[opt] ;
5314
5315 selection-statement:
5316 if-statement
5317 switch-statement
5318
5319 iteration-statement:
5320 while-statement
5321 do-statement
5322 for-statement
5323
5324 jump-statement:
5325 goto identifier ;
5326 continue ;
5327 break ;
5328 return expression[opt] ;
5329
5330 GNU extensions:
5331
5332 statement:
5333 asm-statement
5334
5335 jump-statement:
5336 goto * expression ;
5337
5338 expression-statement:
5339 gnu-attributes ;
5340
5341 Objective-C:
5342
5343 statement:
5344 objc-throw-statement
5345 objc-try-catch-statement
5346 objc-synchronized-statement
5347
5348 objc-throw-statement:
5349 @throw expression ;
5350 @throw ;
5351
5352 OpenACC:
5353
5354 statement:
5355 openacc-construct
5356
5357 openacc-construct:
5358 parallel-construct
5359 kernels-construct
5360 data-construct
5361 loop-construct
5362
5363 parallel-construct:
5364 parallel-directive structured-block
5365
5366 kernels-construct:
5367 kernels-directive structured-block
5368
5369 data-construct:
5370 data-directive structured-block
5371
5372 loop-construct:
5373 loop-directive structured-block
5374
5375 OpenMP:
5376
5377 statement:
5378 openmp-construct
5379
5380 openmp-construct:
5381 parallel-construct
5382 for-construct
5383 simd-construct
5384 for-simd-construct
5385 sections-construct
5386 single-construct
5387 parallel-for-construct
5388 parallel-for-simd-construct
5389 parallel-sections-construct
5390 master-construct
5391 critical-construct
5392 atomic-construct
5393 ordered-construct
5394
5395 parallel-construct:
5396 parallel-directive structured-block
5397
5398 for-construct:
5399 for-directive iteration-statement
5400
5401 simd-construct:
5402 simd-directive iteration-statements
5403
5404 for-simd-construct:
5405 for-simd-directive iteration-statements
5406
5407 sections-construct:
5408 sections-directive section-scope
5409
5410 single-construct:
5411 single-directive structured-block
5412
5413 parallel-for-construct:
5414 parallel-for-directive iteration-statement
5415
5416 parallel-for-simd-construct:
5417 parallel-for-simd-directive iteration-statement
5418
5419 parallel-sections-construct:
5420 parallel-sections-directive section-scope
5421
5422 master-construct:
5423 master-directive structured-block
5424
5425 critical-construct:
5426 critical-directive structured-block
5427
5428 atomic-construct:
5429 atomic-directive expression-statement
5430
5431 ordered-construct:
5432 ordered-directive structured-block
5433
5434 Transactional Memory:
5435
5436 statement:
5437 transaction-statement
5438 transaction-cancel-statement
5439
5440 IF_P is used to track whether there's a (possibly labeled) if statement
5441 which is not enclosed in braces and has an else clause. This is used to
5442 implement -Wparentheses. */
5443
5444 static void
5445 c_parser_statement (c_parser *parser, bool *if_p, location_t *loc_after_labels)
5446 {
5447 c_parser_all_labels (parser);
5448 if (loc_after_labels)
5449 *loc_after_labels = c_parser_peek_token (parser)->location;
5450 c_parser_statement_after_labels (parser, if_p, NULL);
5451 }
5452
5453 /* Parse a statement, other than a labeled statement. CHAIN is a vector
5454 of if-else-if conditions.
5455
5456 IF_P is used to track whether there's a (possibly labeled) if statement
5457 which is not enclosed in braces and has an else clause. This is used to
5458 implement -Wparentheses. */
5459
5460 static void
5461 c_parser_statement_after_labels (c_parser *parser, bool *if_p,
5462 vec<tree> *chain)
5463 {
5464 location_t loc = c_parser_peek_token (parser)->location;
5465 tree stmt = NULL_TREE;
5466 bool in_if_block = parser->in_if_block;
5467 parser->in_if_block = false;
5468 if (if_p != NULL)
5469 *if_p = false;
5470
5471 if (c_parser_peek_token (parser)->type != CPP_OPEN_BRACE)
5472 add_debug_begin_stmt (loc);
5473
5474 switch (c_parser_peek_token (parser)->type)
5475 {
5476 case CPP_OPEN_BRACE:
5477 add_stmt (c_parser_compound_statement (parser));
5478 break;
5479 case CPP_KEYWORD:
5480 switch (c_parser_peek_token (parser)->keyword)
5481 {
5482 case RID_IF:
5483 c_parser_if_statement (parser, if_p, chain);
5484 break;
5485 case RID_SWITCH:
5486 c_parser_switch_statement (parser, if_p);
5487 break;
5488 case RID_WHILE:
5489 c_parser_while_statement (parser, false, 0, if_p);
5490 break;
5491 case RID_DO:
5492 c_parser_do_statement (parser, 0, false);
5493 break;
5494 case RID_FOR:
5495 c_parser_for_statement (parser, false, 0, if_p);
5496 break;
5497 case RID_GOTO:
5498 c_parser_consume_token (parser);
5499 if (c_parser_next_token_is (parser, CPP_NAME))
5500 {
5501 stmt = c_finish_goto_label (loc,
5502 c_parser_peek_token (parser)->value);
5503 c_parser_consume_token (parser);
5504 }
5505 else if (c_parser_next_token_is (parser, CPP_MULT))
5506 {
5507 struct c_expr val;
5508
5509 c_parser_consume_token (parser);
5510 val = c_parser_expression (parser);
5511 val = convert_lvalue_to_rvalue (loc, val, false, true);
5512 stmt = c_finish_goto_ptr (loc, val.value);
5513 }
5514 else
5515 c_parser_error (parser, "expected identifier or %<*%>");
5516 goto expect_semicolon;
5517 case RID_CONTINUE:
5518 c_parser_consume_token (parser);
5519 stmt = c_finish_bc_stmt (loc, &c_cont_label, false);
5520 goto expect_semicolon;
5521 case RID_BREAK:
5522 c_parser_consume_token (parser);
5523 stmt = c_finish_bc_stmt (loc, &c_break_label, true);
5524 goto expect_semicolon;
5525 case RID_RETURN:
5526 c_parser_consume_token (parser);
5527 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5528 {
5529 stmt = c_finish_return (loc, NULL_TREE, NULL_TREE);
5530 c_parser_consume_token (parser);
5531 }
5532 else
5533 {
5534 location_t xloc = c_parser_peek_token (parser)->location;
5535 struct c_expr expr = c_parser_expression_conv (parser);
5536 mark_exp_read (expr.value);
5537 stmt = c_finish_return (EXPR_LOC_OR_LOC (expr.value, xloc),
5538 expr.value, expr.original_type);
5539 goto expect_semicolon;
5540 }
5541 break;
5542 case RID_ASM:
5543 stmt = c_parser_asm_statement (parser);
5544 break;
5545 case RID_TRANSACTION_ATOMIC:
5546 case RID_TRANSACTION_RELAXED:
5547 stmt = c_parser_transaction (parser,
5548 c_parser_peek_token (parser)->keyword);
5549 break;
5550 case RID_TRANSACTION_CANCEL:
5551 stmt = c_parser_transaction_cancel (parser);
5552 goto expect_semicolon;
5553 case RID_AT_THROW:
5554 gcc_assert (c_dialect_objc ());
5555 c_parser_consume_token (parser);
5556 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5557 {
5558 stmt = objc_build_throw_stmt (loc, NULL_TREE);
5559 c_parser_consume_token (parser);
5560 }
5561 else
5562 {
5563 struct c_expr expr = c_parser_expression (parser);
5564 expr = convert_lvalue_to_rvalue (loc, expr, false, false);
5565 expr.value = c_fully_fold (expr.value, false, NULL);
5566 stmt = objc_build_throw_stmt (loc, expr.value);
5567 goto expect_semicolon;
5568 }
5569 break;
5570 case RID_AT_TRY:
5571 gcc_assert (c_dialect_objc ());
5572 c_parser_objc_try_catch_finally_statement (parser);
5573 break;
5574 case RID_AT_SYNCHRONIZED:
5575 gcc_assert (c_dialect_objc ());
5576 c_parser_objc_synchronized_statement (parser);
5577 break;
5578 case RID_ATTRIBUTE:
5579 {
5580 /* Allow '__attribute__((fallthrough));'. */
5581 tree attrs = c_parser_gnu_attributes (parser);
5582 if (attribute_fallthrough_p (attrs))
5583 {
5584 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5585 {
5586 tree fn = build_call_expr_internal_loc (loc,
5587 IFN_FALLTHROUGH,
5588 void_type_node, 0);
5589 add_stmt (fn);
5590 /* Eat the ';'. */
5591 c_parser_consume_token (parser);
5592 }
5593 else
5594 warning_at (loc, OPT_Wattributes,
5595 "%<fallthrough%> attribute not followed "
5596 "by %<;%>");
5597 }
5598 else if (attrs != NULL_TREE)
5599 warning_at (loc, OPT_Wattributes, "only attribute %<fallthrough%>"
5600 " can be applied to a null statement");
5601 break;
5602 }
5603 default:
5604 goto expr_stmt;
5605 }
5606 break;
5607 case CPP_SEMICOLON:
5608 c_parser_consume_token (parser);
5609 break;
5610 case CPP_CLOSE_PAREN:
5611 case CPP_CLOSE_SQUARE:
5612 /* Avoid infinite loop in error recovery:
5613 c_parser_skip_until_found stops at a closing nesting
5614 delimiter without consuming it, but here we need to consume
5615 it to proceed further. */
5616 c_parser_error (parser, "expected statement");
5617 c_parser_consume_token (parser);
5618 break;
5619 case CPP_PRAGMA:
5620 c_parser_pragma (parser, pragma_stmt, if_p);
5621 break;
5622 default:
5623 expr_stmt:
5624 stmt = c_finish_expr_stmt (loc, c_parser_expression_conv (parser).value);
5625 expect_semicolon:
5626 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
5627 break;
5628 }
5629 /* Two cases cannot and do not have line numbers associated: If stmt
5630 is degenerate, such as "2;", then stmt is an INTEGER_CST, which
5631 cannot hold line numbers. But that's OK because the statement
5632 will either be changed to a MODIFY_EXPR during gimplification of
5633 the statement expr, or discarded. If stmt was compound, but
5634 without new variables, we will have skipped the creation of a
5635 BIND and will have a bare STATEMENT_LIST. But that's OK because
5636 (recursively) all of the component statements should already have
5637 line numbers assigned. ??? Can we discard no-op statements
5638 earlier? */
5639 if (EXPR_LOCATION (stmt) == UNKNOWN_LOCATION)
5640 protected_set_expr_location (stmt, loc);
5641
5642 parser->in_if_block = in_if_block;
5643 }
5644
5645 /* Parse the condition from an if, do, while or for statements. */
5646
5647 static tree
5648 c_parser_condition (c_parser *parser)
5649 {
5650 location_t loc = c_parser_peek_token (parser)->location;
5651 tree cond;
5652 cond = c_parser_expression_conv (parser).value;
5653 cond = c_objc_common_truthvalue_conversion (loc, cond);
5654 cond = c_fully_fold (cond, false, NULL);
5655 if (warn_sequence_point)
5656 verify_sequence_points (cond);
5657 return cond;
5658 }
5659
5660 /* Parse a parenthesized condition from an if, do or while statement.
5661
5662 condition:
5663 ( expression )
5664 */
5665 static tree
5666 c_parser_paren_condition (c_parser *parser)
5667 {
5668 tree cond;
5669 matching_parens parens;
5670 if (!parens.require_open (parser))
5671 return error_mark_node;
5672 cond = c_parser_condition (parser);
5673 parens.skip_until_found_close (parser);
5674 return cond;
5675 }
5676
5677 /* Parse a statement which is a block in C99.
5678
5679 IF_P is used to track whether there's a (possibly labeled) if statement
5680 which is not enclosed in braces and has an else clause. This is used to
5681 implement -Wparentheses. */
5682
5683 static tree
5684 c_parser_c99_block_statement (c_parser *parser, bool *if_p,
5685 location_t *loc_after_labels)
5686 {
5687 tree block = c_begin_compound_stmt (flag_isoc99);
5688 location_t loc = c_parser_peek_token (parser)->location;
5689 c_parser_statement (parser, if_p, loc_after_labels);
5690 return c_end_compound_stmt (loc, block, flag_isoc99);
5691 }
5692
5693 /* Parse the body of an if statement. This is just parsing a
5694 statement but (a) it is a block in C99, (b) we track whether the
5695 body is an if statement for the sake of -Wparentheses warnings, (c)
5696 we handle an empty body specially for the sake of -Wempty-body
5697 warnings, and (d) we call parser_compound_statement directly
5698 because c_parser_statement_after_labels resets
5699 parser->in_if_block.
5700
5701 IF_P is used to track whether there's a (possibly labeled) if statement
5702 which is not enclosed in braces and has an else clause. This is used to
5703 implement -Wparentheses. */
5704
5705 static tree
5706 c_parser_if_body (c_parser *parser, bool *if_p,
5707 const token_indent_info &if_tinfo)
5708 {
5709 tree block = c_begin_compound_stmt (flag_isoc99);
5710 location_t body_loc = c_parser_peek_token (parser)->location;
5711 location_t body_loc_after_labels = UNKNOWN_LOCATION;
5712 token_indent_info body_tinfo
5713 = get_token_indent_info (c_parser_peek_token (parser));
5714
5715 c_parser_all_labels (parser);
5716 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5717 {
5718 location_t loc = c_parser_peek_token (parser)->location;
5719 add_stmt (build_empty_stmt (loc));
5720 c_parser_consume_token (parser);
5721 if (!c_parser_next_token_is_keyword (parser, RID_ELSE))
5722 warning_at (loc, OPT_Wempty_body,
5723 "suggest braces around empty body in an %<if%> statement");
5724 }
5725 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
5726 add_stmt (c_parser_compound_statement (parser));
5727 else
5728 {
5729 body_loc_after_labels = c_parser_peek_token (parser)->location;
5730 c_parser_statement_after_labels (parser, if_p);
5731 }
5732
5733 token_indent_info next_tinfo
5734 = get_token_indent_info (c_parser_peek_token (parser));
5735 warn_for_misleading_indentation (if_tinfo, body_tinfo, next_tinfo);
5736 if (body_loc_after_labels != UNKNOWN_LOCATION
5737 && next_tinfo.type != CPP_SEMICOLON)
5738 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
5739 if_tinfo.location, RID_IF);
5740
5741 return c_end_compound_stmt (body_loc, block, flag_isoc99);
5742 }
5743
5744 /* Parse the else body of an if statement. This is just parsing a
5745 statement but (a) it is a block in C99, (b) we handle an empty body
5746 specially for the sake of -Wempty-body warnings. CHAIN is a vector
5747 of if-else-if conditions. */
5748
5749 static tree
5750 c_parser_else_body (c_parser *parser, const token_indent_info &else_tinfo,
5751 vec<tree> *chain)
5752 {
5753 location_t body_loc = c_parser_peek_token (parser)->location;
5754 tree block = c_begin_compound_stmt (flag_isoc99);
5755 token_indent_info body_tinfo
5756 = get_token_indent_info (c_parser_peek_token (parser));
5757 location_t body_loc_after_labels = UNKNOWN_LOCATION;
5758
5759 c_parser_all_labels (parser);
5760 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
5761 {
5762 location_t loc = c_parser_peek_token (parser)->location;
5763 warning_at (loc,
5764 OPT_Wempty_body,
5765 "suggest braces around empty body in an %<else%> statement");
5766 add_stmt (build_empty_stmt (loc));
5767 c_parser_consume_token (parser);
5768 }
5769 else
5770 {
5771 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
5772 body_loc_after_labels = c_parser_peek_token (parser)->location;
5773 c_parser_statement_after_labels (parser, NULL, chain);
5774 }
5775
5776 token_indent_info next_tinfo
5777 = get_token_indent_info (c_parser_peek_token (parser));
5778 warn_for_misleading_indentation (else_tinfo, body_tinfo, next_tinfo);
5779 if (body_loc_after_labels != UNKNOWN_LOCATION
5780 && next_tinfo.type != CPP_SEMICOLON)
5781 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
5782 else_tinfo.location, RID_ELSE);
5783
5784 return c_end_compound_stmt (body_loc, block, flag_isoc99);
5785 }
5786
5787 /* We might need to reclassify any previously-lexed identifier, e.g.
5788 when we've left a for loop with an if-statement without else in the
5789 body - we might have used a wrong scope for the token. See PR67784. */
5790
5791 static void
5792 c_parser_maybe_reclassify_token (c_parser *parser)
5793 {
5794 if (c_parser_next_token_is (parser, CPP_NAME))
5795 {
5796 c_token *token = c_parser_peek_token (parser);
5797
5798 if (token->id_kind != C_ID_CLASSNAME)
5799 {
5800 tree decl = lookup_name (token->value);
5801
5802 token->id_kind = C_ID_ID;
5803 if (decl)
5804 {
5805 if (TREE_CODE (decl) == TYPE_DECL)
5806 token->id_kind = C_ID_TYPENAME;
5807 }
5808 else if (c_dialect_objc ())
5809 {
5810 tree objc_interface_decl = objc_is_class_name (token->value);
5811 /* Objective-C class names are in the same namespace as
5812 variables and typedefs, and hence are shadowed by local
5813 declarations. */
5814 if (objc_interface_decl)
5815 {
5816 token->value = objc_interface_decl;
5817 token->id_kind = C_ID_CLASSNAME;
5818 }
5819 }
5820 }
5821 }
5822 }
5823
5824 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
5825
5826 if-statement:
5827 if ( expression ) statement
5828 if ( expression ) statement else statement
5829
5830 CHAIN is a vector of if-else-if conditions.
5831 IF_P is used to track whether there's a (possibly labeled) if statement
5832 which is not enclosed in braces and has an else clause. This is used to
5833 implement -Wparentheses. */
5834
5835 static void
5836 c_parser_if_statement (c_parser *parser, bool *if_p, vec<tree> *chain)
5837 {
5838 tree block;
5839 location_t loc;
5840 tree cond;
5841 bool nested_if = false;
5842 tree first_body, second_body;
5843 bool in_if_block;
5844
5845 gcc_assert (c_parser_next_token_is_keyword (parser, RID_IF));
5846 token_indent_info if_tinfo
5847 = get_token_indent_info (c_parser_peek_token (parser));
5848 c_parser_consume_token (parser);
5849 block = c_begin_compound_stmt (flag_isoc99);
5850 loc = c_parser_peek_token (parser)->location;
5851 cond = c_parser_paren_condition (parser);
5852 in_if_block = parser->in_if_block;
5853 parser->in_if_block = true;
5854 first_body = c_parser_if_body (parser, &nested_if, if_tinfo);
5855 parser->in_if_block = in_if_block;
5856
5857 if (warn_duplicated_cond)
5858 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond), cond, &chain);
5859
5860 if (c_parser_next_token_is_keyword (parser, RID_ELSE))
5861 {
5862 token_indent_info else_tinfo
5863 = get_token_indent_info (c_parser_peek_token (parser));
5864 c_parser_consume_token (parser);
5865 if (warn_duplicated_cond)
5866 {
5867 if (c_parser_next_token_is_keyword (parser, RID_IF)
5868 && chain == NULL)
5869 {
5870 /* We've got "if (COND) else if (COND2)". Start the
5871 condition chain and add COND as the first element. */
5872 chain = new vec<tree> ();
5873 if (!CONSTANT_CLASS_P (cond) && !TREE_SIDE_EFFECTS (cond))
5874 chain->safe_push (cond);
5875 }
5876 else if (!c_parser_next_token_is_keyword (parser, RID_IF))
5877 {
5878 /* This is if-else without subsequent if. Zap the condition
5879 chain; we would have already warned at this point. */
5880 delete chain;
5881 chain = NULL;
5882 }
5883 }
5884 second_body = c_parser_else_body (parser, else_tinfo, chain);
5885 /* Set IF_P to true to indicate that this if statement has an
5886 else clause. This may trigger the Wparentheses warning
5887 below when we get back up to the parent if statement. */
5888 if (if_p != NULL)
5889 *if_p = true;
5890 }
5891 else
5892 {
5893 second_body = NULL_TREE;
5894
5895 /* Diagnose an ambiguous else if if-then-else is nested inside
5896 if-then. */
5897 if (nested_if)
5898 warning_at (loc, OPT_Wdangling_else,
5899 "suggest explicit braces to avoid ambiguous %<else%>");
5900
5901 if (warn_duplicated_cond)
5902 {
5903 /* This if statement does not have an else clause. We don't
5904 need the condition chain anymore. */
5905 delete chain;
5906 chain = NULL;
5907 }
5908 }
5909 c_finish_if_stmt (loc, cond, first_body, second_body);
5910 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
5911
5912 c_parser_maybe_reclassify_token (parser);
5913 }
5914
5915 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
5916
5917 switch-statement:
5918 switch (expression) statement
5919 */
5920
5921 static void
5922 c_parser_switch_statement (c_parser *parser, bool *if_p)
5923 {
5924 struct c_expr ce;
5925 tree block, expr, body, save_break;
5926 location_t switch_loc = c_parser_peek_token (parser)->location;
5927 location_t switch_cond_loc;
5928 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH));
5929 c_parser_consume_token (parser);
5930 block = c_begin_compound_stmt (flag_isoc99);
5931 bool explicit_cast_p = false;
5932 matching_parens parens;
5933 if (parens.require_open (parser))
5934 {
5935 switch_cond_loc = c_parser_peek_token (parser)->location;
5936 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
5937 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
5938 explicit_cast_p = true;
5939 ce = c_parser_expression (parser);
5940 ce = convert_lvalue_to_rvalue (switch_cond_loc, ce, true, false);
5941 expr = ce.value;
5942 /* ??? expr has no valid location? */
5943 parens.skip_until_found_close (parser);
5944 }
5945 else
5946 {
5947 switch_cond_loc = UNKNOWN_LOCATION;
5948 expr = error_mark_node;
5949 ce.original_type = error_mark_node;
5950 }
5951 c_start_case (switch_loc, switch_cond_loc, expr, explicit_cast_p);
5952 save_break = c_break_label;
5953 c_break_label = NULL_TREE;
5954 location_t loc_after_labels;
5955 bool open_brace_p = c_parser_peek_token (parser)->type == CPP_OPEN_BRACE;
5956 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
5957 location_t next_loc = c_parser_peek_token (parser)->location;
5958 if (!open_brace_p && c_parser_peek_token (parser)->type != CPP_SEMICOLON)
5959 warn_for_multistatement_macros (loc_after_labels, next_loc, switch_loc,
5960 RID_SWITCH);
5961 if (c_break_label)
5962 {
5963 location_t here = c_parser_peek_token (parser)->location;
5964 tree t = build1 (LABEL_EXPR, void_type_node, c_break_label);
5965 SET_EXPR_LOCATION (t, here);
5966 SWITCH_BREAK_LABEL_P (c_break_label) = 1;
5967 append_to_statement_list_force (t, &body);
5968 }
5969 c_finish_case (body, ce.original_type);
5970 c_break_label = save_break;
5971 add_stmt (c_end_compound_stmt (switch_loc, block, flag_isoc99));
5972 c_parser_maybe_reclassify_token (parser);
5973 }
5974
5975 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
5976
5977 while-statement:
5978 while (expression) statement
5979
5980 IF_P is used to track whether there's a (possibly labeled) if statement
5981 which is not enclosed in braces and has an else clause. This is used to
5982 implement -Wparentheses. */
5983
5984 static void
5985 c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll,
5986 bool *if_p)
5987 {
5988 tree block, cond, body, save_break, save_cont;
5989 location_t loc;
5990 gcc_assert (c_parser_next_token_is_keyword (parser, RID_WHILE));
5991 token_indent_info while_tinfo
5992 = get_token_indent_info (c_parser_peek_token (parser));
5993 c_parser_consume_token (parser);
5994 block = c_begin_compound_stmt (flag_isoc99);
5995 loc = c_parser_peek_token (parser)->location;
5996 cond = c_parser_paren_condition (parser);
5997 if (ivdep && cond != error_mark_node)
5998 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
5999 build_int_cst (integer_type_node,
6000 annot_expr_ivdep_kind),
6001 integer_zero_node);
6002 if (unroll && cond != error_mark_node)
6003 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6004 build_int_cst (integer_type_node,
6005 annot_expr_unroll_kind),
6006 build_int_cst (integer_type_node, unroll));
6007 save_break = c_break_label;
6008 c_break_label = NULL_TREE;
6009 save_cont = c_cont_label;
6010 c_cont_label = NULL_TREE;
6011
6012 token_indent_info body_tinfo
6013 = get_token_indent_info (c_parser_peek_token (parser));
6014
6015 location_t loc_after_labels;
6016 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
6017 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6018 c_finish_loop (loc, loc, cond, UNKNOWN_LOCATION, NULL, body,
6019 c_break_label, c_cont_label, true);
6020 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6021 c_parser_maybe_reclassify_token (parser);
6022
6023 token_indent_info next_tinfo
6024 = get_token_indent_info (c_parser_peek_token (parser));
6025 warn_for_misleading_indentation (while_tinfo, body_tinfo, next_tinfo);
6026
6027 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
6028 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
6029 while_tinfo.location, RID_WHILE);
6030
6031 c_break_label = save_break;
6032 c_cont_label = save_cont;
6033 }
6034
6035 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6036
6037 do-statement:
6038 do statement while ( expression ) ;
6039 */
6040
6041 static void
6042 c_parser_do_statement (c_parser *parser, bool ivdep, unsigned short unroll)
6043 {
6044 tree block, cond, body, save_break, save_cont, new_break, new_cont;
6045 location_t loc;
6046 gcc_assert (c_parser_next_token_is_keyword (parser, RID_DO));
6047 c_parser_consume_token (parser);
6048 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6049 warning_at (c_parser_peek_token (parser)->location,
6050 OPT_Wempty_body,
6051 "suggest braces around empty body in %<do%> statement");
6052 block = c_begin_compound_stmt (flag_isoc99);
6053 loc = c_parser_peek_token (parser)->location;
6054 save_break = c_break_label;
6055 c_break_label = NULL_TREE;
6056 save_cont = c_cont_label;
6057 c_cont_label = NULL_TREE;
6058 body = c_parser_c99_block_statement (parser, NULL);
6059 c_parser_require_keyword (parser, RID_WHILE, "expected %<while%>");
6060 new_break = c_break_label;
6061 c_break_label = save_break;
6062 new_cont = c_cont_label;
6063 c_cont_label = save_cont;
6064 location_t cond_loc = c_parser_peek_token (parser)->location;
6065 cond = c_parser_paren_condition (parser);
6066 if (ivdep && cond != error_mark_node)
6067 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6068 build_int_cst (integer_type_node,
6069 annot_expr_ivdep_kind),
6070 integer_zero_node);
6071 if (unroll && cond != error_mark_node)
6072 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6073 build_int_cst (integer_type_node,
6074 annot_expr_unroll_kind),
6075 build_int_cst (integer_type_node, unroll));
6076 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
6077 c_parser_skip_to_end_of_block_or_statement (parser);
6078 c_finish_loop (loc, cond_loc, cond, UNKNOWN_LOCATION, NULL, body,
6079 new_break, new_cont, false);
6080 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
6081 }
6082
6083 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
6084
6085 for-statement:
6086 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
6087 for ( nested-declaration expression[opt] ; expression[opt] ) statement
6088
6089 The form with a declaration is new in C99.
6090
6091 ??? In accordance with the old parser, the declaration may be a
6092 nested function, which is then rejected in check_for_loop_decls,
6093 but does it make any sense for this to be included in the grammar?
6094 Note in particular that the nested function does not include a
6095 trailing ';', whereas the "declaration" production includes one.
6096 Also, can we reject bad declarations earlier and cheaper than
6097 check_for_loop_decls?
6098
6099 In Objective-C, there are two additional variants:
6100
6101 foreach-statement:
6102 for ( expression in expresssion ) statement
6103 for ( declaration in expression ) statement
6104
6105 This is inconsistent with C, because the second variant is allowed
6106 even if c99 is not enabled.
6107
6108 The rest of the comment documents these Objective-C foreach-statement.
6109
6110 Here is the canonical example of the first variant:
6111 for (object in array) { do something with object }
6112 we call the first expression ("object") the "object_expression" and
6113 the second expression ("array") the "collection_expression".
6114 object_expression must be an lvalue of type "id" (a generic Objective-C
6115 object) because the loop works by assigning to object_expression the
6116 various objects from the collection_expression. collection_expression
6117 must evaluate to something of type "id" which responds to the method
6118 countByEnumeratingWithState:objects:count:.
6119
6120 The canonical example of the second variant is:
6121 for (id object in array) { do something with object }
6122 which is completely equivalent to
6123 {
6124 id object;
6125 for (object in array) { do something with object }
6126 }
6127 Note that initizializing 'object' in some way (eg, "for ((object =
6128 xxx) in array) { do something with object }") is possibly
6129 technically valid, but completely pointless as 'object' will be
6130 assigned to something else as soon as the loop starts. We should
6131 most likely reject it (TODO).
6132
6133 The beginning of the Objective-C foreach-statement looks exactly
6134 like the beginning of the for-statement, and we can tell it is a
6135 foreach-statement only because the initial declaration or
6136 expression is terminated by 'in' instead of ';'.
6137
6138 IF_P is used to track whether there's a (possibly labeled) if statement
6139 which is not enclosed in braces and has an else clause. This is used to
6140 implement -Wparentheses. */
6141
6142 static void
6143 c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
6144 bool *if_p)
6145 {
6146 tree block, cond, incr, save_break, save_cont, body;
6147 /* The following are only used when parsing an ObjC foreach statement. */
6148 tree object_expression;
6149 /* Silence the bogus uninitialized warning. */
6150 tree collection_expression = NULL;
6151 location_t loc = c_parser_peek_token (parser)->location;
6152 location_t for_loc = loc;
6153 location_t cond_loc = UNKNOWN_LOCATION;
6154 location_t incr_loc = UNKNOWN_LOCATION;
6155 bool is_foreach_statement = false;
6156 gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
6157 token_indent_info for_tinfo
6158 = get_token_indent_info (c_parser_peek_token (parser));
6159 c_parser_consume_token (parser);
6160 /* Open a compound statement in Objective-C as well, just in case this is
6161 as foreach expression. */
6162 block = c_begin_compound_stmt (flag_isoc99 || c_dialect_objc ());
6163 cond = error_mark_node;
6164 incr = error_mark_node;
6165 matching_parens parens;
6166 if (parens.require_open (parser))
6167 {
6168 /* Parse the initialization declaration or expression. */
6169 object_expression = error_mark_node;
6170 parser->objc_could_be_foreach_context = c_dialect_objc ();
6171 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6172 {
6173 parser->objc_could_be_foreach_context = false;
6174 c_parser_consume_token (parser);
6175 c_finish_expr_stmt (loc, NULL_TREE);
6176 }
6177 else if (c_parser_next_tokens_start_declaration (parser))
6178 {
6179 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
6180 &object_expression, vNULL);
6181 parser->objc_could_be_foreach_context = false;
6182
6183 if (c_parser_next_token_is_keyword (parser, RID_IN))
6184 {
6185 c_parser_consume_token (parser);
6186 is_foreach_statement = true;
6187 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
6188 c_parser_error (parser, "multiple iterating variables in "
6189 "fast enumeration");
6190 }
6191 else
6192 check_for_loop_decls (for_loc, flag_isoc99);
6193 }
6194 else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
6195 {
6196 /* __extension__ can start a declaration, but is also an
6197 unary operator that can start an expression. Consume all
6198 but the last of a possible series of __extension__ to
6199 determine which. */
6200 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
6201 && (c_parser_peek_2nd_token (parser)->keyword
6202 == RID_EXTENSION))
6203 c_parser_consume_token (parser);
6204 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser)))
6205 {
6206 int ext;
6207 ext = disable_extension_diagnostics ();
6208 c_parser_consume_token (parser);
6209 c_parser_declaration_or_fndef (parser, true, true, true, true,
6210 true, &object_expression, vNULL);
6211 parser->objc_could_be_foreach_context = false;
6212
6213 restore_extension_diagnostics (ext);
6214 if (c_parser_next_token_is_keyword (parser, RID_IN))
6215 {
6216 c_parser_consume_token (parser);
6217 is_foreach_statement = true;
6218 if (check_for_loop_decls (for_loc, true) == NULL_TREE)
6219 c_parser_error (parser, "multiple iterating variables in "
6220 "fast enumeration");
6221 }
6222 else
6223 check_for_loop_decls (for_loc, flag_isoc99);
6224 }
6225 else
6226 goto init_expr;
6227 }
6228 else
6229 {
6230 init_expr:
6231 {
6232 struct c_expr ce;
6233 tree init_expression;
6234 ce = c_parser_expression (parser);
6235 init_expression = ce.value;
6236 parser->objc_could_be_foreach_context = false;
6237 if (c_parser_next_token_is_keyword (parser, RID_IN))
6238 {
6239 c_parser_consume_token (parser);
6240 is_foreach_statement = true;
6241 if (! lvalue_p (init_expression))
6242 c_parser_error (parser, "invalid iterating variable in "
6243 "fast enumeration");
6244 object_expression
6245 = c_fully_fold (init_expression, false, NULL);
6246 }
6247 else
6248 {
6249 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
6250 init_expression = ce.value;
6251 c_finish_expr_stmt (loc, init_expression);
6252 c_parser_skip_until_found (parser, CPP_SEMICOLON,
6253 "expected %<;%>");
6254 }
6255 }
6256 }
6257 /* Parse the loop condition. In the case of a foreach
6258 statement, there is no loop condition. */
6259 gcc_assert (!parser->objc_could_be_foreach_context);
6260 if (!is_foreach_statement)
6261 {
6262 cond_loc = c_parser_peek_token (parser)->location;
6263 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
6264 {
6265 if (ivdep)
6266 {
6267 c_parser_error (parser, "missing loop condition in loop "
6268 "with %<GCC ivdep%> pragma");
6269 cond = error_mark_node;
6270 }
6271 else if (unroll)
6272 {
6273 c_parser_error (parser, "missing loop condition in loop "
6274 "with %<GCC unroll%> pragma");
6275 cond = error_mark_node;
6276 }
6277 else
6278 {
6279 c_parser_consume_token (parser);
6280 cond = NULL_TREE;
6281 }
6282 }
6283 else
6284 {
6285 cond = c_parser_condition (parser);
6286 c_parser_skip_until_found (parser, CPP_SEMICOLON,
6287 "expected %<;%>");
6288 }
6289 if (ivdep && cond != error_mark_node)
6290 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6291 build_int_cst (integer_type_node,
6292 annot_expr_ivdep_kind),
6293 integer_zero_node);
6294 if (unroll && cond != error_mark_node)
6295 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
6296 build_int_cst (integer_type_node,
6297 annot_expr_unroll_kind),
6298 build_int_cst (integer_type_node, unroll));
6299 }
6300 /* Parse the increment expression (the third expression in a
6301 for-statement). In the case of a foreach-statement, this is
6302 the expression that follows the 'in'. */
6303 loc = incr_loc = c_parser_peek_token (parser)->location;
6304 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
6305 {
6306 if (is_foreach_statement)
6307 {
6308 c_parser_error (parser,
6309 "missing collection in fast enumeration");
6310 collection_expression = error_mark_node;
6311 }
6312 else
6313 incr = c_process_expr_stmt (loc, NULL_TREE);
6314 }
6315 else
6316 {
6317 if (is_foreach_statement)
6318 collection_expression
6319 = c_fully_fold (c_parser_expression (parser).value, false, NULL);
6320 else
6321 {
6322 struct c_expr ce = c_parser_expression (parser);
6323 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
6324 incr = c_process_expr_stmt (loc, ce.value);
6325 }
6326 }
6327 parens.skip_until_found_close (parser);
6328 }
6329 save_break = c_break_label;
6330 c_break_label = NULL_TREE;
6331 save_cont = c_cont_label;
6332 c_cont_label = NULL_TREE;
6333
6334 token_indent_info body_tinfo
6335 = get_token_indent_info (c_parser_peek_token (parser));
6336
6337 location_t loc_after_labels;
6338 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
6339 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
6340
6341 if (is_foreach_statement)
6342 objc_finish_foreach_loop (for_loc, object_expression,
6343 collection_expression, body, c_break_label,
6344 c_cont_label);
6345 else
6346 c_finish_loop (for_loc, cond_loc, cond, incr_loc, incr, body,
6347 c_break_label, c_cont_label, true);
6348 add_stmt (c_end_compound_stmt (for_loc, block,
6349 flag_isoc99 || c_dialect_objc ()));
6350 c_parser_maybe_reclassify_token (parser);
6351
6352 token_indent_info next_tinfo
6353 = get_token_indent_info (c_parser_peek_token (parser));
6354 warn_for_misleading_indentation (for_tinfo, body_tinfo, next_tinfo);
6355
6356 if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
6357 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
6358 for_tinfo.location, RID_FOR);
6359
6360 c_break_label = save_break;
6361 c_cont_label = save_cont;
6362 }
6363
6364 /* Parse an asm statement, a GNU extension. This is a full-blown asm
6365 statement with inputs, outputs, clobbers, and volatile, inline, and goto
6366 tags allowed.
6367
6368 asm-qualifier:
6369 volatile
6370 inline
6371 goto
6372
6373 asm-qualifier-list:
6374 asm-qualifier-list asm-qualifier
6375 asm-qualifier
6376
6377 asm-statement:
6378 asm asm-qualifier-list[opt] ( asm-argument ) ;
6379
6380 asm-argument:
6381 asm-string-literal
6382 asm-string-literal : asm-operands[opt]
6383 asm-string-literal : asm-operands[opt] : asm-operands[opt]
6384 asm-string-literal : asm-operands[opt] : asm-operands[opt] \
6385 : asm-clobbers[opt]
6386 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
6387 : asm-goto-operands
6388
6389 The form with asm-goto-operands is valid if and only if the
6390 asm-qualifier-list contains goto, and is the only allowed form in that case.
6391 Duplicate asm-qualifiers are not allowed.
6392
6393 The :: token is considered equivalent to two consecutive : tokens. */
6394
6395 static tree
6396 c_parser_asm_statement (c_parser *parser)
6397 {
6398 tree str, outputs, inputs, clobbers, labels, ret;
6399 bool simple;
6400 location_t asm_loc = c_parser_peek_token (parser)->location;
6401 int section, nsections;
6402
6403 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
6404 c_parser_consume_token (parser);
6405
6406 /* Handle the asm-qualifier-list. */
6407 location_t volatile_loc = UNKNOWN_LOCATION;
6408 location_t inline_loc = UNKNOWN_LOCATION;
6409 location_t goto_loc = UNKNOWN_LOCATION;
6410 for (;;)
6411 {
6412 c_token *token = c_parser_peek_token (parser);
6413 location_t loc = token->location;
6414 switch (token->keyword)
6415 {
6416 case RID_VOLATILE:
6417 if (volatile_loc)
6418 {
6419 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
6420 inform (volatile_loc, "first seen here");
6421 }
6422 else
6423 volatile_loc = loc;
6424 c_parser_consume_token (parser);
6425 continue;
6426
6427 case RID_INLINE:
6428 if (inline_loc)
6429 {
6430 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
6431 inform (inline_loc, "first seen here");
6432 }
6433 else
6434 inline_loc = loc;
6435 c_parser_consume_token (parser);
6436 continue;
6437
6438 case RID_GOTO:
6439 if (goto_loc)
6440 {
6441 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
6442 inform (goto_loc, "first seen here");
6443 }
6444 else
6445 goto_loc = loc;
6446 c_parser_consume_token (parser);
6447 continue;
6448
6449 case RID_CONST:
6450 case RID_RESTRICT:
6451 error_at (loc, "%qE is not a valid %<asm%> qualifier", token->value);
6452 c_parser_consume_token (parser);
6453 continue;
6454
6455 default:
6456 break;
6457 }
6458 break;
6459 }
6460
6461 bool is_volatile = (volatile_loc != UNKNOWN_LOCATION);
6462 bool is_inline = (inline_loc != UNKNOWN_LOCATION);
6463 bool is_goto = (goto_loc != UNKNOWN_LOCATION);
6464
6465 ret = NULL;
6466
6467 matching_parens parens;
6468 if (!parens.require_open (parser))
6469 goto error;
6470
6471 str = c_parser_asm_string_literal (parser);
6472 if (str == NULL_TREE)
6473 goto error_close_paren;
6474
6475 simple = true;
6476 outputs = NULL_TREE;
6477 inputs = NULL_TREE;
6478 clobbers = NULL_TREE;
6479 labels = NULL_TREE;
6480
6481 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
6482 goto done_asm;
6483
6484 /* Parse each colon-delimited section of operands. */
6485 nsections = 3 + is_goto;
6486 for (section = 0; section < nsections; ++section)
6487 {
6488 if (c_parser_next_token_is (parser, CPP_SCOPE))
6489 {
6490 ++section;
6491 if (section == nsections)
6492 {
6493 c_parser_error (parser, "expected %<)%>");
6494 goto error_close_paren;
6495 }
6496 c_parser_consume_token (parser);
6497 }
6498 else if (!c_parser_require (parser, CPP_COLON,
6499 is_goto
6500 ? G_("expected %<:%>")
6501 : G_("expected %<:%> or %<)%>"),
6502 UNKNOWN_LOCATION, is_goto))
6503 goto error_close_paren;
6504
6505 /* Once past any colon, we're no longer a simple asm. */
6506 simple = false;
6507
6508 if ((!c_parser_next_token_is (parser, CPP_COLON)
6509 && !c_parser_next_token_is (parser, CPP_SCOPE)
6510 && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
6511 || section == 3)
6512 switch (section)
6513 {
6514 case 0:
6515 /* For asm goto, we don't allow output operands, but reserve
6516 the slot for a future extension that does allow them. */
6517 if (!is_goto)
6518 outputs = c_parser_asm_operands (parser);
6519 break;
6520 case 1:
6521 inputs = c_parser_asm_operands (parser);
6522 break;
6523 case 2:
6524 clobbers = c_parser_asm_clobbers (parser);
6525 break;
6526 case 3:
6527 labels = c_parser_asm_goto_operands (parser);
6528 break;
6529 default:
6530 gcc_unreachable ();
6531 }
6532
6533 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
6534 goto done_asm;
6535 }
6536
6537 done_asm:
6538 if (!parens.require_close (parser))
6539 {
6540 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
6541 goto error;
6542 }
6543
6544 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
6545 c_parser_skip_to_end_of_block_or_statement (parser);
6546
6547 ret = build_asm_stmt (is_volatile,
6548 build_asm_expr (asm_loc, str, outputs, inputs,
6549 clobbers, labels, simple, is_inline));
6550
6551 error:
6552 return ret;
6553
6554 error_close_paren:
6555 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
6556 goto error;
6557 }
6558
6559 /* Parse asm operands, a GNU extension.
6560
6561 asm-operands:
6562 asm-operand
6563 asm-operands , asm-operand
6564
6565 asm-operand:
6566 asm-string-literal ( expression )
6567 [ identifier ] asm-string-literal ( expression )
6568 */
6569
6570 static tree
6571 c_parser_asm_operands (c_parser *parser)
6572 {
6573 tree list = NULL_TREE;
6574 while (true)
6575 {
6576 tree name, str;
6577 struct c_expr expr;
6578 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
6579 {
6580 c_parser_consume_token (parser);
6581 if (c_parser_next_token_is (parser, CPP_NAME))
6582 {
6583 tree id = c_parser_peek_token (parser)->value;
6584 c_parser_consume_token (parser);
6585 name = build_string (IDENTIFIER_LENGTH (id),
6586 IDENTIFIER_POINTER (id));
6587 }
6588 else
6589 {
6590 c_parser_error (parser, "expected identifier");
6591 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
6592 return NULL_TREE;
6593 }
6594 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
6595 "expected %<]%>");
6596 }
6597 else
6598 name = NULL_TREE;
6599 str = c_parser_asm_string_literal (parser);
6600 if (str == NULL_TREE)
6601 return NULL_TREE;
6602 matching_parens parens;
6603 if (!parens.require_open (parser))
6604 return NULL_TREE;
6605 expr = c_parser_expression (parser);
6606 mark_exp_read (expr.value);
6607 if (!parens.require_close (parser))
6608 {
6609 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
6610 return NULL_TREE;
6611 }
6612 list = chainon (list, build_tree_list (build_tree_list (name, str),
6613 expr.value));
6614 if (c_parser_next_token_is (parser, CPP_COMMA))
6615 c_parser_consume_token (parser);
6616 else
6617 break;
6618 }
6619 return list;
6620 }
6621
6622 /* Parse asm clobbers, a GNU extension.
6623
6624 asm-clobbers:
6625 asm-string-literal
6626 asm-clobbers , asm-string-literal
6627 */
6628
6629 static tree
6630 c_parser_asm_clobbers (c_parser *parser)
6631 {
6632 tree list = NULL_TREE;
6633 while (true)
6634 {
6635 tree str = c_parser_asm_string_literal (parser);
6636 if (str)
6637 list = tree_cons (NULL_TREE, str, list);
6638 else
6639 return NULL_TREE;
6640 if (c_parser_next_token_is (parser, CPP_COMMA))
6641 c_parser_consume_token (parser);
6642 else
6643 break;
6644 }
6645 return list;
6646 }
6647
6648 /* Parse asm goto labels, a GNU extension.
6649
6650 asm-goto-operands:
6651 identifier
6652 asm-goto-operands , identifier
6653 */
6654
6655 static tree
6656 c_parser_asm_goto_operands (c_parser *parser)
6657 {
6658 tree list = NULL_TREE;
6659 while (true)
6660 {
6661 tree name, label;
6662
6663 if (c_parser_next_token_is (parser, CPP_NAME))
6664 {
6665 c_token *tok = c_parser_peek_token (parser);
6666 name = tok->value;
6667 label = lookup_label_for_goto (tok->location, name);
6668 c_parser_consume_token (parser);
6669 TREE_USED (label) = 1;
6670 }
6671 else
6672 {
6673 c_parser_error (parser, "expected identifier");
6674 return NULL_TREE;
6675 }
6676
6677 name = build_string (IDENTIFIER_LENGTH (name),
6678 IDENTIFIER_POINTER (name));
6679 list = tree_cons (name, label, list);
6680 if (c_parser_next_token_is (parser, CPP_COMMA))
6681 c_parser_consume_token (parser);
6682 else
6683 return nreverse (list);
6684 }
6685 }
6686
6687 /* Parse a possibly concatenated sequence of string literals.
6688 TRANSLATE says whether to translate them to the execution character
6689 set; WIDE_OK says whether any kind of prefixed string literal is
6690 permitted in this context. This code is based on that in
6691 lex_string. */
6692
6693 struct c_expr
6694 c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok)
6695 {
6696 struct c_expr ret;
6697 size_t count;
6698 struct obstack str_ob;
6699 struct obstack loc_ob;
6700 cpp_string str, istr, *strs;
6701 c_token *tok;
6702 location_t loc, last_tok_loc;
6703 enum cpp_ttype type;
6704 tree value, string_tree;
6705
6706 tok = c_parser_peek_token (parser);
6707 loc = tok->location;
6708 last_tok_loc = linemap_resolve_location (line_table, loc,
6709 LRK_MACRO_DEFINITION_LOCATION,
6710 NULL);
6711 type = tok->type;
6712 switch (type)
6713 {
6714 case CPP_STRING:
6715 case CPP_WSTRING:
6716 case CPP_STRING16:
6717 case CPP_STRING32:
6718 case CPP_UTF8STRING:
6719 string_tree = tok->value;
6720 break;
6721
6722 default:
6723 c_parser_error (parser, "expected string literal");
6724 ret.set_error ();
6725 ret.value = NULL_TREE;
6726 ret.original_code = ERROR_MARK;
6727 ret.original_type = NULL_TREE;
6728 return ret;
6729 }
6730
6731 /* Try to avoid the overhead of creating and destroying an obstack
6732 for the common case of just one string. */
6733 switch (c_parser_peek_2nd_token (parser)->type)
6734 {
6735 default:
6736 c_parser_consume_token (parser);
6737 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
6738 str.len = TREE_STRING_LENGTH (string_tree);
6739 count = 1;
6740 strs = &str;
6741 break;
6742
6743 case CPP_STRING:
6744 case CPP_WSTRING:
6745 case CPP_STRING16:
6746 case CPP_STRING32:
6747 case CPP_UTF8STRING:
6748 gcc_obstack_init (&str_ob);
6749 gcc_obstack_init (&loc_ob);
6750 count = 0;
6751 do
6752 {
6753 c_parser_consume_token (parser);
6754 count++;
6755 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
6756 str.len = TREE_STRING_LENGTH (string_tree);
6757 if (type != tok->type)
6758 {
6759 if (type == CPP_STRING)
6760 type = tok->type;
6761 else if (tok->type != CPP_STRING)
6762 error ("unsupported non-standard concatenation "
6763 "of string literals");
6764 }
6765 obstack_grow (&str_ob, &str, sizeof (cpp_string));
6766 obstack_grow (&loc_ob, &last_tok_loc, sizeof (location_t));
6767 tok = c_parser_peek_token (parser);
6768 string_tree = tok->value;
6769 last_tok_loc
6770 = linemap_resolve_location (line_table, tok->location,
6771 LRK_MACRO_DEFINITION_LOCATION, NULL);
6772 }
6773 while (tok->type == CPP_STRING
6774 || tok->type == CPP_WSTRING
6775 || tok->type == CPP_STRING16
6776 || tok->type == CPP_STRING32
6777 || tok->type == CPP_UTF8STRING);
6778 strs = (cpp_string *) obstack_finish (&str_ob);
6779 }
6780
6781 if (count > 1 && !in_system_header_at (input_location))
6782 warning (OPT_Wtraditional,
6783 "traditional C rejects string constant concatenation");
6784
6785 if ((type == CPP_STRING || wide_ok)
6786 && ((translate
6787 ? cpp_interpret_string : cpp_interpret_string_notranslate)
6788 (parse_in, strs, count, &istr, type)))
6789 {
6790 value = build_string (istr.len, (const char *) istr.text);
6791 free (CONST_CAST (unsigned char *, istr.text));
6792 if (count > 1)
6793 {
6794 location_t *locs = (location_t *) obstack_finish (&loc_ob);
6795 gcc_assert (g_string_concat_db);
6796 g_string_concat_db->record_string_concatenation (count, locs);
6797 }
6798 }
6799 else
6800 {
6801 if (type != CPP_STRING && !wide_ok)
6802 {
6803 error_at (loc, "a wide string is invalid in this context");
6804 type = CPP_STRING;
6805 }
6806 /* Callers cannot generally handle error_mark_node in this
6807 context, so return the empty string instead. An error has
6808 been issued, either above or from cpp_interpret_string. */
6809 switch (type)
6810 {
6811 default:
6812 case CPP_STRING:
6813 case CPP_UTF8STRING:
6814 value = build_string (1, "");
6815 break;
6816 case CPP_STRING16:
6817 value = build_string (TYPE_PRECISION (char16_type_node)
6818 / TYPE_PRECISION (char_type_node),
6819 "\0"); /* char16_t is 16 bits */
6820 break;
6821 case CPP_STRING32:
6822 value = build_string (TYPE_PRECISION (char32_type_node)
6823 / TYPE_PRECISION (char_type_node),
6824 "\0\0\0"); /* char32_t is 32 bits */
6825 break;
6826 case CPP_WSTRING:
6827 value = build_string (TYPE_PRECISION (wchar_type_node)
6828 / TYPE_PRECISION (char_type_node),
6829 "\0\0\0"); /* widest supported wchar_t
6830 is 32 bits */
6831 break;
6832 }
6833 }
6834
6835 switch (type)
6836 {
6837 default:
6838 case CPP_STRING:
6839 case CPP_UTF8STRING:
6840 TREE_TYPE (value) = char_array_type_node;
6841 break;
6842 case CPP_STRING16:
6843 TREE_TYPE (value) = char16_array_type_node;
6844 break;
6845 case CPP_STRING32:
6846 TREE_TYPE (value) = char32_array_type_node;
6847 break;
6848 case CPP_WSTRING:
6849 TREE_TYPE (value) = wchar_array_type_node;
6850 }
6851 value = fix_string_type (value);
6852
6853 if (count > 1)
6854 {
6855 obstack_free (&str_ob, 0);
6856 obstack_free (&loc_ob, 0);
6857 }
6858
6859 ret.value = value;
6860 ret.original_code = STRING_CST;
6861 ret.original_type = NULL_TREE;
6862 set_c_expr_source_range (&ret, get_range_from_loc (line_table, loc));
6863 return ret;
6864 }
6865
6866 /* Parse an expression other than a compound expression; that is, an
6867 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If
6868 AFTER is not NULL then it is an Objective-C message expression which
6869 is the primary-expression starting the expression as an initializer.
6870
6871 assignment-expression:
6872 conditional-expression
6873 unary-expression assignment-operator assignment-expression
6874
6875 assignment-operator: one of
6876 = *= /= %= += -= <<= >>= &= ^= |=
6877
6878 In GNU C we accept any conditional expression on the LHS and
6879 diagnose the invalid lvalue rather than producing a syntax
6880 error. */
6881
6882 static struct c_expr
6883 c_parser_expr_no_commas (c_parser *parser, struct c_expr *after,
6884 tree omp_atomic_lhs)
6885 {
6886 struct c_expr lhs, rhs, ret;
6887 enum tree_code code;
6888 location_t op_location, exp_location;
6889 gcc_assert (!after || c_dialect_objc ());
6890 lhs = c_parser_conditional_expression (parser, after, omp_atomic_lhs);
6891 op_location = c_parser_peek_token (parser)->location;
6892 switch (c_parser_peek_token (parser)->type)
6893 {
6894 case CPP_EQ:
6895 code = NOP_EXPR;
6896 break;
6897 case CPP_MULT_EQ:
6898 code = MULT_EXPR;
6899 break;
6900 case CPP_DIV_EQ:
6901 code = TRUNC_DIV_EXPR;
6902 break;
6903 case CPP_MOD_EQ:
6904 code = TRUNC_MOD_EXPR;
6905 break;
6906 case CPP_PLUS_EQ:
6907 code = PLUS_EXPR;
6908 break;
6909 case CPP_MINUS_EQ:
6910 code = MINUS_EXPR;
6911 break;
6912 case CPP_LSHIFT_EQ:
6913 code = LSHIFT_EXPR;
6914 break;
6915 case CPP_RSHIFT_EQ:
6916 code = RSHIFT_EXPR;
6917 break;
6918 case CPP_AND_EQ:
6919 code = BIT_AND_EXPR;
6920 break;
6921 case CPP_XOR_EQ:
6922 code = BIT_XOR_EXPR;
6923 break;
6924 case CPP_OR_EQ:
6925 code = BIT_IOR_EXPR;
6926 break;
6927 default:
6928 return lhs;
6929 }
6930 c_parser_consume_token (parser);
6931 exp_location = c_parser_peek_token (parser)->location;
6932 rhs = c_parser_expr_no_commas (parser, NULL);
6933 rhs = convert_lvalue_to_rvalue (exp_location, rhs, true, true);
6934
6935 ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
6936 code, exp_location, rhs.value,
6937 rhs.original_type);
6938 set_c_expr_source_range (&ret, lhs.get_start (), rhs.get_finish ());
6939 if (code == NOP_EXPR)
6940 ret.original_code = MODIFY_EXPR;
6941 else
6942 {
6943 TREE_NO_WARNING (ret.value) = 1;
6944 ret.original_code = ERROR_MARK;
6945 }
6946 ret.original_type = NULL;
6947 return ret;
6948 }
6949
6950 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If
6951 AFTER is not NULL then it is an Objective-C message expression which is
6952 the primary-expression starting the expression as an initializer.
6953
6954 conditional-expression:
6955 logical-OR-expression
6956 logical-OR-expression ? expression : conditional-expression
6957
6958 GNU extensions:
6959
6960 conditional-expression:
6961 logical-OR-expression ? : conditional-expression
6962 */
6963
6964 static struct c_expr
6965 c_parser_conditional_expression (c_parser *parser, struct c_expr *after,
6966 tree omp_atomic_lhs)
6967 {
6968 struct c_expr cond, exp1, exp2, ret;
6969 location_t start, cond_loc, colon_loc;
6970
6971 gcc_assert (!after || c_dialect_objc ());
6972
6973 cond = c_parser_binary_expression (parser, after, omp_atomic_lhs);
6974
6975 if (c_parser_next_token_is_not (parser, CPP_QUERY))
6976 return cond;
6977 if (cond.value != error_mark_node)
6978 start = cond.get_start ();
6979 else
6980 start = UNKNOWN_LOCATION;
6981 cond_loc = c_parser_peek_token (parser)->location;
6982 cond = convert_lvalue_to_rvalue (cond_loc, cond, true, true);
6983 c_parser_consume_token (parser);
6984 if (c_parser_next_token_is (parser, CPP_COLON))
6985 {
6986 tree eptype = NULL_TREE;
6987
6988 location_t middle_loc = c_parser_peek_token (parser)->location;
6989 pedwarn (middle_loc, OPT_Wpedantic,
6990 "ISO C forbids omitting the middle term of a %<?:%> expression");
6991 if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR)
6992 {
6993 eptype = TREE_TYPE (cond.value);
6994 cond.value = TREE_OPERAND (cond.value, 0);
6995 }
6996 tree e = cond.value;
6997 while (TREE_CODE (e) == COMPOUND_EXPR)
6998 e = TREE_OPERAND (e, 1);
6999 warn_for_omitted_condop (middle_loc, e);
7000 /* Make sure first operand is calculated only once. */
7001 exp1.value = save_expr (default_conversion (cond.value));
7002 if (eptype)
7003 exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value);
7004 exp1.original_type = NULL;
7005 exp1.src_range = cond.src_range;
7006 cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value);
7007 c_inhibit_evaluation_warnings += cond.value == truthvalue_true_node;
7008 }
7009 else
7010 {
7011 cond.value
7012 = c_objc_common_truthvalue_conversion
7013 (cond_loc, default_conversion (cond.value));
7014 c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node;
7015 exp1 = c_parser_expression_conv (parser);
7016 mark_exp_read (exp1.value);
7017 c_inhibit_evaluation_warnings +=
7018 ((cond.value == truthvalue_true_node)
7019 - (cond.value == truthvalue_false_node));
7020 }
7021
7022 colon_loc = c_parser_peek_token (parser)->location;
7023 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
7024 {
7025 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
7026 ret.set_error ();
7027 ret.original_code = ERROR_MARK;
7028 ret.original_type = NULL;
7029 return ret;
7030 }
7031 {
7032 location_t exp2_loc = c_parser_peek_token (parser)->location;
7033 exp2 = c_parser_conditional_expression (parser, NULL, NULL_TREE);
7034 exp2 = convert_lvalue_to_rvalue (exp2_loc, exp2, true, true);
7035 }
7036 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
7037 location_t loc1 = make_location (exp1.get_start (), exp1.src_range);
7038 location_t loc2 = make_location (exp2.get_start (), exp2.src_range);
7039 ret.value = build_conditional_expr (colon_loc, cond.value,
7040 cond.original_code == C_MAYBE_CONST_EXPR,
7041 exp1.value, exp1.original_type, loc1,
7042 exp2.value, exp2.original_type, loc2);
7043 ret.original_code = ERROR_MARK;
7044 if (exp1.value == error_mark_node || exp2.value == error_mark_node)
7045 ret.original_type = NULL;
7046 else
7047 {
7048 tree t1, t2;
7049
7050 /* If both sides are enum type, the default conversion will have
7051 made the type of the result be an integer type. We want to
7052 remember the enum types we started with. */
7053 t1 = exp1.original_type ? exp1.original_type : TREE_TYPE (exp1.value);
7054 t2 = exp2.original_type ? exp2.original_type : TREE_TYPE (exp2.value);
7055 ret.original_type = ((t1 != error_mark_node
7056 && t2 != error_mark_node
7057 && (TYPE_MAIN_VARIANT (t1)
7058 == TYPE_MAIN_VARIANT (t2)))
7059 ? t1
7060 : NULL);
7061 }
7062 set_c_expr_source_range (&ret, start, exp2.get_finish ());
7063 return ret;
7064 }
7065
7066 /* Parse a binary expression; that is, a logical-OR-expression (C90
7067 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not
7068 NULL then it is an Objective-C message expression which is the
7069 primary-expression starting the expression as an initializer.
7070
7071 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
7072 when it should be the unfolded lhs. In a valid OpenMP source,
7073 one of the operands of the toplevel binary expression must be equal
7074 to it. In that case, just return a build2 created binary operation
7075 rather than result of parser_build_binary_op.
7076
7077 multiplicative-expression:
7078 cast-expression
7079 multiplicative-expression * cast-expression
7080 multiplicative-expression / cast-expression
7081 multiplicative-expression % cast-expression
7082
7083 additive-expression:
7084 multiplicative-expression
7085 additive-expression + multiplicative-expression
7086 additive-expression - multiplicative-expression
7087
7088 shift-expression:
7089 additive-expression
7090 shift-expression << additive-expression
7091 shift-expression >> additive-expression
7092
7093 relational-expression:
7094 shift-expression
7095 relational-expression < shift-expression
7096 relational-expression > shift-expression
7097 relational-expression <= shift-expression
7098 relational-expression >= shift-expression
7099
7100 equality-expression:
7101 relational-expression
7102 equality-expression == relational-expression
7103 equality-expression != relational-expression
7104
7105 AND-expression:
7106 equality-expression
7107 AND-expression & equality-expression
7108
7109 exclusive-OR-expression:
7110 AND-expression
7111 exclusive-OR-expression ^ AND-expression
7112
7113 inclusive-OR-expression:
7114 exclusive-OR-expression
7115 inclusive-OR-expression | exclusive-OR-expression
7116
7117 logical-AND-expression:
7118 inclusive-OR-expression
7119 logical-AND-expression && inclusive-OR-expression
7120
7121 logical-OR-expression:
7122 logical-AND-expression
7123 logical-OR-expression || logical-AND-expression
7124 */
7125
7126 static struct c_expr
7127 c_parser_binary_expression (c_parser *parser, struct c_expr *after,
7128 tree omp_atomic_lhs)
7129 {
7130 /* A binary expression is parsed using operator-precedence parsing,
7131 with the operands being cast expressions. All the binary
7132 operators are left-associative. Thus a binary expression is of
7133 form:
7134
7135 E0 op1 E1 op2 E2 ...
7136
7137 which we represent on a stack. On the stack, the precedence
7138 levels are strictly increasing. When a new operator is
7139 encountered of higher precedence than that at the top of the
7140 stack, it is pushed; its LHS is the top expression, and its RHS
7141 is everything parsed until it is popped. When a new operator is
7142 encountered with precedence less than or equal to that at the top
7143 of the stack, triples E[i-1] op[i] E[i] are popped and replaced
7144 by the result of the operation until the operator at the top of
7145 the stack has lower precedence than the new operator or there is
7146 only one element on the stack; then the top expression is the LHS
7147 of the new operator. In the case of logical AND and OR
7148 expressions, we also need to adjust c_inhibit_evaluation_warnings
7149 as appropriate when the operators are pushed and popped. */
7150
7151 struct {
7152 /* The expression at this stack level. */
7153 struct c_expr expr;
7154 /* The precedence of the operator on its left, PREC_NONE at the
7155 bottom of the stack. */
7156 enum c_parser_prec prec;
7157 /* The operation on its left. */
7158 enum tree_code op;
7159 /* The source location of this operation. */
7160 location_t loc;
7161 /* The sizeof argument if expr.original_code == SIZEOF_EXPR. */
7162 tree sizeof_arg;
7163 } stack[NUM_PRECS];
7164 int sp;
7165 /* Location of the binary operator. */
7166 location_t binary_loc = UNKNOWN_LOCATION; /* Quiet warning. */
7167 #define POP \
7168 do { \
7169 switch (stack[sp].op) \
7170 { \
7171 case TRUTH_ANDIF_EXPR: \
7172 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7173 == truthvalue_false_node); \
7174 break; \
7175 case TRUTH_ORIF_EXPR: \
7176 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
7177 == truthvalue_true_node); \
7178 break; \
7179 case TRUNC_DIV_EXPR: \
7180 if (stack[sp - 1].expr.original_code == SIZEOF_EXPR \
7181 && stack[sp].expr.original_code == SIZEOF_EXPR) \
7182 { \
7183 tree type0 = stack[sp - 1].sizeof_arg; \
7184 tree type1 = stack[sp].sizeof_arg; \
7185 tree first_arg = type0; \
7186 if (!TYPE_P (type0)) \
7187 type0 = TREE_TYPE (type0); \
7188 if (!TYPE_P (type1)) \
7189 type1 = TREE_TYPE (type1); \
7190 if (POINTER_TYPE_P (type0) \
7191 && comptypes (TREE_TYPE (type0), type1) \
7192 && !(TREE_CODE (first_arg) == PARM_DECL \
7193 && C_ARRAY_PARAMETER (first_arg) \
7194 && warn_sizeof_array_argument)) \
7195 { \
7196 auto_diagnostic_group d; \
7197 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \
7198 "division %<sizeof (%T) / sizeof (%T)%> " \
7199 "does not compute the number of array " \
7200 "elements", \
7201 type0, type1)) \
7202 if (DECL_P (first_arg)) \
7203 inform (DECL_SOURCE_LOCATION (first_arg), \
7204 "first %<sizeof%> operand was declared here"); \
7205 } \
7206 } \
7207 break; \
7208 default: \
7209 break; \
7210 } \
7211 stack[sp - 1].expr \
7212 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \
7213 stack[sp - 1].expr, true, true); \
7214 stack[sp].expr \
7215 = convert_lvalue_to_rvalue (stack[sp].loc, \
7216 stack[sp].expr, true, true); \
7217 if (__builtin_expect (omp_atomic_lhs != NULL_TREE, 0) && sp == 1 \
7218 && c_parser_peek_token (parser)->type == CPP_SEMICOLON \
7219 && ((1 << stack[sp].prec) \
7220 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) | (1 << PREC_BITAND) \
7221 | (1 << PREC_SHIFT) | (1 << PREC_ADD) | (1 << PREC_MULT))) \
7222 && stack[sp].op != TRUNC_MOD_EXPR \
7223 && stack[0].expr.value != error_mark_node \
7224 && stack[1].expr.value != error_mark_node \
7225 && (c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \
7226 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs))) \
7227 stack[0].expr.value \
7228 = build2 (stack[1].op, TREE_TYPE (stack[0].expr.value), \
7229 stack[0].expr.value, stack[1].expr.value); \
7230 else \
7231 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
7232 stack[sp].op, \
7233 stack[sp - 1].expr, \
7234 stack[sp].expr); \
7235 sp--; \
7236 } while (0)
7237 gcc_assert (!after || c_dialect_objc ());
7238 stack[0].loc = c_parser_peek_token (parser)->location;
7239 stack[0].expr = c_parser_cast_expression (parser, after);
7240 stack[0].prec = PREC_NONE;
7241 stack[0].sizeof_arg = c_last_sizeof_arg;
7242 sp = 0;
7243 while (true)
7244 {
7245 enum c_parser_prec oprec;
7246 enum tree_code ocode;
7247 source_range src_range;
7248 if (parser->error)
7249 goto out;
7250 switch (c_parser_peek_token (parser)->type)
7251 {
7252 case CPP_MULT:
7253 oprec = PREC_MULT;
7254 ocode = MULT_EXPR;
7255 break;
7256 case CPP_DIV:
7257 oprec = PREC_MULT;
7258 ocode = TRUNC_DIV_EXPR;
7259 break;
7260 case CPP_MOD:
7261 oprec = PREC_MULT;
7262 ocode = TRUNC_MOD_EXPR;
7263 break;
7264 case CPP_PLUS:
7265 oprec = PREC_ADD;
7266 ocode = PLUS_EXPR;
7267 break;
7268 case CPP_MINUS:
7269 oprec = PREC_ADD;
7270 ocode = MINUS_EXPR;
7271 break;
7272 case CPP_LSHIFT:
7273 oprec = PREC_SHIFT;
7274 ocode = LSHIFT_EXPR;
7275 break;
7276 case CPP_RSHIFT:
7277 oprec = PREC_SHIFT;
7278 ocode = RSHIFT_EXPR;
7279 break;
7280 case CPP_LESS:
7281 oprec = PREC_REL;
7282 ocode = LT_EXPR;
7283 break;
7284 case CPP_GREATER:
7285 oprec = PREC_REL;
7286 ocode = GT_EXPR;
7287 break;
7288 case CPP_LESS_EQ:
7289 oprec = PREC_REL;
7290 ocode = LE_EXPR;
7291 break;
7292 case CPP_GREATER_EQ:
7293 oprec = PREC_REL;
7294 ocode = GE_EXPR;
7295 break;
7296 case CPP_EQ_EQ:
7297 oprec = PREC_EQ;
7298 ocode = EQ_EXPR;
7299 break;
7300 case CPP_NOT_EQ:
7301 oprec = PREC_EQ;
7302 ocode = NE_EXPR;
7303 break;
7304 case CPP_AND:
7305 oprec = PREC_BITAND;
7306 ocode = BIT_AND_EXPR;
7307 break;
7308 case CPP_XOR:
7309 oprec = PREC_BITXOR;
7310 ocode = BIT_XOR_EXPR;
7311 break;
7312 case CPP_OR:
7313 oprec = PREC_BITOR;
7314 ocode = BIT_IOR_EXPR;
7315 break;
7316 case CPP_AND_AND:
7317 oprec = PREC_LOGAND;
7318 ocode = TRUTH_ANDIF_EXPR;
7319 break;
7320 case CPP_OR_OR:
7321 oprec = PREC_LOGOR;
7322 ocode = TRUTH_ORIF_EXPR;
7323 break;
7324 default:
7325 /* Not a binary operator, so end of the binary
7326 expression. */
7327 goto out;
7328 }
7329 binary_loc = c_parser_peek_token (parser)->location;
7330 while (oprec <= stack[sp].prec)
7331 POP;
7332 c_parser_consume_token (parser);
7333 switch (ocode)
7334 {
7335 case TRUTH_ANDIF_EXPR:
7336 src_range = stack[sp].expr.src_range;
7337 stack[sp].expr
7338 = convert_lvalue_to_rvalue (stack[sp].loc,
7339 stack[sp].expr, true, true);
7340 stack[sp].expr.value = c_objc_common_truthvalue_conversion
7341 (stack[sp].loc, default_conversion (stack[sp].expr.value));
7342 c_inhibit_evaluation_warnings += (stack[sp].expr.value
7343 == truthvalue_false_node);
7344 set_c_expr_source_range (&stack[sp].expr, src_range);
7345 break;
7346 case TRUTH_ORIF_EXPR:
7347 src_range = stack[sp].expr.src_range;
7348 stack[sp].expr
7349 = convert_lvalue_to_rvalue (stack[sp].loc,
7350 stack[sp].expr, true, true);
7351 stack[sp].expr.value = c_objc_common_truthvalue_conversion
7352 (stack[sp].loc, default_conversion (stack[sp].expr.value));
7353 c_inhibit_evaluation_warnings += (stack[sp].expr.value
7354 == truthvalue_true_node);
7355 set_c_expr_source_range (&stack[sp].expr, src_range);
7356 break;
7357 default:
7358 break;
7359 }
7360 sp++;
7361 stack[sp].loc = binary_loc;
7362 stack[sp].expr = c_parser_cast_expression (parser, NULL);
7363 stack[sp].prec = oprec;
7364 stack[sp].op = ocode;
7365 stack[sp].sizeof_arg = c_last_sizeof_arg;
7366 }
7367 out:
7368 while (sp > 0)
7369 POP;
7370 return stack[0].expr;
7371 #undef POP
7372 }
7373
7374 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER
7375 is not NULL then it is an Objective-C message expression which is the
7376 primary-expression starting the expression as an initializer.
7377
7378 cast-expression:
7379 unary-expression
7380 ( type-name ) unary-expression
7381 */
7382
7383 static struct c_expr
7384 c_parser_cast_expression (c_parser *parser, struct c_expr *after)
7385 {
7386 location_t cast_loc = c_parser_peek_token (parser)->location;
7387 gcc_assert (!after || c_dialect_objc ());
7388 if (after)
7389 return c_parser_postfix_expression_after_primary (parser,
7390 cast_loc, *after);
7391 /* If the expression begins with a parenthesized type name, it may
7392 be either a cast or a compound literal; we need to see whether
7393 the next character is '{' to tell the difference. If not, it is
7394 an unary expression. Full detection of unknown typenames here
7395 would require a 3-token lookahead. */
7396 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
7397 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
7398 {
7399 struct c_type_name *type_name;
7400 struct c_expr ret;
7401 struct c_expr expr;
7402 matching_parens parens;
7403 parens.consume_open (parser);
7404 type_name = c_parser_type_name (parser, true);
7405 parens.skip_until_found_close (parser);
7406 if (type_name == NULL)
7407 {
7408 ret.set_error ();
7409 ret.original_code = ERROR_MARK;
7410 ret.original_type = NULL;
7411 return ret;
7412 }
7413
7414 /* Save casted types in the function's used types hash table. */
7415 used_types_insert (type_name->specs->type);
7416
7417 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
7418 return c_parser_postfix_expression_after_paren_type (parser, type_name,
7419 cast_loc);
7420 if (type_name->specs->alignas_p)
7421 error_at (type_name->specs->locations[cdw_alignas],
7422 "alignment specified for type name in cast");
7423 {
7424 location_t expr_loc = c_parser_peek_token (parser)->location;
7425 expr = c_parser_cast_expression (parser, NULL);
7426 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
7427 }
7428 ret.value = c_cast_expr (cast_loc, type_name, expr.value);
7429 if (ret.value && expr.value)
7430 set_c_expr_source_range (&ret, cast_loc, expr.get_finish ());
7431 ret.original_code = ERROR_MARK;
7432 ret.original_type = NULL;
7433 return ret;
7434 }
7435 else
7436 return c_parser_unary_expression (parser);
7437 }
7438
7439 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
7440
7441 unary-expression:
7442 postfix-expression
7443 ++ unary-expression
7444 -- unary-expression
7445 unary-operator cast-expression
7446 sizeof unary-expression
7447 sizeof ( type-name )
7448
7449 unary-operator: one of
7450 & * + - ~ !
7451
7452 GNU extensions:
7453
7454 unary-expression:
7455 __alignof__ unary-expression
7456 __alignof__ ( type-name )
7457 && identifier
7458
7459 (C11 permits _Alignof with type names only.)
7460
7461 unary-operator: one of
7462 __extension__ __real__ __imag__
7463
7464 Transactional Memory:
7465
7466 unary-expression:
7467 transaction-expression
7468
7469 In addition, the GNU syntax treats ++ and -- as unary operators, so
7470 they may be applied to cast expressions with errors for non-lvalues
7471 given later. */
7472
7473 static struct c_expr
7474 c_parser_unary_expression (c_parser *parser)
7475 {
7476 int ext;
7477 struct c_expr ret, op;
7478 location_t op_loc = c_parser_peek_token (parser)->location;
7479 location_t exp_loc;
7480 location_t finish;
7481 ret.original_code = ERROR_MARK;
7482 ret.original_type = NULL;
7483 switch (c_parser_peek_token (parser)->type)
7484 {
7485 case CPP_PLUS_PLUS:
7486 c_parser_consume_token (parser);
7487 exp_loc = c_parser_peek_token (parser)->location;
7488 op = c_parser_cast_expression (parser, NULL);
7489
7490 op = default_function_array_read_conversion (exp_loc, op);
7491 return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
7492 case CPP_MINUS_MINUS:
7493 c_parser_consume_token (parser);
7494 exp_loc = c_parser_peek_token (parser)->location;
7495 op = c_parser_cast_expression (parser, NULL);
7496
7497 op = default_function_array_read_conversion (exp_loc, op);
7498 return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
7499 case CPP_AND:
7500 c_parser_consume_token (parser);
7501 op = c_parser_cast_expression (parser, NULL);
7502 mark_exp_read (op.value);
7503 return parser_build_unary_op (op_loc, ADDR_EXPR, op);
7504 case CPP_MULT:
7505 {
7506 c_parser_consume_token (parser);
7507 exp_loc = c_parser_peek_token (parser)->location;
7508 op = c_parser_cast_expression (parser, NULL);
7509 finish = op.get_finish ();
7510 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
7511 location_t combined_loc = make_location (op_loc, op_loc, finish);
7512 ret.value = build_indirect_ref (combined_loc, op.value, RO_UNARY_STAR);
7513 ret.src_range.m_start = op_loc;
7514 ret.src_range.m_finish = finish;
7515 return ret;
7516 }
7517 case CPP_PLUS:
7518 if (!c_dialect_objc () && !in_system_header_at (input_location))
7519 warning_at (op_loc,
7520 OPT_Wtraditional,
7521 "traditional C rejects the unary plus operator");
7522 c_parser_consume_token (parser);
7523 exp_loc = c_parser_peek_token (parser)->location;
7524 op = c_parser_cast_expression (parser, NULL);
7525 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
7526 return parser_build_unary_op (op_loc, CONVERT_EXPR, op);
7527 case CPP_MINUS:
7528 c_parser_consume_token (parser);
7529 exp_loc = c_parser_peek_token (parser)->location;
7530 op = c_parser_cast_expression (parser, NULL);
7531 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
7532 return parser_build_unary_op (op_loc, NEGATE_EXPR, op);
7533 case CPP_COMPL:
7534 c_parser_consume_token (parser);
7535 exp_loc = c_parser_peek_token (parser)->location;
7536 op = c_parser_cast_expression (parser, NULL);
7537 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
7538 return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
7539 case CPP_NOT:
7540 c_parser_consume_token (parser);
7541 exp_loc = c_parser_peek_token (parser)->location;
7542 op = c_parser_cast_expression (parser, NULL);
7543 op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
7544 return parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op);
7545 case CPP_AND_AND:
7546 /* Refer to the address of a label as a pointer. */
7547 c_parser_consume_token (parser);
7548 if (c_parser_next_token_is (parser, CPP_NAME))
7549 {
7550 ret.value = finish_label_address_expr
7551 (c_parser_peek_token (parser)->value, op_loc);
7552 set_c_expr_source_range (&ret, op_loc,
7553 c_parser_peek_token (parser)->get_finish ());
7554 c_parser_consume_token (parser);
7555 }
7556 else
7557 {
7558 c_parser_error (parser, "expected identifier");
7559 ret.set_error ();
7560 }
7561 return ret;
7562 case CPP_KEYWORD:
7563 switch (c_parser_peek_token (parser)->keyword)
7564 {
7565 case RID_SIZEOF:
7566 return c_parser_sizeof_expression (parser);
7567 case RID_ALIGNOF:
7568 return c_parser_alignof_expression (parser);
7569 case RID_BUILTIN_HAS_ATTRIBUTE:
7570 return c_parser_has_attribute_expression (parser);
7571 case RID_EXTENSION:
7572 c_parser_consume_token (parser);
7573 ext = disable_extension_diagnostics ();
7574 ret = c_parser_cast_expression (parser, NULL);
7575 restore_extension_diagnostics (ext);
7576 return ret;
7577 case RID_REALPART:
7578 c_parser_consume_token (parser);
7579 exp_loc = c_parser_peek_token (parser)->location;
7580 op = c_parser_cast_expression (parser, NULL);
7581 op = default_function_array_conversion (exp_loc, op);
7582 return parser_build_unary_op (op_loc, REALPART_EXPR, op);
7583 case RID_IMAGPART:
7584 c_parser_consume_token (parser);
7585 exp_loc = c_parser_peek_token (parser)->location;
7586 op = c_parser_cast_expression (parser, NULL);
7587 op = default_function_array_conversion (exp_loc, op);
7588 return parser_build_unary_op (op_loc, IMAGPART_EXPR, op);
7589 case RID_TRANSACTION_ATOMIC:
7590 case RID_TRANSACTION_RELAXED:
7591 return c_parser_transaction_expression (parser,
7592 c_parser_peek_token (parser)->keyword);
7593 default:
7594 return c_parser_postfix_expression (parser);
7595 }
7596 default:
7597 return c_parser_postfix_expression (parser);
7598 }
7599 }
7600
7601 /* Parse a sizeof expression. */
7602
7603 static struct c_expr
7604 c_parser_sizeof_expression (c_parser *parser)
7605 {
7606 struct c_expr expr;
7607 struct c_expr result;
7608 location_t expr_loc;
7609 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF));
7610
7611 location_t start;
7612 location_t finish = UNKNOWN_LOCATION;
7613
7614 start = c_parser_peek_token (parser)->location;
7615
7616 c_parser_consume_token (parser);
7617 c_inhibit_evaluation_warnings++;
7618 in_sizeof++;
7619 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
7620 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
7621 {
7622 /* Either sizeof ( type-name ) or sizeof unary-expression
7623 starting with a compound literal. */
7624 struct c_type_name *type_name;
7625 matching_parens parens;
7626 parens.consume_open (parser);
7627 expr_loc = c_parser_peek_token (parser)->location;
7628 type_name = c_parser_type_name (parser, true);
7629 parens.skip_until_found_close (parser);
7630 finish = parser->tokens_buf[0].location;
7631 if (type_name == NULL)
7632 {
7633 struct c_expr ret;
7634 c_inhibit_evaluation_warnings--;
7635 in_sizeof--;
7636 ret.set_error ();
7637 ret.original_code = ERROR_MARK;
7638 ret.original_type = NULL;
7639 return ret;
7640 }
7641 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
7642 {
7643 expr = c_parser_postfix_expression_after_paren_type (parser,
7644 type_name,
7645 expr_loc);
7646 finish = expr.get_finish ();
7647 goto sizeof_expr;
7648 }
7649 /* sizeof ( type-name ). */
7650 if (type_name->specs->alignas_p)
7651 error_at (type_name->specs->locations[cdw_alignas],
7652 "alignment specified for type name in %<sizeof%>");
7653 c_inhibit_evaluation_warnings--;
7654 in_sizeof--;
7655 result = c_expr_sizeof_type (expr_loc, type_name);
7656 }
7657 else
7658 {
7659 expr_loc = c_parser_peek_token (parser)->location;
7660 expr = c_parser_unary_expression (parser);
7661 finish = expr.get_finish ();
7662 sizeof_expr:
7663 c_inhibit_evaluation_warnings--;
7664 in_sizeof--;
7665 mark_exp_read (expr.value);
7666 if (TREE_CODE (expr.value) == COMPONENT_REF
7667 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
7668 error_at (expr_loc, "%<sizeof%> applied to a bit-field");
7669 result = c_expr_sizeof_expr (expr_loc, expr);
7670 }
7671 if (finish == UNKNOWN_LOCATION)
7672 finish = start;
7673 set_c_expr_source_range (&result, start, finish);
7674 return result;
7675 }
7676
7677 /* Parse an alignof expression. */
7678
7679 static struct c_expr
7680 c_parser_alignof_expression (c_parser *parser)
7681 {
7682 struct c_expr expr;
7683 location_t start_loc = c_parser_peek_token (parser)->location;
7684 location_t end_loc;
7685 tree alignof_spelling = c_parser_peek_token (parser)->value;
7686 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF));
7687 bool is_c11_alignof = strcmp (IDENTIFIER_POINTER (alignof_spelling),
7688 "_Alignof") == 0;
7689 /* A diagnostic is not required for the use of this identifier in
7690 the implementation namespace; only diagnose it for the C11
7691 spelling because of existing code using the other spellings. */
7692 if (is_c11_alignof)
7693 {
7694 if (flag_isoc99)
7695 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C99 does not support %qE",
7696 alignof_spelling);
7697 else
7698 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C90 does not support %qE",
7699 alignof_spelling);
7700 }
7701 c_parser_consume_token (parser);
7702 c_inhibit_evaluation_warnings++;
7703 in_alignof++;
7704 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
7705 && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
7706 {
7707 /* Either __alignof__ ( type-name ) or __alignof__
7708 unary-expression starting with a compound literal. */
7709 location_t loc;
7710 struct c_type_name *type_name;
7711 struct c_expr ret;
7712 matching_parens parens;
7713 parens.consume_open (parser);
7714 loc = c_parser_peek_token (parser)->location;
7715 type_name = c_parser_type_name (parser, true);
7716 end_loc = c_parser_peek_token (parser)->location;
7717 parens.skip_until_found_close (parser);
7718 if (type_name == NULL)
7719 {
7720 struct c_expr ret;
7721 c_inhibit_evaluation_warnings--;
7722 in_alignof--;
7723 ret.set_error ();
7724 ret.original_code = ERROR_MARK;
7725 ret.original_type = NULL;
7726 return ret;
7727 }
7728 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
7729 {
7730 expr = c_parser_postfix_expression_after_paren_type (parser,
7731 type_name,
7732 loc);
7733 goto alignof_expr;
7734 }
7735 /* alignof ( type-name ). */
7736 if (type_name->specs->alignas_p)
7737 error_at (type_name->specs->locations[cdw_alignas],
7738 "alignment specified for type name in %qE",
7739 alignof_spelling);
7740 c_inhibit_evaluation_warnings--;
7741 in_alignof--;
7742 ret.value = c_sizeof_or_alignof_type (loc, groktypename (type_name,
7743 NULL, NULL),
7744 false, is_c11_alignof, 1);
7745 ret.original_code = ERROR_MARK;
7746 ret.original_type = NULL;
7747 set_c_expr_source_range (&ret, start_loc, end_loc);
7748 return ret;
7749 }
7750 else
7751 {
7752 struct c_expr ret;
7753 expr = c_parser_unary_expression (parser);
7754 end_loc = expr.src_range.m_finish;
7755 alignof_expr:
7756 mark_exp_read (expr.value);
7757 c_inhibit_evaluation_warnings--;
7758 in_alignof--;
7759 if (is_c11_alignof)
7760 pedwarn (start_loc,
7761 OPT_Wpedantic, "ISO C does not allow %<%E (expression)%>",
7762 alignof_spelling);
7763 ret.value = c_alignof_expr (start_loc, expr.value);
7764 ret.original_code = ERROR_MARK;
7765 ret.original_type = NULL;
7766 set_c_expr_source_range (&ret, start_loc, end_loc);
7767 return ret;
7768 }
7769 }
7770
7771 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
7772 expression. */
7773
7774 static struct c_expr
7775 c_parser_has_attribute_expression (c_parser *parser)
7776 {
7777 gcc_assert (c_parser_next_token_is_keyword (parser,
7778 RID_BUILTIN_HAS_ATTRIBUTE));
7779 c_parser_consume_token (parser);
7780
7781 c_inhibit_evaluation_warnings++;
7782
7783 matching_parens parens;
7784 if (!parens.require_open (parser))
7785 {
7786 c_inhibit_evaluation_warnings--;
7787 in_typeof--;
7788
7789 struct c_expr result;
7790 result.set_error ();
7791 result.original_code = ERROR_MARK;
7792 result.original_type = NULL;
7793 return result;
7794 }
7795
7796 /* Treat the type argument the same way as in typeof for the purposes
7797 of warnings. FIXME: Generalize this so the warning refers to
7798 __builtin_has_attribute rather than typeof. */
7799 in_typeof++;
7800
7801 /* The first operand: one of DECL, EXPR, or TYPE. */
7802 tree oper = NULL_TREE;
7803 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
7804 {
7805 struct c_type_name *tname = c_parser_type_name (parser);
7806 in_typeof--;
7807 if (tname)
7808 {
7809 oper = groktypename (tname, NULL, NULL);
7810 pop_maybe_used (variably_modified_type_p (oper, NULL_TREE));
7811 }
7812 }
7813 else
7814 {
7815 struct c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
7816 c_inhibit_evaluation_warnings--;
7817 in_typeof--;
7818 if (cexpr.value != error_mark_node)
7819 {
7820 mark_exp_read (cexpr.value);
7821 oper = cexpr.value;
7822 tree etype = TREE_TYPE (oper);
7823 bool was_vm = variably_modified_type_p (etype, NULL_TREE);
7824 /* This is returned with the type so that when the type is
7825 evaluated, this can be evaluated. */
7826 if (was_vm)
7827 oper = c_fully_fold (oper, false, NULL);
7828 pop_maybe_used (was_vm);
7829 }
7830 }
7831
7832 struct c_expr result;
7833 result.original_code = ERROR_MARK;
7834 result.original_type = NULL;
7835
7836 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
7837 {
7838 /* Consume the closing parenthesis if that's the next token
7839 in the likely case the built-in was invoked with fewer
7840 than two arguments. */
7841 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
7842 c_parser_consume_token (parser);
7843 c_inhibit_evaluation_warnings--;
7844 result.set_error ();
7845 return result;
7846 }
7847
7848 bool save_translate_strings_p = parser->translate_strings_p;
7849
7850 location_t atloc = c_parser_peek_token (parser)->location;
7851 /* Parse a single attribute. Require no leading comma and do not
7852 allow empty attributes. */
7853 tree attr = c_parser_gnu_attribute (parser, NULL_TREE, false, false);
7854
7855 parser->translate_strings_p = save_translate_strings_p;
7856
7857 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
7858 c_parser_consume_token (parser);
7859 else
7860 {
7861 c_parser_error (parser, "expected identifier");
7862 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
7863
7864 result.set_error ();
7865 return result;
7866 }
7867
7868 if (!attr)
7869 {
7870 error_at (atloc, "expected identifier");
7871 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
7872 "expected %<)%>");
7873 result.set_error ();
7874 return result;
7875 }
7876
7877 result.original_code = INTEGER_CST;
7878 result.original_type = boolean_type_node;
7879
7880 if (has_attribute (atloc, oper, attr, default_conversion))
7881 result.value = boolean_true_node;
7882 else
7883 result.value = boolean_false_node;
7884
7885 return result;
7886 }
7887
7888 /* Helper function to read arguments of builtins which are interfaces
7889 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
7890 others. The name of the builtin is passed using BNAME parameter.
7891 Function returns true if there were no errors while parsing and
7892 stores the arguments in CEXPR_LIST. If it returns true,
7893 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
7894 parenthesis. */
7895 static bool
7896 c_parser_get_builtin_args (c_parser *parser, const char *bname,
7897 vec<c_expr_t, va_gc> **ret_cexpr_list,
7898 bool choose_expr_p,
7899 location_t *out_close_paren_loc)
7900 {
7901 location_t loc = c_parser_peek_token (parser)->location;
7902 vec<c_expr_t, va_gc> *cexpr_list;
7903 c_expr_t expr;
7904 bool saved_force_folding_builtin_constant_p;
7905
7906 *ret_cexpr_list = NULL;
7907 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
7908 {
7909 error_at (loc, "cannot take address of %qs", bname);
7910 return false;
7911 }
7912
7913 c_parser_consume_token (parser);
7914
7915 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
7916 {
7917 *out_close_paren_loc = c_parser_peek_token (parser)->location;
7918 c_parser_consume_token (parser);
7919 return true;
7920 }
7921
7922 saved_force_folding_builtin_constant_p
7923 = force_folding_builtin_constant_p;
7924 force_folding_builtin_constant_p |= choose_expr_p;
7925 expr = c_parser_expr_no_commas (parser, NULL);
7926 force_folding_builtin_constant_p
7927 = saved_force_folding_builtin_constant_p;
7928 vec_alloc (cexpr_list, 1);
7929 vec_safe_push (cexpr_list, expr);
7930 while (c_parser_next_token_is (parser, CPP_COMMA))
7931 {
7932 c_parser_consume_token (parser);
7933 expr = c_parser_expr_no_commas (parser, NULL);
7934 vec_safe_push (cexpr_list, expr);
7935 }
7936
7937 *out_close_paren_loc = c_parser_peek_token (parser)->location;
7938 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
7939 return false;
7940
7941 *ret_cexpr_list = cexpr_list;
7942 return true;
7943 }
7944
7945 /* This represents a single generic-association. */
7946
7947 struct c_generic_association
7948 {
7949 /* The location of the starting token of the type. */
7950 location_t type_location;
7951 /* The association's type, or NULL_TREE for 'default'. */
7952 tree type;
7953 /* The association's expression. */
7954 struct c_expr expression;
7955 };
7956
7957 /* Parse a generic-selection. (C11 6.5.1.1).
7958
7959 generic-selection:
7960 _Generic ( assignment-expression , generic-assoc-list )
7961
7962 generic-assoc-list:
7963 generic-association
7964 generic-assoc-list , generic-association
7965
7966 generic-association:
7967 type-name : assignment-expression
7968 default : assignment-expression
7969 */
7970
7971 static struct c_expr
7972 c_parser_generic_selection (c_parser *parser)
7973 {
7974 struct c_expr selector, error_expr;
7975 tree selector_type;
7976 struct c_generic_association matched_assoc;
7977 bool match_found = false;
7978 location_t generic_loc, selector_loc;
7979
7980 error_expr.original_code = ERROR_MARK;
7981 error_expr.original_type = NULL;
7982 error_expr.set_error ();
7983 matched_assoc.type_location = UNKNOWN_LOCATION;
7984 matched_assoc.type = NULL_TREE;
7985 matched_assoc.expression = error_expr;
7986
7987 gcc_assert (c_parser_next_token_is_keyword (parser, RID_GENERIC));
7988 generic_loc = c_parser_peek_token (parser)->location;
7989 c_parser_consume_token (parser);
7990 if (flag_isoc99)
7991 pedwarn_c99 (generic_loc, OPT_Wpedantic,
7992 "ISO C99 does not support %<_Generic%>");
7993 else
7994 pedwarn_c99 (generic_loc, OPT_Wpedantic,
7995 "ISO C90 does not support %<_Generic%>");
7996
7997 matching_parens parens;
7998 if (!parens.require_open (parser))
7999 return error_expr;
8000
8001 c_inhibit_evaluation_warnings++;
8002 selector_loc = c_parser_peek_token (parser)->location;
8003 selector = c_parser_expr_no_commas (parser, NULL);
8004 selector = default_function_array_conversion (selector_loc, selector);
8005 c_inhibit_evaluation_warnings--;
8006
8007 if (selector.value == error_mark_node)
8008 {
8009 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8010 return selector;
8011 }
8012 selector_type = TREE_TYPE (selector.value);
8013 /* In ISO C terms, rvalues (including the controlling expression of
8014 _Generic) do not have qualified types. */
8015 if (TREE_CODE (selector_type) != ARRAY_TYPE)
8016 selector_type = TYPE_MAIN_VARIANT (selector_type);
8017 /* In ISO C terms, _Noreturn is not part of the type of expressions
8018 such as &abort, but in GCC it is represented internally as a type
8019 qualifier. */
8020 if (FUNCTION_POINTER_TYPE_P (selector_type)
8021 && TYPE_QUALS (TREE_TYPE (selector_type)) != TYPE_UNQUALIFIED)
8022 selector_type
8023 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type)));
8024
8025 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8026 {
8027 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8028 return error_expr;
8029 }
8030
8031 auto_vec<c_generic_association> associations;
8032 while (1)
8033 {
8034 struct c_generic_association assoc, *iter;
8035 unsigned int ix;
8036 c_token *token = c_parser_peek_token (parser);
8037
8038 assoc.type_location = token->location;
8039 if (token->type == CPP_KEYWORD && token->keyword == RID_DEFAULT)
8040 {
8041 c_parser_consume_token (parser);
8042 assoc.type = NULL_TREE;
8043 }
8044 else
8045 {
8046 struct c_type_name *type_name;
8047
8048 type_name = c_parser_type_name (parser);
8049 if (type_name == NULL)
8050 {
8051 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8052 return error_expr;
8053 }
8054 assoc.type = groktypename (type_name, NULL, NULL);
8055 if (assoc.type == error_mark_node)
8056 {
8057 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8058 return error_expr;
8059 }
8060
8061 if (TREE_CODE (assoc.type) == FUNCTION_TYPE)
8062 error_at (assoc.type_location,
8063 "%<_Generic%> association has function type");
8064 else if (!COMPLETE_TYPE_P (assoc.type))
8065 error_at (assoc.type_location,
8066 "%<_Generic%> association has incomplete type");
8067
8068 if (variably_modified_type_p (assoc.type, NULL_TREE))
8069 error_at (assoc.type_location,
8070 "%<_Generic%> association has "
8071 "variable length type");
8072 }
8073
8074 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
8075 {
8076 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8077 return error_expr;
8078 }
8079
8080 assoc.expression = c_parser_expr_no_commas (parser, NULL);
8081 if (assoc.expression.value == error_mark_node)
8082 {
8083 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8084 return error_expr;
8085 }
8086
8087 for (ix = 0; associations.iterate (ix, &iter); ++ix)
8088 {
8089 if (assoc.type == NULL_TREE)
8090 {
8091 if (iter->type == NULL_TREE)
8092 {
8093 error_at (assoc.type_location,
8094 "duplicate %<default%> case in %<_Generic%>");
8095 inform (iter->type_location, "original %<default%> is here");
8096 }
8097 }
8098 else if (iter->type != NULL_TREE)
8099 {
8100 if (comptypes (assoc.type, iter->type))
8101 {
8102 error_at (assoc.type_location,
8103 "%<_Generic%> specifies two compatible types");
8104 inform (iter->type_location, "compatible type is here");
8105 }
8106 }
8107 }
8108
8109 if (assoc.type == NULL_TREE)
8110 {
8111 if (!match_found)
8112 {
8113 matched_assoc = assoc;
8114 match_found = true;
8115 }
8116 }
8117 else if (comptypes (assoc.type, selector_type))
8118 {
8119 if (!match_found || matched_assoc.type == NULL_TREE)
8120 {
8121 matched_assoc = assoc;
8122 match_found = true;
8123 }
8124 else
8125 {
8126 error_at (assoc.type_location,
8127 "%<_Generic%> selector matches multiple associations");
8128 inform (matched_assoc.type_location,
8129 "other match is here");
8130 }
8131 }
8132
8133 associations.safe_push (assoc);
8134
8135 if (c_parser_peek_token (parser)->type != CPP_COMMA)
8136 break;
8137 c_parser_consume_token (parser);
8138 }
8139
8140 if (!parens.require_close (parser))
8141 {
8142 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8143 return error_expr;
8144 }
8145
8146 if (!match_found)
8147 {
8148 error_at (selector_loc, "%<_Generic%> selector of type %qT is not "
8149 "compatible with any association",
8150 selector_type);
8151 return error_expr;
8152 }
8153
8154 return matched_assoc.expression;
8155 }
8156
8157 /* Check the validity of a function pointer argument *EXPR (argument
8158 position POS) to __builtin_tgmath. Return the number of function
8159 arguments if possibly valid; return 0 having reported an error if
8160 not valid. */
8161
8162 static unsigned int
8163 check_tgmath_function (c_expr *expr, unsigned int pos)
8164 {
8165 tree type = TREE_TYPE (expr->value);
8166 if (!FUNCTION_POINTER_TYPE_P (type))
8167 {
8168 error_at (expr->get_location (),
8169 "argument %u of %<__builtin_tgmath%> is not a function pointer",
8170 pos);
8171 return 0;
8172 }
8173 type = TREE_TYPE (type);
8174 if (!prototype_p (type))
8175 {
8176 error_at (expr->get_location (),
8177 "argument %u of %<__builtin_tgmath%> is unprototyped", pos);
8178 return 0;
8179 }
8180 if (stdarg_p (type))
8181 {
8182 error_at (expr->get_location (),
8183 "argument %u of %<__builtin_tgmath%> has variable arguments",
8184 pos);
8185 return 0;
8186 }
8187 unsigned int nargs = 0;
8188 function_args_iterator iter;
8189 tree t;
8190 FOREACH_FUNCTION_ARGS (type, t, iter)
8191 {
8192 if (t == void_type_node)
8193 break;
8194 nargs++;
8195 }
8196 if (nargs == 0)
8197 {
8198 error_at (expr->get_location (),
8199 "argument %u of %<__builtin_tgmath%> has no arguments", pos);
8200 return 0;
8201 }
8202 return nargs;
8203 }
8204
8205 /* Ways in which a parameter or return value of a type-generic macro
8206 may vary between the different functions the macro may call. */
8207 enum tgmath_parm_kind
8208 {
8209 tgmath_fixed, tgmath_real, tgmath_complex
8210 };
8211
8212 /* Helper function for c_parser_postfix_expression. Parse predefined
8213 identifiers. */
8214
8215 static struct c_expr
8216 c_parser_predefined_identifier (c_parser *parser)
8217 {
8218 location_t loc = c_parser_peek_token (parser)->location;
8219 switch (c_parser_peek_token (parser)->keyword)
8220 {
8221 case RID_FUNCTION_NAME:
8222 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
8223 "identifier", "__FUNCTION__");
8224 break;
8225 case RID_PRETTY_FUNCTION_NAME:
8226 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
8227 "identifier", "__PRETTY_FUNCTION__");
8228 break;
8229 case RID_C99_FUNCTION_NAME:
8230 pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not support "
8231 "%<__func__%> predefined identifier");
8232 break;
8233 default:
8234 gcc_unreachable ();
8235 }
8236
8237 struct c_expr expr;
8238 expr.original_code = ERROR_MARK;
8239 expr.original_type = NULL;
8240 expr.value = fname_decl (loc, c_parser_peek_token (parser)->keyword,
8241 c_parser_peek_token (parser)->value);
8242 set_c_expr_source_range (&expr, loc, loc);
8243 c_parser_consume_token (parser);
8244 return expr;
8245 }
8246
8247 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
8248 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to
8249 call c_parser_postfix_expression_after_paren_type on encountering them.
8250
8251 postfix-expression:
8252 primary-expression
8253 postfix-expression [ expression ]
8254 postfix-expression ( argument-expression-list[opt] )
8255 postfix-expression . identifier
8256 postfix-expression -> identifier
8257 postfix-expression ++
8258 postfix-expression --
8259 ( type-name ) { initializer-list }
8260 ( type-name ) { initializer-list , }
8261
8262 argument-expression-list:
8263 argument-expression
8264 argument-expression-list , argument-expression
8265
8266 primary-expression:
8267 identifier
8268 constant
8269 string-literal
8270 ( expression )
8271 generic-selection
8272
8273 GNU extensions:
8274
8275 primary-expression:
8276 __func__
8277 (treated as a keyword in GNU C)
8278 __FUNCTION__
8279 __PRETTY_FUNCTION__
8280 ( compound-statement )
8281 __builtin_va_arg ( assignment-expression , type-name )
8282 __builtin_offsetof ( type-name , offsetof-member-designator )
8283 __builtin_choose_expr ( assignment-expression ,
8284 assignment-expression ,
8285 assignment-expression )
8286 __builtin_types_compatible_p ( type-name , type-name )
8287 __builtin_tgmath ( expr-list )
8288 __builtin_complex ( assignment-expression , assignment-expression )
8289 __builtin_shuffle ( assignment-expression , assignment-expression )
8290 __builtin_shuffle ( assignment-expression ,
8291 assignment-expression ,
8292 assignment-expression, )
8293 __builtin_convertvector ( assignment-expression , type-name )
8294
8295 offsetof-member-designator:
8296 identifier
8297 offsetof-member-designator . identifier
8298 offsetof-member-designator [ expression ]
8299
8300 Objective-C:
8301
8302 primary-expression:
8303 [ objc-receiver objc-message-args ]
8304 @selector ( objc-selector-arg )
8305 @protocol ( identifier )
8306 @encode ( type-name )
8307 objc-string-literal
8308 Classname . identifier
8309 */
8310
8311 static struct c_expr
8312 c_parser_postfix_expression (c_parser *parser)
8313 {
8314 struct c_expr expr, e1;
8315 struct c_type_name *t1, *t2;
8316 location_t loc = c_parser_peek_token (parser)->location;
8317 source_range tok_range = c_parser_peek_token (parser)->get_range ();
8318 expr.original_code = ERROR_MARK;
8319 expr.original_type = NULL;
8320 switch (c_parser_peek_token (parser)->type)
8321 {
8322 case CPP_NUMBER:
8323 expr.value = c_parser_peek_token (parser)->value;
8324 set_c_expr_source_range (&expr, tok_range);
8325 loc = c_parser_peek_token (parser)->location;
8326 c_parser_consume_token (parser);
8327 if (TREE_CODE (expr.value) == FIXED_CST
8328 && !targetm.fixed_point_supported_p ())
8329 {
8330 error_at (loc, "fixed-point types not supported for this target");
8331 expr.set_error ();
8332 }
8333 break;
8334 case CPP_CHAR:
8335 case CPP_CHAR16:
8336 case CPP_CHAR32:
8337 case CPP_WCHAR:
8338 expr.value = c_parser_peek_token (parser)->value;
8339 /* For the purpose of warning when a pointer is compared with
8340 a zero character constant. */
8341 expr.original_type = char_type_node;
8342 set_c_expr_source_range (&expr, tok_range);
8343 c_parser_consume_token (parser);
8344 break;
8345 case CPP_STRING:
8346 case CPP_STRING16:
8347 case CPP_STRING32:
8348 case CPP_WSTRING:
8349 case CPP_UTF8STRING:
8350 expr = c_parser_string_literal (parser, parser->translate_strings_p,
8351 true);
8352 break;
8353 case CPP_OBJC_STRING:
8354 gcc_assert (c_dialect_objc ());
8355 expr.value
8356 = objc_build_string_object (c_parser_peek_token (parser)->value);
8357 set_c_expr_source_range (&expr, tok_range);
8358 c_parser_consume_token (parser);
8359 break;
8360 case CPP_NAME:
8361 switch (c_parser_peek_token (parser)->id_kind)
8362 {
8363 case C_ID_ID:
8364 {
8365 tree id = c_parser_peek_token (parser)->value;
8366 c_parser_consume_token (parser);
8367 expr.value = build_external_ref (loc, id,
8368 (c_parser_peek_token (parser)->type
8369 == CPP_OPEN_PAREN),
8370 &expr.original_type);
8371 set_c_expr_source_range (&expr, tok_range);
8372 break;
8373 }
8374 case C_ID_CLASSNAME:
8375 {
8376 /* Here we parse the Objective-C 2.0 Class.name dot
8377 syntax. */
8378 tree class_name = c_parser_peek_token (parser)->value;
8379 tree component;
8380 c_parser_consume_token (parser);
8381 gcc_assert (c_dialect_objc ());
8382 if (!c_parser_require (parser, CPP_DOT, "expected %<.%>"))
8383 {
8384 expr.set_error ();
8385 break;
8386 }
8387 if (c_parser_next_token_is_not (parser, CPP_NAME))
8388 {
8389 c_parser_error (parser, "expected identifier");
8390 expr.set_error ();
8391 break;
8392 }
8393 c_token *component_tok = c_parser_peek_token (parser);
8394 component = component_tok->value;
8395 location_t end_loc = component_tok->get_finish ();
8396 c_parser_consume_token (parser);
8397 expr.value = objc_build_class_component_ref (class_name,
8398 component);
8399 set_c_expr_source_range (&expr, loc, end_loc);
8400 break;
8401 }
8402 default:
8403 c_parser_error (parser, "expected expression");
8404 expr.set_error ();
8405 break;
8406 }
8407 break;
8408 case CPP_OPEN_PAREN:
8409 /* A parenthesized expression, statement expression or compound
8410 literal. */
8411 if (c_parser_peek_2nd_token (parser)->type == CPP_OPEN_BRACE)
8412 {
8413 /* A statement expression. */
8414 tree stmt;
8415 location_t brace_loc;
8416 c_parser_consume_token (parser);
8417 brace_loc = c_parser_peek_token (parser)->location;
8418 c_parser_consume_token (parser);
8419 /* If we've not yet started the current function's statement list,
8420 or we're in the parameter scope of an old-style function
8421 declaration, statement expressions are not allowed. */
8422 if (!building_stmt_list_p () || old_style_parameter_scope ())
8423 {
8424 error_at (loc, "braced-group within expression allowed "
8425 "only inside a function");
8426 parser->error = true;
8427 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
8428 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8429 expr.set_error ();
8430 break;
8431 }
8432 stmt = c_begin_stmt_expr ();
8433 c_parser_compound_statement_nostart (parser);
8434 location_t close_loc = c_parser_peek_token (parser)->location;
8435 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
8436 "expected %<)%>");
8437 pedwarn (loc, OPT_Wpedantic,
8438 "ISO C forbids braced-groups within expressions");
8439 expr.value = c_finish_stmt_expr (brace_loc, stmt);
8440 set_c_expr_source_range (&expr, loc, close_loc);
8441 mark_exp_read (expr.value);
8442 }
8443 else
8444 {
8445 /* A parenthesized expression. */
8446 location_t loc_open_paren = c_parser_peek_token (parser)->location;
8447 c_parser_consume_token (parser);
8448 expr = c_parser_expression (parser);
8449 if (TREE_CODE (expr.value) == MODIFY_EXPR)
8450 TREE_NO_WARNING (expr.value) = 1;
8451 if (expr.original_code != C_MAYBE_CONST_EXPR
8452 && expr.original_code != SIZEOF_EXPR)
8453 expr.original_code = ERROR_MARK;
8454 /* Don't change EXPR.ORIGINAL_TYPE. */
8455 location_t loc_close_paren = c_parser_peek_token (parser)->location;
8456 set_c_expr_source_range (&expr, loc_open_paren, loc_close_paren);
8457 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
8458 "expected %<)%>", loc_open_paren);
8459 }
8460 break;
8461 case CPP_KEYWORD:
8462 switch (c_parser_peek_token (parser)->keyword)
8463 {
8464 case RID_FUNCTION_NAME:
8465 case RID_PRETTY_FUNCTION_NAME:
8466 case RID_C99_FUNCTION_NAME:
8467 expr = c_parser_predefined_identifier (parser);
8468 break;
8469 case RID_VA_ARG:
8470 {
8471 location_t start_loc = loc;
8472 c_parser_consume_token (parser);
8473 matching_parens parens;
8474 if (!parens.require_open (parser))
8475 {
8476 expr.set_error ();
8477 break;
8478 }
8479 e1 = c_parser_expr_no_commas (parser, NULL);
8480 mark_exp_read (e1.value);
8481 e1.value = c_fully_fold (e1.value, false, NULL);
8482 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8483 {
8484 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8485 expr.set_error ();
8486 break;
8487 }
8488 loc = c_parser_peek_token (parser)->location;
8489 t1 = c_parser_type_name (parser);
8490 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
8491 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
8492 "expected %<)%>");
8493 if (t1 == NULL)
8494 {
8495 expr.set_error ();
8496 }
8497 else
8498 {
8499 tree type_expr = NULL_TREE;
8500 expr.value = c_build_va_arg (start_loc, e1.value, loc,
8501 groktypename (t1, &type_expr, NULL));
8502 if (type_expr)
8503 {
8504 expr.value = build2 (C_MAYBE_CONST_EXPR,
8505 TREE_TYPE (expr.value), type_expr,
8506 expr.value);
8507 C_MAYBE_CONST_EXPR_NON_CONST (expr.value) = true;
8508 }
8509 set_c_expr_source_range (&expr, start_loc, end_loc);
8510 }
8511 }
8512 break;
8513 case RID_OFFSETOF:
8514 {
8515 c_parser_consume_token (parser);
8516 matching_parens parens;
8517 if (!parens.require_open (parser))
8518 {
8519 expr.set_error ();
8520 break;
8521 }
8522 t1 = c_parser_type_name (parser);
8523 if (t1 == NULL)
8524 parser->error = true;
8525 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8526 gcc_assert (parser->error);
8527 if (parser->error)
8528 {
8529 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8530 expr.set_error ();
8531 break;
8532 }
8533 tree type = groktypename (t1, NULL, NULL);
8534 tree offsetof_ref;
8535 if (type == error_mark_node)
8536 offsetof_ref = error_mark_node;
8537 else
8538 {
8539 offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
8540 SET_EXPR_LOCATION (offsetof_ref, loc);
8541 }
8542 /* Parse the second argument to __builtin_offsetof. We
8543 must have one identifier, and beyond that we want to
8544 accept sub structure and sub array references. */
8545 if (c_parser_next_token_is (parser, CPP_NAME))
8546 {
8547 c_token *comp_tok = c_parser_peek_token (parser);
8548 offsetof_ref = build_component_ref
8549 (loc, offsetof_ref, comp_tok->value, comp_tok->location);
8550 c_parser_consume_token (parser);
8551 while (c_parser_next_token_is (parser, CPP_DOT)
8552 || c_parser_next_token_is (parser,
8553 CPP_OPEN_SQUARE)
8554 || c_parser_next_token_is (parser,
8555 CPP_DEREF))
8556 {
8557 if (c_parser_next_token_is (parser, CPP_DEREF))
8558 {
8559 loc = c_parser_peek_token (parser)->location;
8560 offsetof_ref = build_array_ref (loc,
8561 offsetof_ref,
8562 integer_zero_node);
8563 goto do_dot;
8564 }
8565 else if (c_parser_next_token_is (parser, CPP_DOT))
8566 {
8567 do_dot:
8568 c_parser_consume_token (parser);
8569 if (c_parser_next_token_is_not (parser,
8570 CPP_NAME))
8571 {
8572 c_parser_error (parser, "expected identifier");
8573 break;
8574 }
8575 c_token *comp_tok = c_parser_peek_token (parser);
8576 offsetof_ref = build_component_ref
8577 (loc, offsetof_ref, comp_tok->value,
8578 comp_tok->location);
8579 c_parser_consume_token (parser);
8580 }
8581 else
8582 {
8583 struct c_expr ce;
8584 tree idx;
8585 loc = c_parser_peek_token (parser)->location;
8586 c_parser_consume_token (parser);
8587 ce = c_parser_expression (parser);
8588 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
8589 idx = ce.value;
8590 idx = c_fully_fold (idx, false, NULL);
8591 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
8592 "expected %<]%>");
8593 offsetof_ref = build_array_ref (loc, offsetof_ref, idx);
8594 }
8595 }
8596 }
8597 else
8598 c_parser_error (parser, "expected identifier");
8599 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
8600 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
8601 "expected %<)%>");
8602 expr.value = fold_offsetof (offsetof_ref);
8603 set_c_expr_source_range (&expr, loc, end_loc);
8604 }
8605 break;
8606 case RID_CHOOSE_EXPR:
8607 {
8608 vec<c_expr_t, va_gc> *cexpr_list;
8609 c_expr_t *e1_p, *e2_p, *e3_p;
8610 tree c;
8611 location_t close_paren_loc;
8612
8613 c_parser_consume_token (parser);
8614 if (!c_parser_get_builtin_args (parser,
8615 "__builtin_choose_expr",
8616 &cexpr_list, true,
8617 &close_paren_loc))
8618 {
8619 expr.set_error ();
8620 break;
8621 }
8622
8623 if (vec_safe_length (cexpr_list) != 3)
8624 {
8625 error_at (loc, "wrong number of arguments to "
8626 "%<__builtin_choose_expr%>");
8627 expr.set_error ();
8628 break;
8629 }
8630
8631 e1_p = &(*cexpr_list)[0];
8632 e2_p = &(*cexpr_list)[1];
8633 e3_p = &(*cexpr_list)[2];
8634
8635 c = e1_p->value;
8636 mark_exp_read (e2_p->value);
8637 mark_exp_read (e3_p->value);
8638 if (TREE_CODE (c) != INTEGER_CST
8639 || !INTEGRAL_TYPE_P (TREE_TYPE (c)))
8640 error_at (loc,
8641 "first argument to %<__builtin_choose_expr%> not"
8642 " a constant");
8643 constant_expression_warning (c);
8644 expr = integer_zerop (c) ? *e3_p : *e2_p;
8645 set_c_expr_source_range (&expr, loc, close_paren_loc);
8646 break;
8647 }
8648 case RID_TYPES_COMPATIBLE_P:
8649 {
8650 c_parser_consume_token (parser);
8651 matching_parens parens;
8652 if (!parens.require_open (parser))
8653 {
8654 expr.set_error ();
8655 break;
8656 }
8657 t1 = c_parser_type_name (parser);
8658 if (t1 == NULL)
8659 {
8660 expr.set_error ();
8661 break;
8662 }
8663 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
8664 {
8665 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
8666 expr.set_error ();
8667 break;
8668 }
8669 t2 = c_parser_type_name (parser);
8670 if (t2 == NULL)
8671 {
8672 expr.set_error ();
8673 break;
8674 }
8675 location_t close_paren_loc = c_parser_peek_token (parser)->location;
8676 parens.skip_until_found_close (parser);
8677 tree e1, e2;
8678 e1 = groktypename (t1, NULL, NULL);
8679 e2 = groktypename (t2, NULL, NULL);
8680 if (e1 == error_mark_node || e2 == error_mark_node)
8681 {
8682 expr.set_error ();
8683 break;
8684 }
8685
8686 e1 = TYPE_MAIN_VARIANT (e1);
8687 e2 = TYPE_MAIN_VARIANT (e2);
8688
8689 expr.value
8690 = comptypes (e1, e2) ? integer_one_node : integer_zero_node;
8691 set_c_expr_source_range (&expr, loc, close_paren_loc);
8692 }
8693 break;
8694 case RID_BUILTIN_TGMATH:
8695 {
8696 vec<c_expr_t, va_gc> *cexpr_list;
8697 location_t close_paren_loc;
8698
8699 c_parser_consume_token (parser);
8700 if (!c_parser_get_builtin_args (parser,
8701 "__builtin_tgmath",
8702 &cexpr_list, false,
8703 &close_paren_loc))
8704 {
8705 expr.set_error ();
8706 break;
8707 }
8708
8709 if (vec_safe_length (cexpr_list) < 3)
8710 {
8711 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
8712 expr.set_error ();
8713 break;
8714 }
8715
8716 unsigned int i;
8717 c_expr_t *p;
8718 FOR_EACH_VEC_ELT (*cexpr_list, i, p)
8719 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
8720 unsigned int nargs = check_tgmath_function (&(*cexpr_list)[0], 1);
8721 if (nargs == 0)
8722 {
8723 expr.set_error ();
8724 break;
8725 }
8726 if (vec_safe_length (cexpr_list) < nargs)
8727 {
8728 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
8729 expr.set_error ();
8730 break;
8731 }
8732 unsigned int num_functions = vec_safe_length (cexpr_list) - nargs;
8733 if (num_functions < 2)
8734 {
8735 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
8736 expr.set_error ();
8737 break;
8738 }
8739
8740 /* The first NUM_FUNCTIONS expressions are the function
8741 pointers. The remaining NARGS expressions are the
8742 arguments that are to be passed to one of those
8743 functions, chosen following <tgmath.h> rules. */
8744 for (unsigned int j = 1; j < num_functions; j++)
8745 {
8746 unsigned int this_nargs
8747 = check_tgmath_function (&(*cexpr_list)[j], j + 1);
8748 if (this_nargs == 0)
8749 {
8750 expr.set_error ();
8751 goto out;
8752 }
8753 if (this_nargs != nargs)
8754 {
8755 error_at ((*cexpr_list)[j].get_location (),
8756 "argument %u of %<__builtin_tgmath%> has "
8757 "wrong number of arguments", j + 1);
8758 expr.set_error ();
8759 goto out;
8760 }
8761 }
8762
8763 /* The functions all have the same number of arguments.
8764 Determine whether arguments and return types vary in
8765 ways permitted for <tgmath.h> functions. */
8766 /* The first entry in each of these vectors is for the
8767 return type, subsequent entries for parameter
8768 types. */
8769 auto_vec<enum tgmath_parm_kind> parm_kind (nargs + 1);
8770 auto_vec<tree> parm_first (nargs + 1);
8771 auto_vec<bool> parm_complex (nargs + 1);
8772 auto_vec<bool> parm_varies (nargs + 1);
8773 tree first_type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[0].value));
8774 tree first_ret = TYPE_MAIN_VARIANT (TREE_TYPE (first_type));
8775 parm_first.quick_push (first_ret);
8776 parm_complex.quick_push (TREE_CODE (first_ret) == COMPLEX_TYPE);
8777 parm_varies.quick_push (false);
8778 function_args_iterator iter;
8779 tree t;
8780 unsigned int argpos;
8781 FOREACH_FUNCTION_ARGS (first_type, t, iter)
8782 {
8783 if (t == void_type_node)
8784 break;
8785 parm_first.quick_push (TYPE_MAIN_VARIANT (t));
8786 parm_complex.quick_push (TREE_CODE (t) == COMPLEX_TYPE);
8787 parm_varies.quick_push (false);
8788 }
8789 for (unsigned int j = 1; j < num_functions; j++)
8790 {
8791 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
8792 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
8793 if (ret != parm_first[0])
8794 {
8795 parm_varies[0] = true;
8796 if (!SCALAR_FLOAT_TYPE_P (parm_first[0])
8797 && !COMPLEX_FLOAT_TYPE_P (parm_first[0]))
8798 {
8799 error_at ((*cexpr_list)[0].get_location (),
8800 "invalid type-generic return type for "
8801 "argument %u of %<__builtin_tgmath%>",
8802 1);
8803 expr.set_error ();
8804 goto out;
8805 }
8806 if (!SCALAR_FLOAT_TYPE_P (ret)
8807 && !COMPLEX_FLOAT_TYPE_P (ret))
8808 {
8809 error_at ((*cexpr_list)[j].get_location (),
8810 "invalid type-generic return type for "
8811 "argument %u of %<__builtin_tgmath%>",
8812 j + 1);
8813 expr.set_error ();
8814 goto out;
8815 }
8816 }
8817 if (TREE_CODE (ret) == COMPLEX_TYPE)
8818 parm_complex[0] = true;
8819 argpos = 1;
8820 FOREACH_FUNCTION_ARGS (type, t, iter)
8821 {
8822 if (t == void_type_node)
8823 break;
8824 t = TYPE_MAIN_VARIANT (t);
8825 if (t != parm_first[argpos])
8826 {
8827 parm_varies[argpos] = true;
8828 if (!SCALAR_FLOAT_TYPE_P (parm_first[argpos])
8829 && !COMPLEX_FLOAT_TYPE_P (parm_first[argpos]))
8830 {
8831 error_at ((*cexpr_list)[0].get_location (),
8832 "invalid type-generic type for "
8833 "argument %u of argument %u of "
8834 "%<__builtin_tgmath%>", argpos, 1);
8835 expr.set_error ();
8836 goto out;
8837 }
8838 if (!SCALAR_FLOAT_TYPE_P (t)
8839 && !COMPLEX_FLOAT_TYPE_P (t))
8840 {
8841 error_at ((*cexpr_list)[j].get_location (),
8842 "invalid type-generic type for "
8843 "argument %u of argument %u of "
8844 "%<__builtin_tgmath%>", argpos, j + 1);
8845 expr.set_error ();
8846 goto out;
8847 }
8848 }
8849 if (TREE_CODE (t) == COMPLEX_TYPE)
8850 parm_complex[argpos] = true;
8851 argpos++;
8852 }
8853 }
8854 enum tgmath_parm_kind max_variation = tgmath_fixed;
8855 for (unsigned int j = 0; j <= nargs; j++)
8856 {
8857 enum tgmath_parm_kind this_kind;
8858 if (parm_varies[j])
8859 {
8860 if (parm_complex[j])
8861 max_variation = this_kind = tgmath_complex;
8862 else
8863 {
8864 this_kind = tgmath_real;
8865 if (max_variation != tgmath_complex)
8866 max_variation = tgmath_real;
8867 }
8868 }
8869 else
8870 this_kind = tgmath_fixed;
8871 parm_kind.quick_push (this_kind);
8872 }
8873 if (max_variation == tgmath_fixed)
8874 {
8875 error_at (loc, "function arguments of %<__builtin_tgmath%> "
8876 "all have the same type");
8877 expr.set_error ();
8878 break;
8879 }
8880
8881 /* Identify a parameter (not the return type) that varies,
8882 including with complex types if any variation includes
8883 complex types; there must be at least one such
8884 parameter. */
8885 unsigned int tgarg = 0;
8886 for (unsigned int j = 1; j <= nargs; j++)
8887 if (parm_kind[j] == max_variation)
8888 {
8889 tgarg = j;
8890 break;
8891 }
8892 if (tgarg == 0)
8893 {
8894 error_at (loc, "function arguments of %<__builtin_tgmath%> "
8895 "lack type-generic parameter");
8896 expr.set_error ();
8897 break;
8898 }
8899
8900 /* Determine the type of the relevant parameter for each
8901 function. */
8902 auto_vec<tree> tg_type (num_functions);
8903 for (unsigned int j = 0; j < num_functions; j++)
8904 {
8905 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
8906 argpos = 1;
8907 FOREACH_FUNCTION_ARGS (type, t, iter)
8908 {
8909 if (argpos == tgarg)
8910 {
8911 tg_type.quick_push (TYPE_MAIN_VARIANT (t));
8912 break;
8913 }
8914 argpos++;
8915 }
8916 }
8917
8918 /* Verify that the corresponding types are different for
8919 all the listed functions. Also determine whether all
8920 the types are complex, whether all the types are
8921 standard or binary, and whether all the types are
8922 decimal. */
8923 bool all_complex = true;
8924 bool all_binary = true;
8925 bool all_decimal = true;
8926 hash_set<tree> tg_types;
8927 FOR_EACH_VEC_ELT (tg_type, i, t)
8928 {
8929 if (TREE_CODE (t) == COMPLEX_TYPE)
8930 all_decimal = false;
8931 else
8932 {
8933 all_complex = false;
8934 if (DECIMAL_FLOAT_TYPE_P (t))
8935 all_binary = false;
8936 else
8937 all_decimal = false;
8938 }
8939 if (tg_types.add (t))
8940 {
8941 error_at ((*cexpr_list)[i].get_location (),
8942 "duplicate type-generic parameter type for "
8943 "function argument %u of %<__builtin_tgmath%>",
8944 i + 1);
8945 expr.set_error ();
8946 goto out;
8947 }
8948 }
8949
8950 /* Verify that other parameters and the return type whose
8951 types vary have their types varying in the correct
8952 way. */
8953 for (unsigned int j = 0; j < num_functions; j++)
8954 {
8955 tree exp_type = tg_type[j];
8956 tree exp_real_type = exp_type;
8957 if (TREE_CODE (exp_type) == COMPLEX_TYPE)
8958 exp_real_type = TREE_TYPE (exp_type);
8959 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
8960 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
8961 if ((parm_kind[0] == tgmath_complex && ret != exp_type)
8962 || (parm_kind[0] == tgmath_real && ret != exp_real_type))
8963 {
8964 error_at ((*cexpr_list)[j].get_location (),
8965 "bad return type for function argument %u "
8966 "of %<__builtin_tgmath%>", j + 1);
8967 expr.set_error ();
8968 goto out;
8969 }
8970 argpos = 1;
8971 FOREACH_FUNCTION_ARGS (type, t, iter)
8972 {
8973 if (t == void_type_node)
8974 break;
8975 t = TYPE_MAIN_VARIANT (t);
8976 if ((parm_kind[argpos] == tgmath_complex
8977 && t != exp_type)
8978 || (parm_kind[argpos] == tgmath_real
8979 && t != exp_real_type))
8980 {
8981 error_at ((*cexpr_list)[j].get_location (),
8982 "bad type for argument %u of "
8983 "function argument %u of "
8984 "%<__builtin_tgmath%>", argpos, j + 1);
8985 expr.set_error ();
8986 goto out;
8987 }
8988 argpos++;
8989 }
8990 }
8991
8992 /* The functions listed are a valid set of functions for a
8993 <tgmath.h> macro to select between. Identify the
8994 matching function, if any. First, the argument types
8995 must be combined following <tgmath.h> rules. Integer
8996 types are treated as _Decimal64 if any type-generic
8997 argument is decimal, or if the only alternatives for
8998 type-generic arguments are of decimal types, and are
8999 otherwise treated as double (or _Complex double for
9000 complex integer types, or _Float64 or _Complex _Float64
9001 if all the return types are the same _FloatN or
9002 _FloatNx type). After that adjustment, types are
9003 combined following the usual arithmetic conversions.
9004 If the function only accepts complex arguments, a
9005 complex type is produced. */
9006 bool arg_complex = all_complex;
9007 bool arg_binary = all_binary;
9008 bool arg_int_decimal = all_decimal;
9009 for (unsigned int j = 1; j <= nargs; j++)
9010 {
9011 if (parm_kind[j] == tgmath_fixed)
9012 continue;
9013 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
9014 tree type = TREE_TYPE (ce->value);
9015 if (!INTEGRAL_TYPE_P (type)
9016 && !SCALAR_FLOAT_TYPE_P (type)
9017 && TREE_CODE (type) != COMPLEX_TYPE)
9018 {
9019 error_at (ce->get_location (),
9020 "invalid type of argument %u of type-generic "
9021 "function", j);
9022 expr.set_error ();
9023 goto out;
9024 }
9025 if (DECIMAL_FLOAT_TYPE_P (type))
9026 {
9027 arg_int_decimal = true;
9028 if (all_complex)
9029 {
9030 error_at (ce->get_location (),
9031 "decimal floating-point argument %u to "
9032 "complex-only type-generic function", j);
9033 expr.set_error ();
9034 goto out;
9035 }
9036 else if (all_binary)
9037 {
9038 error_at (ce->get_location (),
9039 "decimal floating-point argument %u to "
9040 "binary-only type-generic function", j);
9041 expr.set_error ();
9042 goto out;
9043 }
9044 else if (arg_complex)
9045 {
9046 error_at (ce->get_location (),
9047 "both complex and decimal floating-point "
9048 "arguments to type-generic function");
9049 expr.set_error ();
9050 goto out;
9051 }
9052 else if (arg_binary)
9053 {
9054 error_at (ce->get_location (),
9055 "both binary and decimal floating-point "
9056 "arguments to type-generic function");
9057 expr.set_error ();
9058 goto out;
9059 }
9060 }
9061 else if (TREE_CODE (type) == COMPLEX_TYPE)
9062 {
9063 arg_complex = true;
9064 if (COMPLEX_FLOAT_TYPE_P (type))
9065 arg_binary = true;
9066 if (all_decimal)
9067 {
9068 error_at (ce->get_location (),
9069 "complex argument %u to "
9070 "decimal-only type-generic function", j);
9071 expr.set_error ();
9072 goto out;
9073 }
9074 else if (arg_int_decimal)
9075 {
9076 error_at (ce->get_location (),
9077 "both complex and decimal floating-point "
9078 "arguments to type-generic function");
9079 expr.set_error ();
9080 goto out;
9081 }
9082 }
9083 else if (SCALAR_FLOAT_TYPE_P (type))
9084 {
9085 arg_binary = true;
9086 if (all_decimal)
9087 {
9088 error_at (ce->get_location (),
9089 "binary argument %u to "
9090 "decimal-only type-generic function", j);
9091 expr.set_error ();
9092 goto out;
9093 }
9094 else if (arg_int_decimal)
9095 {
9096 error_at (ce->get_location (),
9097 "both binary and decimal floating-point "
9098 "arguments to type-generic function");
9099 expr.set_error ();
9100 goto out;
9101 }
9102 }
9103 }
9104 /* For a macro rounding its result to a narrower type, map
9105 integer types to _Float64 not double if the return type
9106 is a _FloatN or _FloatNx type. */
9107 bool arg_int_float64 = false;
9108 if (parm_kind[0] == tgmath_fixed
9109 && SCALAR_FLOAT_TYPE_P (parm_first[0])
9110 && float64_type_node != NULL_TREE)
9111 for (unsigned int j = 0; j < NUM_FLOATN_NX_TYPES; j++)
9112 if (parm_first[0] == FLOATN_TYPE_NODE (j))
9113 {
9114 arg_int_float64 = true;
9115 break;
9116 }
9117 tree arg_real = NULL_TREE;
9118 for (unsigned int j = 1; j <= nargs; j++)
9119 {
9120 if (parm_kind[j] == tgmath_fixed)
9121 continue;
9122 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
9123 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ce->value));
9124 if (TREE_CODE (type) == COMPLEX_TYPE)
9125 type = TREE_TYPE (type);
9126 if (INTEGRAL_TYPE_P (type))
9127 type = (arg_int_decimal
9128 ? dfloat64_type_node
9129 : arg_int_float64
9130 ? float64_type_node
9131 : double_type_node);
9132 if (arg_real == NULL_TREE)
9133 arg_real = type;
9134 else
9135 arg_real = common_type (arg_real, type);
9136 if (arg_real == error_mark_node)
9137 {
9138 expr.set_error ();
9139 goto out;
9140 }
9141 }
9142 tree arg_type = (arg_complex
9143 ? build_complex_type (arg_real)
9144 : arg_real);
9145
9146 /* Look for a function to call with type-generic parameter
9147 type ARG_TYPE. */
9148 c_expr_t *fn = NULL;
9149 for (unsigned int j = 0; j < num_functions; j++)
9150 {
9151 if (tg_type[j] == arg_type)
9152 {
9153 fn = &(*cexpr_list)[j];
9154 break;
9155 }
9156 }
9157 if (fn == NULL
9158 && parm_kind[0] == tgmath_fixed
9159 && SCALAR_FLOAT_TYPE_P (parm_first[0]))
9160 {
9161 /* Presume this is a macro that rounds its result to a
9162 narrower type, and look for the first function with
9163 at least the range and precision of the argument
9164 type. */
9165 for (unsigned int j = 0; j < num_functions; j++)
9166 {
9167 if (arg_complex
9168 != (TREE_CODE (tg_type[j]) == COMPLEX_TYPE))
9169 continue;
9170 tree real_tg_type = (arg_complex
9171 ? TREE_TYPE (tg_type[j])
9172 : tg_type[j]);
9173 if (DECIMAL_FLOAT_TYPE_P (arg_real)
9174 != DECIMAL_FLOAT_TYPE_P (real_tg_type))
9175 continue;
9176 scalar_float_mode arg_mode
9177 = SCALAR_FLOAT_TYPE_MODE (arg_real);
9178 scalar_float_mode tg_mode
9179 = SCALAR_FLOAT_TYPE_MODE (real_tg_type);
9180 const real_format *arg_fmt = REAL_MODE_FORMAT (arg_mode);
9181 const real_format *tg_fmt = REAL_MODE_FORMAT (tg_mode);
9182 if (arg_fmt->b == tg_fmt->b
9183 && arg_fmt->p <= tg_fmt->p
9184 && arg_fmt->emax <= tg_fmt->emax
9185 && (arg_fmt->emin - arg_fmt->p
9186 >= tg_fmt->emin - tg_fmt->p))
9187 {
9188 fn = &(*cexpr_list)[j];
9189 break;
9190 }
9191 }
9192 }
9193 if (fn == NULL)
9194 {
9195 error_at (loc, "no matching function for type-generic call");
9196 expr.set_error ();
9197 break;
9198 }
9199
9200 /* Construct a call to FN. */
9201 vec<tree, va_gc> *args;
9202 vec_alloc (args, nargs);
9203 vec<tree, va_gc> *origtypes;
9204 vec_alloc (origtypes, nargs);
9205 auto_vec<location_t> arg_loc (nargs);
9206 for (unsigned int j = 0; j < nargs; j++)
9207 {
9208 c_expr_t *ce = &(*cexpr_list)[num_functions + j];
9209 args->quick_push (ce->value);
9210 arg_loc.quick_push (ce->get_location ());
9211 origtypes->quick_push (ce->original_type);
9212 }
9213 expr.value = c_build_function_call_vec (loc, arg_loc, fn->value,
9214 args, origtypes);
9215 set_c_expr_source_range (&expr, loc, close_paren_loc);
9216 break;
9217 }
9218 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN:
9219 {
9220 vec<c_expr_t, va_gc> *cexpr_list;
9221 c_expr_t *e2_p;
9222 tree chain_value;
9223 location_t close_paren_loc;
9224
9225 c_parser_consume_token (parser);
9226 if (!c_parser_get_builtin_args (parser,
9227 "__builtin_call_with_static_chain",
9228 &cexpr_list, false,
9229 &close_paren_loc))
9230 {
9231 expr.set_error ();
9232 break;
9233 }
9234 if (vec_safe_length (cexpr_list) != 2)
9235 {
9236 error_at (loc, "wrong number of arguments to "
9237 "%<__builtin_call_with_static_chain%>");
9238 expr.set_error ();
9239 break;
9240 }
9241
9242 expr = (*cexpr_list)[0];
9243 e2_p = &(*cexpr_list)[1];
9244 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
9245 chain_value = e2_p->value;
9246 mark_exp_read (chain_value);
9247
9248 if (TREE_CODE (expr.value) != CALL_EXPR)
9249 error_at (loc, "first argument to "
9250 "%<__builtin_call_with_static_chain%> "
9251 "must be a call expression");
9252 else if (TREE_CODE (TREE_TYPE (chain_value)) != POINTER_TYPE)
9253 error_at (loc, "second argument to "
9254 "%<__builtin_call_with_static_chain%> "
9255 "must be a pointer type");
9256 else
9257 CALL_EXPR_STATIC_CHAIN (expr.value) = chain_value;
9258 set_c_expr_source_range (&expr, loc, close_paren_loc);
9259 break;
9260 }
9261 case RID_BUILTIN_COMPLEX:
9262 {
9263 vec<c_expr_t, va_gc> *cexpr_list;
9264 c_expr_t *e1_p, *e2_p;
9265 location_t close_paren_loc;
9266
9267 c_parser_consume_token (parser);
9268 if (!c_parser_get_builtin_args (parser,
9269 "__builtin_complex",
9270 &cexpr_list, false,
9271 &close_paren_loc))
9272 {
9273 expr.set_error ();
9274 break;
9275 }
9276
9277 if (vec_safe_length (cexpr_list) != 2)
9278 {
9279 error_at (loc, "wrong number of arguments to "
9280 "%<__builtin_complex%>");
9281 expr.set_error ();
9282 break;
9283 }
9284
9285 e1_p = &(*cexpr_list)[0];
9286 e2_p = &(*cexpr_list)[1];
9287
9288 *e1_p = convert_lvalue_to_rvalue (loc, *e1_p, true, true);
9289 if (TREE_CODE (e1_p->value) == EXCESS_PRECISION_EXPR)
9290 e1_p->value = convert (TREE_TYPE (e1_p->value),
9291 TREE_OPERAND (e1_p->value, 0));
9292 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
9293 if (TREE_CODE (e2_p->value) == EXCESS_PRECISION_EXPR)
9294 e2_p->value = convert (TREE_TYPE (e2_p->value),
9295 TREE_OPERAND (e2_p->value, 0));
9296 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
9297 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
9298 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p->value))
9299 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p->value)))
9300 {
9301 error_at (loc, "%<__builtin_complex%> operand "
9302 "not of real binary floating-point type");
9303 expr.set_error ();
9304 break;
9305 }
9306 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p->value))
9307 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p->value)))
9308 {
9309 error_at (loc,
9310 "%<__builtin_complex%> operands of different types");
9311 expr.set_error ();
9312 break;
9313 }
9314 pedwarn_c90 (loc, OPT_Wpedantic,
9315 "ISO C90 does not support complex types");
9316 expr.value = build2_loc (loc, COMPLEX_EXPR,
9317 build_complex_type
9318 (TYPE_MAIN_VARIANT
9319 (TREE_TYPE (e1_p->value))),
9320 e1_p->value, e2_p->value);
9321 set_c_expr_source_range (&expr, loc, close_paren_loc);
9322 break;
9323 }
9324 case RID_BUILTIN_SHUFFLE:
9325 {
9326 vec<c_expr_t, va_gc> *cexpr_list;
9327 unsigned int i;
9328 c_expr_t *p;
9329 location_t close_paren_loc;
9330
9331 c_parser_consume_token (parser);
9332 if (!c_parser_get_builtin_args (parser,
9333 "__builtin_shuffle",
9334 &cexpr_list, false,
9335 &close_paren_loc))
9336 {
9337 expr.set_error ();
9338 break;
9339 }
9340
9341 FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
9342 *p = convert_lvalue_to_rvalue (loc, *p, true, true);
9343
9344 if (vec_safe_length (cexpr_list) == 2)
9345 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
9346 NULL_TREE,
9347 (*cexpr_list)[1].value);
9348
9349 else if (vec_safe_length (cexpr_list) == 3)
9350 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
9351 (*cexpr_list)[1].value,
9352 (*cexpr_list)[2].value);
9353 else
9354 {
9355 error_at (loc, "wrong number of arguments to "
9356 "%<__builtin_shuffle%>");
9357 expr.set_error ();
9358 }
9359 set_c_expr_source_range (&expr, loc, close_paren_loc);
9360 break;
9361 }
9362 case RID_BUILTIN_CONVERTVECTOR:
9363 {
9364 location_t start_loc = loc;
9365 c_parser_consume_token (parser);
9366 matching_parens parens;
9367 if (!parens.require_open (parser))
9368 {
9369 expr.set_error ();
9370 break;
9371 }
9372 e1 = c_parser_expr_no_commas (parser, NULL);
9373 mark_exp_read (e1.value);
9374 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
9375 {
9376 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9377 expr.set_error ();
9378 break;
9379 }
9380 loc = c_parser_peek_token (parser)->location;
9381 t1 = c_parser_type_name (parser);
9382 location_t end_loc = c_parser_peek_token (parser)->get_finish ();
9383 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9384 "expected %<)%>");
9385 if (t1 == NULL)
9386 expr.set_error ();
9387 else
9388 {
9389 tree type_expr = NULL_TREE;
9390 expr.value = c_build_vec_convert (start_loc, e1.value, loc,
9391 groktypename (t1, &type_expr,
9392 NULL));
9393 set_c_expr_source_range (&expr, start_loc, end_loc);
9394 }
9395 }
9396 break;
9397 case RID_AT_SELECTOR:
9398 {
9399 gcc_assert (c_dialect_objc ());
9400 c_parser_consume_token (parser);
9401 matching_parens parens;
9402 if (!parens.require_open (parser))
9403 {
9404 expr.set_error ();
9405 break;
9406 }
9407 tree sel = c_parser_objc_selector_arg (parser);
9408 location_t close_loc = c_parser_peek_token (parser)->location;
9409 parens.skip_until_found_close (parser);
9410 expr.value = objc_build_selector_expr (loc, sel);
9411 set_c_expr_source_range (&expr, loc, close_loc);
9412 }
9413 break;
9414 case RID_AT_PROTOCOL:
9415 {
9416 gcc_assert (c_dialect_objc ());
9417 c_parser_consume_token (parser);
9418 matching_parens parens;
9419 if (!parens.require_open (parser))
9420 {
9421 expr.set_error ();
9422 break;
9423 }
9424 if (c_parser_next_token_is_not (parser, CPP_NAME))
9425 {
9426 c_parser_error (parser, "expected identifier");
9427 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9428 expr.set_error ();
9429 break;
9430 }
9431 tree id = c_parser_peek_token (parser)->value;
9432 c_parser_consume_token (parser);
9433 location_t close_loc = c_parser_peek_token (parser)->location;
9434 parens.skip_until_found_close (parser);
9435 expr.value = objc_build_protocol_expr (id);
9436 set_c_expr_source_range (&expr, loc, close_loc);
9437 }
9438 break;
9439 case RID_AT_ENCODE:
9440 {
9441 /* Extension to support C-structures in the archiver. */
9442 gcc_assert (c_dialect_objc ());
9443 c_parser_consume_token (parser);
9444 matching_parens parens;
9445 if (!parens.require_open (parser))
9446 {
9447 expr.set_error ();
9448 break;
9449 }
9450 t1 = c_parser_type_name (parser);
9451 if (t1 == NULL)
9452 {
9453 expr.set_error ();
9454 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
9455 break;
9456 }
9457 location_t close_loc = c_parser_peek_token (parser)->location;
9458 parens.skip_until_found_close (parser);
9459 tree type = groktypename (t1, NULL, NULL);
9460 expr.value = objc_build_encode_expr (type);
9461 set_c_expr_source_range (&expr, loc, close_loc);
9462 }
9463 break;
9464 case RID_GENERIC:
9465 expr = c_parser_generic_selection (parser);
9466 break;
9467 default:
9468 c_parser_error (parser, "expected expression");
9469 expr.set_error ();
9470 break;
9471 }
9472 break;
9473 case CPP_OPEN_SQUARE:
9474 if (c_dialect_objc ())
9475 {
9476 tree receiver, args;
9477 c_parser_consume_token (parser);
9478 receiver = c_parser_objc_receiver (parser);
9479 args = c_parser_objc_message_args (parser);
9480 location_t close_loc = c_parser_peek_token (parser)->location;
9481 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
9482 "expected %<]%>");
9483 expr.value = objc_build_message_expr (receiver, args);
9484 set_c_expr_source_range (&expr, loc, close_loc);
9485 break;
9486 }
9487 /* Else fall through to report error. */
9488 /* FALLTHRU */
9489 default:
9490 c_parser_error (parser, "expected expression");
9491 expr.set_error ();
9492 break;
9493 }
9494 out:
9495 return c_parser_postfix_expression_after_primary
9496 (parser, EXPR_LOC_OR_LOC (expr.value, loc), expr);
9497 }
9498
9499 /* Parse a postfix expression after a parenthesized type name: the
9500 brace-enclosed initializer of a compound literal, possibly followed
9501 by some postfix operators. This is separate because it is not
9502 possible to tell until after the type name whether a cast
9503 expression has a cast or a compound literal, or whether the operand
9504 of sizeof is a parenthesized type name or starts with a compound
9505 literal. TYPE_LOC is the location where TYPE_NAME starts--the
9506 location of the first token after the parentheses around the type
9507 name. */
9508
9509 static struct c_expr
9510 c_parser_postfix_expression_after_paren_type (c_parser *parser,
9511 struct c_type_name *type_name,
9512 location_t type_loc)
9513 {
9514 tree type;
9515 struct c_expr init;
9516 bool non_const;
9517 struct c_expr expr;
9518 location_t start_loc;
9519 tree type_expr = NULL_TREE;
9520 bool type_expr_const = true;
9521 check_compound_literal_type (type_loc, type_name);
9522 rich_location richloc (line_table, type_loc);
9523 start_init (NULL_TREE, NULL, 0, &richloc);
9524 type = groktypename (type_name, &type_expr, &type_expr_const);
9525 start_loc = c_parser_peek_token (parser)->location;
9526 if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type))
9527 {
9528 error_at (type_loc, "compound literal has variable size");
9529 type = error_mark_node;
9530 }
9531 init = c_parser_braced_init (parser, type, false, NULL);
9532 finish_init ();
9533 maybe_warn_string_init (type_loc, type, init);
9534
9535 if (type != error_mark_node
9536 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type))
9537 && current_function_decl)
9538 {
9539 error ("compound literal qualified by address-space qualifier");
9540 type = error_mark_node;
9541 }
9542
9543 pedwarn_c90 (start_loc, OPT_Wpedantic, "ISO C90 forbids compound literals");
9544 non_const = ((init.value && TREE_CODE (init.value) == CONSTRUCTOR)
9545 ? CONSTRUCTOR_NON_CONST (init.value)
9546 : init.original_code == C_MAYBE_CONST_EXPR);
9547 non_const |= !type_expr_const;
9548 unsigned int alignas_align = 0;
9549 if (type != error_mark_node
9550 && type_name->specs->align_log != -1)
9551 {
9552 alignas_align = 1U << type_name->specs->align_log;
9553 if (alignas_align < min_align_of_type (type))
9554 {
9555 error_at (type_name->specs->locations[cdw_alignas],
9556 "%<_Alignas%> specifiers cannot reduce "
9557 "alignment of compound literal");
9558 alignas_align = 0;
9559 }
9560 }
9561 expr.value = build_compound_literal (start_loc, type, init.value, non_const,
9562 alignas_align);
9563 set_c_expr_source_range (&expr, init.src_range);
9564 expr.original_code = ERROR_MARK;
9565 expr.original_type = NULL;
9566 if (type != error_mark_node
9567 && expr.value != error_mark_node
9568 && type_expr)
9569 {
9570 if (TREE_CODE (expr.value) == C_MAYBE_CONST_EXPR)
9571 {
9572 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr.value) == NULL_TREE);
9573 C_MAYBE_CONST_EXPR_PRE (expr.value) = type_expr;
9574 }
9575 else
9576 {
9577 gcc_assert (!non_const);
9578 expr.value = build2 (C_MAYBE_CONST_EXPR, type,
9579 type_expr, expr.value);
9580 }
9581 }
9582 return c_parser_postfix_expression_after_primary (parser, start_loc, expr);
9583 }
9584
9585 /* Callback function for sizeof_pointer_memaccess_warning to compare
9586 types. */
9587
9588 static bool
9589 sizeof_ptr_memacc_comptypes (tree type1, tree type2)
9590 {
9591 return comptypes (type1, type2) == 1;
9592 }
9593
9594 /* Warn for patterns where abs-like function appears to be used incorrectly,
9595 gracefully ignore any non-abs-like function. The warning location should
9596 be LOC. FNDECL is the declaration of called function, it must be a
9597 BUILT_IN_NORMAL function. ARG is the first and only argument of the
9598 call. */
9599
9600 static void
9601 warn_for_abs (location_t loc, tree fndecl, tree arg)
9602 {
9603 /* Avoid warning in unreachable subexpressions. */
9604 if (c_inhibit_evaluation_warnings)
9605 return;
9606
9607 tree atype = TREE_TYPE (arg);
9608
9609 /* Casts from pointers (and thus arrays and fndecls) will generate
9610 -Wint-conversion warnings. Most other wrong types hopefully lead to type
9611 mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P
9612 types and possibly other exotic types. */
9613 if (!INTEGRAL_TYPE_P (atype)
9614 && !SCALAR_FLOAT_TYPE_P (atype)
9615 && TREE_CODE (atype) != COMPLEX_TYPE)
9616 return;
9617
9618 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
9619
9620 switch (fcode)
9621 {
9622 case BUILT_IN_ABS:
9623 case BUILT_IN_LABS:
9624 case BUILT_IN_LLABS:
9625 case BUILT_IN_IMAXABS:
9626 if (!INTEGRAL_TYPE_P (atype))
9627 {
9628 if (SCALAR_FLOAT_TYPE_P (atype))
9629 warning_at (loc, OPT_Wabsolute_value,
9630 "using integer absolute value function %qD when "
9631 "argument is of floating-point type %qT",
9632 fndecl, atype);
9633 else if (TREE_CODE (atype) == COMPLEX_TYPE)
9634 warning_at (loc, OPT_Wabsolute_value,
9635 "using integer absolute value function %qD when "
9636 "argument is of complex type %qT", fndecl, atype);
9637 else
9638 gcc_unreachable ();
9639 return;
9640 }
9641 if (TYPE_UNSIGNED (atype))
9642 warning_at (loc, OPT_Wabsolute_value,
9643 "taking the absolute value of unsigned type %qT "
9644 "has no effect", atype);
9645 break;
9646
9647 CASE_FLT_FN (BUILT_IN_FABS):
9648 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS):
9649 if (!SCALAR_FLOAT_TYPE_P (atype)
9650 || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype)))
9651 {
9652 if (INTEGRAL_TYPE_P (atype))
9653 warning_at (loc, OPT_Wabsolute_value,
9654 "using floating-point absolute value function %qD "
9655 "when argument is of integer type %qT", fndecl, atype);
9656 else if (DECIMAL_FLOAT_TYPE_P (atype))
9657 warning_at (loc, OPT_Wabsolute_value,
9658 "using floating-point absolute value function %qD "
9659 "when argument is of decimal floating-point type %qT",
9660 fndecl, atype);
9661 else if (TREE_CODE (atype) == COMPLEX_TYPE)
9662 warning_at (loc, OPT_Wabsolute_value,
9663 "using floating-point absolute value function %qD when "
9664 "argument is of complex type %qT", fndecl, atype);
9665 else
9666 gcc_unreachable ();
9667 return;
9668 }
9669 break;
9670
9671 CASE_FLT_FN (BUILT_IN_CABS):
9672 if (TREE_CODE (atype) != COMPLEX_TYPE)
9673 {
9674 if (INTEGRAL_TYPE_P (atype))
9675 warning_at (loc, OPT_Wabsolute_value,
9676 "using complex absolute value function %qD when "
9677 "argument is of integer type %qT", fndecl, atype);
9678 else if (SCALAR_FLOAT_TYPE_P (atype))
9679 warning_at (loc, OPT_Wabsolute_value,
9680 "using complex absolute value function %qD when "
9681 "argument is of floating-point type %qT",
9682 fndecl, atype);
9683 else
9684 gcc_unreachable ();
9685
9686 return;
9687 }
9688 break;
9689
9690 case BUILT_IN_FABSD32:
9691 case BUILT_IN_FABSD64:
9692 case BUILT_IN_FABSD128:
9693 if (!DECIMAL_FLOAT_TYPE_P (atype))
9694 {
9695 if (INTEGRAL_TYPE_P (atype))
9696 warning_at (loc, OPT_Wabsolute_value,
9697 "using decimal floating-point absolute value "
9698 "function %qD when argument is of integer type %qT",
9699 fndecl, atype);
9700 else if (SCALAR_FLOAT_TYPE_P (atype))
9701 warning_at (loc, OPT_Wabsolute_value,
9702 "using decimal floating-point absolute value "
9703 "function %qD when argument is of floating-point "
9704 "type %qT", fndecl, atype);
9705 else if (TREE_CODE (atype) == COMPLEX_TYPE)
9706 warning_at (loc, OPT_Wabsolute_value,
9707 "using decimal floating-point absolute value "
9708 "function %qD when argument is of complex type %qT",
9709 fndecl, atype);
9710 else
9711 gcc_unreachable ();
9712 return;
9713 }
9714 break;
9715
9716 default:
9717 return;
9718 }
9719
9720 if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
9721 return;
9722
9723 tree ftype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
9724 if (TREE_CODE (atype) == COMPLEX_TYPE)
9725 {
9726 gcc_assert (TREE_CODE (ftype) == COMPLEX_TYPE);
9727 atype = TREE_TYPE (atype);
9728 ftype = TREE_TYPE (ftype);
9729 }
9730
9731 if (TYPE_PRECISION (ftype) < TYPE_PRECISION (atype))
9732 warning_at (loc, OPT_Wabsolute_value,
9733 "absolute value function %qD given an argument of type %qT "
9734 "but has parameter of type %qT which may cause truncation "
9735 "of value", fndecl, atype, ftype);
9736 }
9737
9738
9739 /* Parse a postfix expression after the initial primary or compound
9740 literal; that is, parse a series of postfix operators.
9741
9742 EXPR_LOC is the location of the primary expression. */
9743
9744 static struct c_expr
9745 c_parser_postfix_expression_after_primary (c_parser *parser,
9746 location_t expr_loc,
9747 struct c_expr expr)
9748 {
9749 struct c_expr orig_expr;
9750 tree ident, idx;
9751 location_t sizeof_arg_loc[3], comp_loc;
9752 tree sizeof_arg[3];
9753 unsigned int literal_zero_mask;
9754 unsigned int i;
9755 vec<tree, va_gc> *exprlist;
9756 vec<tree, va_gc> *origtypes = NULL;
9757 vec<location_t> arg_loc = vNULL;
9758 location_t start;
9759 location_t finish;
9760
9761 while (true)
9762 {
9763 location_t op_loc = c_parser_peek_token (parser)->location;
9764 switch (c_parser_peek_token (parser)->type)
9765 {
9766 case CPP_OPEN_SQUARE:
9767 /* Array reference. */
9768 c_parser_consume_token (parser);
9769 idx = c_parser_expression (parser).value;
9770 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
9771 "expected %<]%>");
9772 start = expr.get_start ();
9773 finish = parser->tokens_buf[0].location;
9774 expr.value = build_array_ref (op_loc, expr.value, idx);
9775 set_c_expr_source_range (&expr, start, finish);
9776 expr.original_code = ERROR_MARK;
9777 expr.original_type = NULL;
9778 break;
9779 case CPP_OPEN_PAREN:
9780 /* Function call. */
9781 c_parser_consume_token (parser);
9782 for (i = 0; i < 3; i++)
9783 {
9784 sizeof_arg[i] = NULL_TREE;
9785 sizeof_arg_loc[i] = UNKNOWN_LOCATION;
9786 }
9787 literal_zero_mask = 0;
9788 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
9789 exprlist = NULL;
9790 else
9791 exprlist = c_parser_expr_list (parser, true, false, &origtypes,
9792 sizeof_arg_loc, sizeof_arg,
9793 &arg_loc, &literal_zero_mask);
9794 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
9795 "expected %<)%>");
9796 orig_expr = expr;
9797 mark_exp_read (expr.value);
9798 if (warn_sizeof_pointer_memaccess)
9799 sizeof_pointer_memaccess_warning (sizeof_arg_loc,
9800 expr.value, exprlist,
9801 sizeof_arg,
9802 sizeof_ptr_memacc_comptypes);
9803 if (TREE_CODE (expr.value) == FUNCTION_DECL)
9804 {
9805 if (fndecl_built_in_p (expr.value, BUILT_IN_MEMSET)
9806 && vec_safe_length (exprlist) == 3)
9807 {
9808 tree arg0 = (*exprlist)[0];
9809 tree arg2 = (*exprlist)[2];
9810 warn_for_memset (expr_loc, arg0, arg2, literal_zero_mask);
9811 }
9812 if (warn_absolute_value
9813 && fndecl_built_in_p (expr.value, BUILT_IN_NORMAL)
9814 && vec_safe_length (exprlist) == 1)
9815 warn_for_abs (expr_loc, expr.value, (*exprlist)[0]);
9816 }
9817
9818 start = expr.get_start ();
9819 finish = parser->tokens_buf[0].get_finish ();
9820 expr.value
9821 = c_build_function_call_vec (expr_loc, arg_loc, expr.value,
9822 exprlist, origtypes);
9823 set_c_expr_source_range (&expr, start, finish);
9824
9825 expr.original_code = ERROR_MARK;
9826 if (TREE_CODE (expr.value) == INTEGER_CST
9827 && TREE_CODE (orig_expr.value) == FUNCTION_DECL
9828 && fndecl_built_in_p (orig_expr.value, BUILT_IN_CONSTANT_P))
9829 expr.original_code = C_MAYBE_CONST_EXPR;
9830 expr.original_type = NULL;
9831 if (exprlist)
9832 {
9833 release_tree_vector (exprlist);
9834 release_tree_vector (origtypes);
9835 }
9836 arg_loc.release ();
9837 break;
9838 case CPP_DOT:
9839 /* Structure element reference. */
9840 c_parser_consume_token (parser);
9841 expr = default_function_array_conversion (expr_loc, expr);
9842 if (c_parser_next_token_is (parser, CPP_NAME))
9843 {
9844 c_token *comp_tok = c_parser_peek_token (parser);
9845 ident = comp_tok->value;
9846 comp_loc = comp_tok->location;
9847 }
9848 else
9849 {
9850 c_parser_error (parser, "expected identifier");
9851 expr.set_error ();
9852 expr.original_code = ERROR_MARK;
9853 expr.original_type = NULL;
9854 return expr;
9855 }
9856 start = expr.get_start ();
9857 finish = c_parser_peek_token (parser)->get_finish ();
9858 c_parser_consume_token (parser);
9859 expr.value = build_component_ref (op_loc, expr.value, ident,
9860 comp_loc);
9861 set_c_expr_source_range (&expr, start, finish);
9862 expr.original_code = ERROR_MARK;
9863 if (TREE_CODE (expr.value) != COMPONENT_REF)
9864 expr.original_type = NULL;
9865 else
9866 {
9867 /* Remember the original type of a bitfield. */
9868 tree field = TREE_OPERAND (expr.value, 1);
9869 if (TREE_CODE (field) != FIELD_DECL)
9870 expr.original_type = NULL;
9871 else
9872 expr.original_type = DECL_BIT_FIELD_TYPE (field);
9873 }
9874 break;
9875 case CPP_DEREF:
9876 /* Structure element reference. */
9877 c_parser_consume_token (parser);
9878 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, false);
9879 if (c_parser_next_token_is (parser, CPP_NAME))
9880 {
9881 c_token *comp_tok = c_parser_peek_token (parser);
9882 ident = comp_tok->value;
9883 comp_loc = comp_tok->location;
9884 }
9885 else
9886 {
9887 c_parser_error (parser, "expected identifier");
9888 expr.set_error ();
9889 expr.original_code = ERROR_MARK;
9890 expr.original_type = NULL;
9891 return expr;
9892 }
9893 start = expr.get_start ();
9894 finish = c_parser_peek_token (parser)->get_finish ();
9895 c_parser_consume_token (parser);
9896 expr.value = build_component_ref (op_loc,
9897 build_indirect_ref (op_loc,
9898 expr.value,
9899 RO_ARROW),
9900 ident, comp_loc);
9901 set_c_expr_source_range (&expr, start, finish);
9902 expr.original_code = ERROR_MARK;
9903 if (TREE_CODE (expr.value) != COMPONENT_REF)
9904 expr.original_type = NULL;
9905 else
9906 {
9907 /* Remember the original type of a bitfield. */
9908 tree field = TREE_OPERAND (expr.value, 1);
9909 if (TREE_CODE (field) != FIELD_DECL)
9910 expr.original_type = NULL;
9911 else
9912 expr.original_type = DECL_BIT_FIELD_TYPE (field);
9913 }
9914 break;
9915 case CPP_PLUS_PLUS:
9916 /* Postincrement. */
9917 start = expr.get_start ();
9918 finish = c_parser_peek_token (parser)->get_finish ();
9919 c_parser_consume_token (parser);
9920 expr = default_function_array_read_conversion (expr_loc, expr);
9921 expr.value = build_unary_op (op_loc, POSTINCREMENT_EXPR,
9922 expr.value, false);
9923 set_c_expr_source_range (&expr, start, finish);
9924 expr.original_code = ERROR_MARK;
9925 expr.original_type = NULL;
9926 break;
9927 case CPP_MINUS_MINUS:
9928 /* Postdecrement. */
9929 start = expr.get_start ();
9930 finish = c_parser_peek_token (parser)->get_finish ();
9931 c_parser_consume_token (parser);
9932 expr = default_function_array_read_conversion (expr_loc, expr);
9933 expr.value = build_unary_op (op_loc, POSTDECREMENT_EXPR,
9934 expr.value, false);
9935 set_c_expr_source_range (&expr, start, finish);
9936 expr.original_code = ERROR_MARK;
9937 expr.original_type = NULL;
9938 break;
9939 default:
9940 return expr;
9941 }
9942 }
9943 }
9944
9945 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
9946
9947 expression:
9948 assignment-expression
9949 expression , assignment-expression
9950 */
9951
9952 static struct c_expr
9953 c_parser_expression (c_parser *parser)
9954 {
9955 location_t tloc = c_parser_peek_token (parser)->location;
9956 struct c_expr expr;
9957 expr = c_parser_expr_no_commas (parser, NULL);
9958 if (c_parser_next_token_is (parser, CPP_COMMA))
9959 expr = convert_lvalue_to_rvalue (tloc, expr, true, false);
9960 while (c_parser_next_token_is (parser, CPP_COMMA))
9961 {
9962 struct c_expr next;
9963 tree lhsval;
9964 location_t loc = c_parser_peek_token (parser)->location;
9965 location_t expr_loc;
9966 c_parser_consume_token (parser);
9967 expr_loc = c_parser_peek_token (parser)->location;
9968 lhsval = expr.value;
9969 while (TREE_CODE (lhsval) == COMPOUND_EXPR)
9970 lhsval = TREE_OPERAND (lhsval, 1);
9971 if (DECL_P (lhsval) || handled_component_p (lhsval))
9972 mark_exp_read (lhsval);
9973 next = c_parser_expr_no_commas (parser, NULL);
9974 next = convert_lvalue_to_rvalue (expr_loc, next, true, false);
9975 expr.value = build_compound_expr (loc, expr.value, next.value);
9976 expr.original_code = COMPOUND_EXPR;
9977 expr.original_type = next.original_type;
9978 }
9979 return expr;
9980 }
9981
9982 /* Parse an expression and convert functions or arrays to pointers and
9983 lvalues to rvalues. */
9984
9985 static struct c_expr
9986 c_parser_expression_conv (c_parser *parser)
9987 {
9988 struct c_expr expr;
9989 location_t loc = c_parser_peek_token (parser)->location;
9990 expr = c_parser_expression (parser);
9991 expr = convert_lvalue_to_rvalue (loc, expr, true, false);
9992 return expr;
9993 }
9994
9995 /* Helper function of c_parser_expr_list. Check if IDXth (0 based)
9996 argument is a literal zero alone and if so, set it in literal_zero_mask. */
9997
9998 static inline void
9999 c_parser_check_literal_zero (c_parser *parser, unsigned *literal_zero_mask,
10000 unsigned int idx)
10001 {
10002 if (idx >= HOST_BITS_PER_INT)
10003 return;
10004
10005 c_token *tok = c_parser_peek_token (parser);
10006 switch (tok->type)
10007 {
10008 case CPP_NUMBER:
10009 case CPP_CHAR:
10010 case CPP_WCHAR:
10011 case CPP_CHAR16:
10012 case CPP_CHAR32:
10013 /* If a parameter is literal zero alone, remember it
10014 for -Wmemset-transposed-args warning. */
10015 if (integer_zerop (tok->value)
10016 && !TREE_OVERFLOW (tok->value)
10017 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
10018 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
10019 *literal_zero_mask |= 1U << idx;
10020 default:
10021 break;
10022 }
10023 }
10024
10025 /* Parse a non-empty list of expressions. If CONVERT_P, convert
10026 functions and arrays to pointers and lvalues to rvalues. If
10027 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the
10028 locations of function arguments into this vector.
10029
10030 nonempty-expr-list:
10031 assignment-expression
10032 nonempty-expr-list , assignment-expression
10033 */
10034
10035 static vec<tree, va_gc> *
10036 c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
10037 vec<tree, va_gc> **p_orig_types,
10038 location_t *sizeof_arg_loc, tree *sizeof_arg,
10039 vec<location_t> *locations,
10040 unsigned int *literal_zero_mask)
10041 {
10042 vec<tree, va_gc> *ret;
10043 vec<tree, va_gc> *orig_types;
10044 struct c_expr expr;
10045 unsigned int idx = 0;
10046
10047 ret = make_tree_vector ();
10048 if (p_orig_types == NULL)
10049 orig_types = NULL;
10050 else
10051 orig_types = make_tree_vector ();
10052
10053 if (literal_zero_mask)
10054 c_parser_check_literal_zero (parser, literal_zero_mask, 0);
10055 expr = c_parser_expr_no_commas (parser, NULL);
10056 if (convert_p)
10057 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true, true);
10058 if (fold_p)
10059 expr.value = c_fully_fold (expr.value, false, NULL);
10060 ret->quick_push (expr.value);
10061 if (orig_types)
10062 orig_types->quick_push (expr.original_type);
10063 if (locations)
10064 locations->safe_push (expr.get_location ());
10065 if (sizeof_arg != NULL
10066 && expr.original_code == SIZEOF_EXPR)
10067 {
10068 sizeof_arg[0] = c_last_sizeof_arg;
10069 sizeof_arg_loc[0] = c_last_sizeof_loc;
10070 }
10071 while (c_parser_next_token_is (parser, CPP_COMMA))
10072 {
10073 c_parser_consume_token (parser);
10074 if (literal_zero_mask)
10075 c_parser_check_literal_zero (parser, literal_zero_mask, idx + 1);
10076 expr = c_parser_expr_no_commas (parser, NULL);
10077 if (convert_p)
10078 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true,
10079 true);
10080 if (fold_p)
10081 expr.value = c_fully_fold (expr.value, false, NULL);
10082 vec_safe_push (ret, expr.value);
10083 if (orig_types)
10084 vec_safe_push (orig_types, expr.original_type);
10085 if (locations)
10086 locations->safe_push (expr.get_location ());
10087 if (++idx < 3
10088 && sizeof_arg != NULL
10089 && expr.original_code == SIZEOF_EXPR)
10090 {
10091 sizeof_arg[idx] = c_last_sizeof_arg;
10092 sizeof_arg_loc[idx] = c_last_sizeof_loc;
10093 }
10094 }
10095 if (orig_types)
10096 *p_orig_types = orig_types;
10097 return ret;
10098 }
10099 \f
10100 /* Parse Objective-C-specific constructs. */
10101
10102 /* Parse an objc-class-definition.
10103
10104 objc-class-definition:
10105 @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
10106 objc-class-instance-variables[opt] objc-methodprotolist @end
10107 @implementation identifier objc-superclass[opt]
10108 objc-class-instance-variables[opt]
10109 @interface identifier ( identifier ) objc-protocol-refs[opt]
10110 objc-methodprotolist @end
10111 @interface identifier ( ) objc-protocol-refs[opt]
10112 objc-methodprotolist @end
10113 @implementation identifier ( identifier )
10114
10115 objc-superclass:
10116 : identifier
10117
10118 "@interface identifier (" must start "@interface identifier (
10119 identifier ) ...": objc-methodprotolist in the first production may
10120 not start with a parenthesized identifier as a declarator of a data
10121 definition with no declaration specifiers if the objc-superclass,
10122 objc-protocol-refs and objc-class-instance-variables are omitted. */
10123
10124 static void
10125 c_parser_objc_class_definition (c_parser *parser, tree attributes)
10126 {
10127 bool iface_p;
10128 tree id1;
10129 tree superclass;
10130 if (c_parser_next_token_is_keyword (parser, RID_AT_INTERFACE))
10131 iface_p = true;
10132 else if (c_parser_next_token_is_keyword (parser, RID_AT_IMPLEMENTATION))
10133 iface_p = false;
10134 else
10135 gcc_unreachable ();
10136
10137 c_parser_consume_token (parser);
10138 if (c_parser_next_token_is_not (parser, CPP_NAME))
10139 {
10140 c_parser_error (parser, "expected identifier");
10141 return;
10142 }
10143 id1 = c_parser_peek_token (parser)->value;
10144 c_parser_consume_token (parser);
10145 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
10146 {
10147 /* We have a category or class extension. */
10148 tree id2;
10149 tree proto = NULL_TREE;
10150 matching_parens parens;
10151 parens.consume_open (parser);
10152 if (c_parser_next_token_is_not (parser, CPP_NAME))
10153 {
10154 if (iface_p && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10155 {
10156 /* We have a class extension. */
10157 id2 = NULL_TREE;
10158 }
10159 else
10160 {
10161 c_parser_error (parser, "expected identifier or %<)%>");
10162 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
10163 return;
10164 }
10165 }
10166 else
10167 {
10168 id2 = c_parser_peek_token (parser)->value;
10169 c_parser_consume_token (parser);
10170 }
10171 parens.skip_until_found_close (parser);
10172 if (!iface_p)
10173 {
10174 objc_start_category_implementation (id1, id2);
10175 return;
10176 }
10177 if (c_parser_next_token_is (parser, CPP_LESS))
10178 proto = c_parser_objc_protocol_refs (parser);
10179 objc_start_category_interface (id1, id2, proto, attributes);
10180 c_parser_objc_methodprotolist (parser);
10181 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
10182 objc_finish_interface ();
10183 return;
10184 }
10185 if (c_parser_next_token_is (parser, CPP_COLON))
10186 {
10187 c_parser_consume_token (parser);
10188 if (c_parser_next_token_is_not (parser, CPP_NAME))
10189 {
10190 c_parser_error (parser, "expected identifier");
10191 return;
10192 }
10193 superclass = c_parser_peek_token (parser)->value;
10194 c_parser_consume_token (parser);
10195 }
10196 else
10197 superclass = NULL_TREE;
10198 if (iface_p)
10199 {
10200 tree proto = NULL_TREE;
10201 if (c_parser_next_token_is (parser, CPP_LESS))
10202 proto = c_parser_objc_protocol_refs (parser);
10203 objc_start_class_interface (id1, superclass, proto, attributes);
10204 }
10205 else
10206 objc_start_class_implementation (id1, superclass);
10207 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
10208 c_parser_objc_class_instance_variables (parser);
10209 if (iface_p)
10210 {
10211 objc_continue_interface ();
10212 c_parser_objc_methodprotolist (parser);
10213 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
10214 objc_finish_interface ();
10215 }
10216 else
10217 {
10218 objc_continue_implementation ();
10219 return;
10220 }
10221 }
10222
10223 /* Parse objc-class-instance-variables.
10224
10225 objc-class-instance-variables:
10226 { objc-instance-variable-decl-list[opt] }
10227
10228 objc-instance-variable-decl-list:
10229 objc-visibility-spec
10230 objc-instance-variable-decl ;
10231 ;
10232 objc-instance-variable-decl-list objc-visibility-spec
10233 objc-instance-variable-decl-list objc-instance-variable-decl ;
10234 objc-instance-variable-decl-list ;
10235
10236 objc-visibility-spec:
10237 @private
10238 @protected
10239 @public
10240
10241 objc-instance-variable-decl:
10242 struct-declaration
10243 */
10244
10245 static void
10246 c_parser_objc_class_instance_variables (c_parser *parser)
10247 {
10248 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
10249 c_parser_consume_token (parser);
10250 while (c_parser_next_token_is_not (parser, CPP_EOF))
10251 {
10252 tree decls;
10253 /* Parse any stray semicolon. */
10254 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
10255 {
10256 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
10257 "extra semicolon");
10258 c_parser_consume_token (parser);
10259 continue;
10260 }
10261 /* Stop if at the end of the instance variables. */
10262 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
10263 {
10264 c_parser_consume_token (parser);
10265 break;
10266 }
10267 /* Parse any objc-visibility-spec. */
10268 if (c_parser_next_token_is_keyword (parser, RID_AT_PRIVATE))
10269 {
10270 c_parser_consume_token (parser);
10271 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE);
10272 continue;
10273 }
10274 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROTECTED))
10275 {
10276 c_parser_consume_token (parser);
10277 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED);
10278 continue;
10279 }
10280 else if (c_parser_next_token_is_keyword (parser, RID_AT_PUBLIC))
10281 {
10282 c_parser_consume_token (parser);
10283 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC);
10284 continue;
10285 }
10286 else if (c_parser_next_token_is_keyword (parser, RID_AT_PACKAGE))
10287 {
10288 c_parser_consume_token (parser);
10289 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE);
10290 continue;
10291 }
10292 else if (c_parser_next_token_is (parser, CPP_PRAGMA))
10293 {
10294 c_parser_pragma (parser, pragma_external, NULL);
10295 continue;
10296 }
10297
10298 /* Parse some comma-separated declarations. */
10299 decls = c_parser_struct_declaration (parser);
10300 if (decls == NULL)
10301 {
10302 /* There is a syntax error. We want to skip the offending
10303 tokens up to the next ';' (included) or '}'
10304 (excluded). */
10305
10306 /* First, skip manually a ')' or ']'. This is because they
10307 reduce the nesting level, so c_parser_skip_until_found()
10308 wouldn't be able to skip past them. */
10309 c_token *token = c_parser_peek_token (parser);
10310 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_CLOSE_SQUARE)
10311 c_parser_consume_token (parser);
10312
10313 /* Then, do the standard skipping. */
10314 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
10315
10316 /* We hopefully recovered. Start normal parsing again. */
10317 parser->error = false;
10318 continue;
10319 }
10320 else
10321 {
10322 /* Comma-separated instance variables are chained together
10323 in reverse order; add them one by one. */
10324 tree ivar = nreverse (decls);
10325 for (; ivar; ivar = DECL_CHAIN (ivar))
10326 objc_add_instance_variable (copy_node (ivar));
10327 }
10328 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
10329 }
10330 }
10331
10332 /* Parse an objc-class-declaration.
10333
10334 objc-class-declaration:
10335 @class identifier-list ;
10336 */
10337
10338 static void
10339 c_parser_objc_class_declaration (c_parser *parser)
10340 {
10341 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_CLASS));
10342 c_parser_consume_token (parser);
10343 /* Any identifiers, including those declared as type names, are OK
10344 here. */
10345 while (true)
10346 {
10347 tree id;
10348 if (c_parser_next_token_is_not (parser, CPP_NAME))
10349 {
10350 c_parser_error (parser, "expected identifier");
10351 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
10352 parser->error = false;
10353 return;
10354 }
10355 id = c_parser_peek_token (parser)->value;
10356 objc_declare_class (id);
10357 c_parser_consume_token (parser);
10358 if (c_parser_next_token_is (parser, CPP_COMMA))
10359 c_parser_consume_token (parser);
10360 else
10361 break;
10362 }
10363 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
10364 }
10365
10366 /* Parse an objc-alias-declaration.
10367
10368 objc-alias-declaration:
10369 @compatibility_alias identifier identifier ;
10370 */
10371
10372 static void
10373 c_parser_objc_alias_declaration (c_parser *parser)
10374 {
10375 tree id1, id2;
10376 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_ALIAS));
10377 c_parser_consume_token (parser);
10378 if (c_parser_next_token_is_not (parser, CPP_NAME))
10379 {
10380 c_parser_error (parser, "expected identifier");
10381 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
10382 return;
10383 }
10384 id1 = c_parser_peek_token (parser)->value;
10385 c_parser_consume_token (parser);
10386 if (c_parser_next_token_is_not (parser, CPP_NAME))
10387 {
10388 c_parser_error (parser, "expected identifier");
10389 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
10390 return;
10391 }
10392 id2 = c_parser_peek_token (parser)->value;
10393 c_parser_consume_token (parser);
10394 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
10395 objc_declare_alias (id1, id2);
10396 }
10397
10398 /* Parse an objc-protocol-definition.
10399
10400 objc-protocol-definition:
10401 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
10402 @protocol identifier-list ;
10403
10404 "@protocol identifier ;" should be resolved as "@protocol
10405 identifier-list ;": objc-methodprotolist may not start with a
10406 semicolon in the first alternative if objc-protocol-refs are
10407 omitted. */
10408
10409 static void
10410 c_parser_objc_protocol_definition (c_parser *parser, tree attributes)
10411 {
10412 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROTOCOL));
10413
10414 c_parser_consume_token (parser);
10415 if (c_parser_next_token_is_not (parser, CPP_NAME))
10416 {
10417 c_parser_error (parser, "expected identifier");
10418 return;
10419 }
10420 if (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
10421 || c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON)
10422 {
10423 /* Any identifiers, including those declared as type names, are
10424 OK here. */
10425 while (true)
10426 {
10427 tree id;
10428 if (c_parser_next_token_is_not (parser, CPP_NAME))
10429 {
10430 c_parser_error (parser, "expected identifier");
10431 break;
10432 }
10433 id = c_parser_peek_token (parser)->value;
10434 objc_declare_protocol (id, attributes);
10435 c_parser_consume_token (parser);
10436 if (c_parser_next_token_is (parser, CPP_COMMA))
10437 c_parser_consume_token (parser);
10438 else
10439 break;
10440 }
10441 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
10442 }
10443 else
10444 {
10445 tree id = c_parser_peek_token (parser)->value;
10446 tree proto = NULL_TREE;
10447 c_parser_consume_token (parser);
10448 if (c_parser_next_token_is (parser, CPP_LESS))
10449 proto = c_parser_objc_protocol_refs (parser);
10450 parser->objc_pq_context = true;
10451 objc_start_protocol (id, proto, attributes);
10452 c_parser_objc_methodprotolist (parser);
10453 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
10454 parser->objc_pq_context = false;
10455 objc_finish_interface ();
10456 }
10457 }
10458
10459 /* Parse an objc-method-type.
10460
10461 objc-method-type:
10462 +
10463 -
10464
10465 Return true if it is a class method (+) and false if it is
10466 an instance method (-).
10467 */
10468 static inline bool
10469 c_parser_objc_method_type (c_parser *parser)
10470 {
10471 switch (c_parser_peek_token (parser)->type)
10472 {
10473 case CPP_PLUS:
10474 c_parser_consume_token (parser);
10475 return true;
10476 case CPP_MINUS:
10477 c_parser_consume_token (parser);
10478 return false;
10479 default:
10480 gcc_unreachable ();
10481 }
10482 }
10483
10484 /* Parse an objc-method-definition.
10485
10486 objc-method-definition:
10487 objc-method-type objc-method-decl ;[opt] compound-statement
10488 */
10489
10490 static void
10491 c_parser_objc_method_definition (c_parser *parser)
10492 {
10493 bool is_class_method = c_parser_objc_method_type (parser);
10494 tree decl, attributes = NULL_TREE, expr = NULL_TREE;
10495 parser->objc_pq_context = true;
10496 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
10497 &expr);
10498 if (decl == error_mark_node)
10499 return; /* Bail here. */
10500
10501 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
10502 {
10503 c_parser_consume_token (parser);
10504 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
10505 "extra semicolon in method definition specified");
10506 }
10507
10508 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
10509 {
10510 c_parser_error (parser, "expected %<{%>");
10511 return;
10512 }
10513
10514 parser->objc_pq_context = false;
10515 if (objc_start_method_definition (is_class_method, decl, attributes, expr))
10516 {
10517 add_stmt (c_parser_compound_statement (parser));
10518 objc_finish_method_definition (current_function_decl);
10519 }
10520 else
10521 {
10522 /* This code is executed when we find a method definition
10523 outside of an @implementation context (or invalid for other
10524 reasons). Parse the method (to keep going) but do not emit
10525 any code.
10526 */
10527 c_parser_compound_statement (parser);
10528 }
10529 }
10530
10531 /* Parse an objc-methodprotolist.
10532
10533 objc-methodprotolist:
10534 empty
10535 objc-methodprotolist objc-methodproto
10536 objc-methodprotolist declaration
10537 objc-methodprotolist ;
10538 @optional
10539 @required
10540
10541 The declaration is a data definition, which may be missing
10542 declaration specifiers under the same rules and diagnostics as
10543 other data definitions outside functions, and the stray semicolon
10544 is diagnosed the same way as a stray semicolon outside a
10545 function. */
10546
10547 static void
10548 c_parser_objc_methodprotolist (c_parser *parser)
10549 {
10550 while (true)
10551 {
10552 /* The list is terminated by @end. */
10553 switch (c_parser_peek_token (parser)->type)
10554 {
10555 case CPP_SEMICOLON:
10556 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
10557 "ISO C does not allow extra %<;%> outside of a function");
10558 c_parser_consume_token (parser);
10559 break;
10560 case CPP_PLUS:
10561 case CPP_MINUS:
10562 c_parser_objc_methodproto (parser);
10563 break;
10564 case CPP_PRAGMA:
10565 c_parser_pragma (parser, pragma_external, NULL);
10566 break;
10567 case CPP_EOF:
10568 return;
10569 default:
10570 if (c_parser_next_token_is_keyword (parser, RID_AT_END))
10571 return;
10572 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY))
10573 c_parser_objc_at_property_declaration (parser);
10574 else if (c_parser_next_token_is_keyword (parser, RID_AT_OPTIONAL))
10575 {
10576 objc_set_method_opt (true);
10577 c_parser_consume_token (parser);
10578 }
10579 else if (c_parser_next_token_is_keyword (parser, RID_AT_REQUIRED))
10580 {
10581 objc_set_method_opt (false);
10582 c_parser_consume_token (parser);
10583 }
10584 else
10585 c_parser_declaration_or_fndef (parser, false, false, true,
10586 false, true, NULL, vNULL);
10587 break;
10588 }
10589 }
10590 }
10591
10592 /* Parse an objc-methodproto.
10593
10594 objc-methodproto:
10595 objc-method-type objc-method-decl ;
10596 */
10597
10598 static void
10599 c_parser_objc_methodproto (c_parser *parser)
10600 {
10601 bool is_class_method = c_parser_objc_method_type (parser);
10602 tree decl, attributes = NULL_TREE;
10603
10604 /* Remember protocol qualifiers in prototypes. */
10605 parser->objc_pq_context = true;
10606 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
10607 NULL);
10608 /* Forget protocol qualifiers now. */
10609 parser->objc_pq_context = false;
10610
10611 /* Do not allow the presence of attributes to hide an erroneous
10612 method implementation in the interface section. */
10613 if (!c_parser_next_token_is (parser, CPP_SEMICOLON))
10614 {
10615 c_parser_error (parser, "expected %<;%>");
10616 return;
10617 }
10618
10619 if (decl != error_mark_node)
10620 objc_add_method_declaration (is_class_method, decl, attributes);
10621
10622 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
10623 }
10624
10625 /* If we are at a position that method attributes may be present, check that
10626 there are not any parsed already (a syntax error) and then collect any
10627 specified at the current location. Finally, if new attributes were present,
10628 check that the next token is legal ( ';' for decls and '{' for defs). */
10629
10630 static bool
10631 c_parser_objc_maybe_method_attributes (c_parser* parser, tree* attributes)
10632 {
10633 bool bad = false;
10634 if (*attributes)
10635 {
10636 c_parser_error (parser,
10637 "method attributes must be specified at the end only");
10638 *attributes = NULL_TREE;
10639 bad = true;
10640 }
10641
10642 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
10643 *attributes = c_parser_gnu_attributes (parser);
10644
10645 /* If there were no attributes here, just report any earlier error. */
10646 if (*attributes == NULL_TREE || bad)
10647 return bad;
10648
10649 /* If the attributes are followed by a ; or {, then just report any earlier
10650 error. */
10651 if (c_parser_next_token_is (parser, CPP_SEMICOLON)
10652 || c_parser_next_token_is (parser, CPP_OPEN_BRACE))
10653 return bad;
10654
10655 /* We've got attributes, but not at the end. */
10656 c_parser_error (parser,
10657 "expected %<;%> or %<{%> after method attribute definition");
10658 return true;
10659 }
10660
10661 /* Parse an objc-method-decl.
10662
10663 objc-method-decl:
10664 ( objc-type-name ) objc-selector
10665 objc-selector
10666 ( objc-type-name ) objc-keyword-selector objc-optparmlist
10667 objc-keyword-selector objc-optparmlist
10668 gnu-attributes
10669
10670 objc-keyword-selector:
10671 objc-keyword-decl
10672 objc-keyword-selector objc-keyword-decl
10673
10674 objc-keyword-decl:
10675 objc-selector : ( objc-type-name ) identifier
10676 objc-selector : identifier
10677 : ( objc-type-name ) identifier
10678 : identifier
10679
10680 objc-optparmlist:
10681 objc-optparms objc-optellipsis
10682
10683 objc-optparms:
10684 empty
10685 objc-opt-parms , parameter-declaration
10686
10687 objc-optellipsis:
10688 empty
10689 , ...
10690 */
10691
10692 static tree
10693 c_parser_objc_method_decl (c_parser *parser, bool is_class_method,
10694 tree *attributes, tree *expr)
10695 {
10696 tree type = NULL_TREE;
10697 tree sel;
10698 tree parms = NULL_TREE;
10699 bool ellipsis = false;
10700 bool attr_err = false;
10701
10702 *attributes = NULL_TREE;
10703 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
10704 {
10705 matching_parens parens;
10706 parens.consume_open (parser);
10707 type = c_parser_objc_type_name (parser);
10708 parens.skip_until_found_close (parser);
10709 }
10710 sel = c_parser_objc_selector (parser);
10711 /* If there is no selector, or a colon follows, we have an
10712 objc-keyword-selector. If there is a selector, and a colon does
10713 not follow, that selector ends the objc-method-decl. */
10714 if (!sel || c_parser_next_token_is (parser, CPP_COLON))
10715 {
10716 tree tsel = sel;
10717 tree list = NULL_TREE;
10718 while (true)
10719 {
10720 tree atype = NULL_TREE, id, keyworddecl;
10721 tree param_attr = NULL_TREE;
10722 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
10723 break;
10724 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
10725 {
10726 c_parser_consume_token (parser);
10727 atype = c_parser_objc_type_name (parser);
10728 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
10729 "expected %<)%>");
10730 }
10731 /* New ObjC allows attributes on method parameters. */
10732 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
10733 param_attr = c_parser_gnu_attributes (parser);
10734 if (c_parser_next_token_is_not (parser, CPP_NAME))
10735 {
10736 c_parser_error (parser, "expected identifier");
10737 return error_mark_node;
10738 }
10739 id = c_parser_peek_token (parser)->value;
10740 c_parser_consume_token (parser);
10741 keyworddecl = objc_build_keyword_decl (tsel, atype, id, param_attr);
10742 list = chainon (list, keyworddecl);
10743 tsel = c_parser_objc_selector (parser);
10744 if (!tsel && c_parser_next_token_is_not (parser, CPP_COLON))
10745 break;
10746 }
10747
10748 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
10749
10750 /* Parse the optional parameter list. Optional Objective-C
10751 method parameters follow the C syntax, and may include '...'
10752 to denote a variable number of arguments. */
10753 parms = make_node (TREE_LIST);
10754 while (c_parser_next_token_is (parser, CPP_COMMA))
10755 {
10756 struct c_parm *parm;
10757 c_parser_consume_token (parser);
10758 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
10759 {
10760 ellipsis = true;
10761 c_parser_consume_token (parser);
10762 attr_err |= c_parser_objc_maybe_method_attributes
10763 (parser, attributes) ;
10764 break;
10765 }
10766 parm = c_parser_parameter_declaration (parser, NULL_TREE);
10767 if (parm == NULL)
10768 break;
10769 parms = chainon (parms,
10770 build_tree_list (NULL_TREE, grokparm (parm, expr)));
10771 }
10772 sel = list;
10773 }
10774 else
10775 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
10776
10777 if (sel == NULL)
10778 {
10779 c_parser_error (parser, "objective-c method declaration is expected");
10780 return error_mark_node;
10781 }
10782
10783 if (attr_err)
10784 return error_mark_node;
10785
10786 return objc_build_method_signature (is_class_method, type, sel, parms, ellipsis);
10787 }
10788
10789 /* Parse an objc-type-name.
10790
10791 objc-type-name:
10792 objc-type-qualifiers[opt] type-name
10793 objc-type-qualifiers[opt]
10794
10795 objc-type-qualifiers:
10796 objc-type-qualifier
10797 objc-type-qualifiers objc-type-qualifier
10798
10799 objc-type-qualifier: one of
10800 in out inout bycopy byref oneway
10801 */
10802
10803 static tree
10804 c_parser_objc_type_name (c_parser *parser)
10805 {
10806 tree quals = NULL_TREE;
10807 struct c_type_name *type_name = NULL;
10808 tree type = NULL_TREE;
10809 while (true)
10810 {
10811 c_token *token = c_parser_peek_token (parser);
10812 if (token->type == CPP_KEYWORD
10813 && (token->keyword == RID_IN
10814 || token->keyword == RID_OUT
10815 || token->keyword == RID_INOUT
10816 || token->keyword == RID_BYCOPY
10817 || token->keyword == RID_BYREF
10818 || token->keyword == RID_ONEWAY))
10819 {
10820 quals = chainon (build_tree_list (NULL_TREE, token->value), quals);
10821 c_parser_consume_token (parser);
10822 }
10823 else
10824 break;
10825 }
10826 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
10827 type_name = c_parser_type_name (parser);
10828 if (type_name)
10829 type = groktypename (type_name, NULL, NULL);
10830
10831 /* If the type is unknown, and error has already been produced and
10832 we need to recover from the error. In that case, use NULL_TREE
10833 for the type, as if no type had been specified; this will use the
10834 default type ('id') which is good for error recovery. */
10835 if (type == error_mark_node)
10836 type = NULL_TREE;
10837
10838 return build_tree_list (quals, type);
10839 }
10840
10841 /* Parse objc-protocol-refs.
10842
10843 objc-protocol-refs:
10844 < identifier-list >
10845 */
10846
10847 static tree
10848 c_parser_objc_protocol_refs (c_parser *parser)
10849 {
10850 tree list = NULL_TREE;
10851 gcc_assert (c_parser_next_token_is (parser, CPP_LESS));
10852 c_parser_consume_token (parser);
10853 /* Any identifiers, including those declared as type names, are OK
10854 here. */
10855 while (true)
10856 {
10857 tree id;
10858 if (c_parser_next_token_is_not (parser, CPP_NAME))
10859 {
10860 c_parser_error (parser, "expected identifier");
10861 break;
10862 }
10863 id = c_parser_peek_token (parser)->value;
10864 list = chainon (list, build_tree_list (NULL_TREE, id));
10865 c_parser_consume_token (parser);
10866 if (c_parser_next_token_is (parser, CPP_COMMA))
10867 c_parser_consume_token (parser);
10868 else
10869 break;
10870 }
10871 c_parser_require (parser, CPP_GREATER, "expected %<>%>");
10872 return list;
10873 }
10874
10875 /* Parse an objc-try-catch-finally-statement.
10876
10877 objc-try-catch-finally-statement:
10878 @try compound-statement objc-catch-list[opt]
10879 @try compound-statement objc-catch-list[opt] @finally compound-statement
10880
10881 objc-catch-list:
10882 @catch ( objc-catch-parameter-declaration ) compound-statement
10883 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
10884
10885 objc-catch-parameter-declaration:
10886 parameter-declaration
10887 '...'
10888
10889 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
10890
10891 PS: This function is identical to cp_parser_objc_try_catch_finally_statement
10892 for C++. Keep them in sync. */
10893
10894 static void
10895 c_parser_objc_try_catch_finally_statement (c_parser *parser)
10896 {
10897 location_t location;
10898 tree stmt;
10899
10900 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_TRY));
10901 c_parser_consume_token (parser);
10902 location = c_parser_peek_token (parser)->location;
10903 objc_maybe_warn_exceptions (location);
10904 stmt = c_parser_compound_statement (parser);
10905 objc_begin_try_stmt (location, stmt);
10906
10907 while (c_parser_next_token_is_keyword (parser, RID_AT_CATCH))
10908 {
10909 struct c_parm *parm;
10910 tree parameter_declaration = error_mark_node;
10911 bool seen_open_paren = false;
10912
10913 c_parser_consume_token (parser);
10914 matching_parens parens;
10915 if (!parens.require_open (parser))
10916 seen_open_paren = true;
10917 if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
10918 {
10919 /* We have "@catch (...)" (where the '...' are literally
10920 what is in the code). Skip the '...'.
10921 parameter_declaration is set to NULL_TREE, and
10922 objc_being_catch_clauses() knows that that means
10923 '...'. */
10924 c_parser_consume_token (parser);
10925 parameter_declaration = NULL_TREE;
10926 }
10927 else
10928 {
10929 /* We have "@catch (NSException *exception)" or something
10930 like that. Parse the parameter declaration. */
10931 parm = c_parser_parameter_declaration (parser, NULL_TREE);
10932 if (parm == NULL)
10933 parameter_declaration = error_mark_node;
10934 else
10935 parameter_declaration = grokparm (parm, NULL);
10936 }
10937 if (seen_open_paren)
10938 parens.require_close (parser);
10939 else
10940 {
10941 /* If there was no open parenthesis, we are recovering from
10942 an error, and we are trying to figure out what mistake
10943 the user has made. */
10944
10945 /* If there is an immediate closing parenthesis, the user
10946 probably forgot the opening one (ie, they typed "@catch
10947 NSException *e)". Parse the closing parenthesis and keep
10948 going. */
10949 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
10950 c_parser_consume_token (parser);
10951
10952 /* If these is no immediate closing parenthesis, the user
10953 probably doesn't know that parenthesis are required at
10954 all (ie, they typed "@catch NSException *e"). So, just
10955 forget about the closing parenthesis and keep going. */
10956 }
10957 objc_begin_catch_clause (parameter_declaration);
10958 if (c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
10959 c_parser_compound_statement_nostart (parser);
10960 objc_finish_catch_clause ();
10961 }
10962 if (c_parser_next_token_is_keyword (parser, RID_AT_FINALLY))
10963 {
10964 c_parser_consume_token (parser);
10965 location = c_parser_peek_token (parser)->location;
10966 stmt = c_parser_compound_statement (parser);
10967 objc_build_finally_clause (location, stmt);
10968 }
10969 objc_finish_try_stmt ();
10970 }
10971
10972 /* Parse an objc-synchronized-statement.
10973
10974 objc-synchronized-statement:
10975 @synchronized ( expression ) compound-statement
10976 */
10977
10978 static void
10979 c_parser_objc_synchronized_statement (c_parser *parser)
10980 {
10981 location_t loc;
10982 tree expr, stmt;
10983 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNCHRONIZED));
10984 c_parser_consume_token (parser);
10985 loc = c_parser_peek_token (parser)->location;
10986 objc_maybe_warn_exceptions (loc);
10987 matching_parens parens;
10988 if (parens.require_open (parser))
10989 {
10990 struct c_expr ce = c_parser_expression (parser);
10991 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
10992 expr = ce.value;
10993 expr = c_fully_fold (expr, false, NULL);
10994 parens.skip_until_found_close (parser);
10995 }
10996 else
10997 expr = error_mark_node;
10998 stmt = c_parser_compound_statement (parser);
10999 objc_build_synchronized (loc, expr, stmt);
11000 }
11001
11002 /* Parse an objc-selector; return NULL_TREE without an error if the
11003 next token is not an objc-selector.
11004
11005 objc-selector:
11006 identifier
11007 one of
11008 enum struct union if else while do for switch case default
11009 break continue return goto asm sizeof typeof __alignof
11010 unsigned long const short volatile signed restrict _Complex
11011 in out inout bycopy byref oneway int char float double void _Bool
11012 _Atomic
11013
11014 ??? Why this selection of keywords but not, for example, storage
11015 class specifiers? */
11016
11017 static tree
11018 c_parser_objc_selector (c_parser *parser)
11019 {
11020 c_token *token = c_parser_peek_token (parser);
11021 tree value = token->value;
11022 if (token->type == CPP_NAME)
11023 {
11024 c_parser_consume_token (parser);
11025 return value;
11026 }
11027 if (token->type != CPP_KEYWORD)
11028 return NULL_TREE;
11029 switch (token->keyword)
11030 {
11031 case RID_ENUM:
11032 case RID_STRUCT:
11033 case RID_UNION:
11034 case RID_IF:
11035 case RID_ELSE:
11036 case RID_WHILE:
11037 case RID_DO:
11038 case RID_FOR:
11039 case RID_SWITCH:
11040 case RID_CASE:
11041 case RID_DEFAULT:
11042 case RID_BREAK:
11043 case RID_CONTINUE:
11044 case RID_RETURN:
11045 case RID_GOTO:
11046 case RID_ASM:
11047 case RID_SIZEOF:
11048 case RID_TYPEOF:
11049 case RID_ALIGNOF:
11050 case RID_UNSIGNED:
11051 case RID_LONG:
11052 case RID_CONST:
11053 case RID_SHORT:
11054 case RID_VOLATILE:
11055 case RID_SIGNED:
11056 case RID_RESTRICT:
11057 case RID_COMPLEX:
11058 case RID_IN:
11059 case RID_OUT:
11060 case RID_INOUT:
11061 case RID_BYCOPY:
11062 case RID_BYREF:
11063 case RID_ONEWAY:
11064 case RID_INT:
11065 case RID_CHAR:
11066 case RID_FLOAT:
11067 case RID_DOUBLE:
11068 CASE_RID_FLOATN_NX:
11069 case RID_VOID:
11070 case RID_BOOL:
11071 case RID_ATOMIC:
11072 case RID_AUTO_TYPE:
11073 case RID_INT_N_0:
11074 case RID_INT_N_1:
11075 case RID_INT_N_2:
11076 case RID_INT_N_3:
11077 c_parser_consume_token (parser);
11078 return value;
11079 default:
11080 return NULL_TREE;
11081 }
11082 }
11083
11084 /* Parse an objc-selector-arg.
11085
11086 objc-selector-arg:
11087 objc-selector
11088 objc-keywordname-list
11089
11090 objc-keywordname-list:
11091 objc-keywordname
11092 objc-keywordname-list objc-keywordname
11093
11094 objc-keywordname:
11095 objc-selector :
11096 :
11097 */
11098
11099 static tree
11100 c_parser_objc_selector_arg (c_parser *parser)
11101 {
11102 tree sel = c_parser_objc_selector (parser);
11103 tree list = NULL_TREE;
11104 if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
11105 return sel;
11106 while (true)
11107 {
11108 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11109 return list;
11110 list = chainon (list, build_tree_list (sel, NULL_TREE));
11111 sel = c_parser_objc_selector (parser);
11112 if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
11113 break;
11114 }
11115 return list;
11116 }
11117
11118 /* Parse an objc-receiver.
11119
11120 objc-receiver:
11121 expression
11122 class-name
11123 type-name
11124 */
11125
11126 static tree
11127 c_parser_objc_receiver (c_parser *parser)
11128 {
11129 location_t loc = c_parser_peek_token (parser)->location;
11130
11131 if (c_parser_peek_token (parser)->type == CPP_NAME
11132 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
11133 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
11134 {
11135 tree id = c_parser_peek_token (parser)->value;
11136 c_parser_consume_token (parser);
11137 return objc_get_class_reference (id);
11138 }
11139 struct c_expr ce = c_parser_expression (parser);
11140 ce = convert_lvalue_to_rvalue (loc, ce, false, false);
11141 return c_fully_fold (ce.value, false, NULL);
11142 }
11143
11144 /* Parse objc-message-args.
11145
11146 objc-message-args:
11147 objc-selector
11148 objc-keywordarg-list
11149
11150 objc-keywordarg-list:
11151 objc-keywordarg
11152 objc-keywordarg-list objc-keywordarg
11153
11154 objc-keywordarg:
11155 objc-selector : objc-keywordexpr
11156 : objc-keywordexpr
11157 */
11158
11159 static tree
11160 c_parser_objc_message_args (c_parser *parser)
11161 {
11162 tree sel = c_parser_objc_selector (parser);
11163 tree list = NULL_TREE;
11164 if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
11165 return sel;
11166 while (true)
11167 {
11168 tree keywordexpr;
11169 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
11170 return error_mark_node;
11171 keywordexpr = c_parser_objc_keywordexpr (parser);
11172 list = chainon (list, build_tree_list (sel, keywordexpr));
11173 sel = c_parser_objc_selector (parser);
11174 if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
11175 break;
11176 }
11177 return list;
11178 }
11179
11180 /* Parse an objc-keywordexpr.
11181
11182 objc-keywordexpr:
11183 nonempty-expr-list
11184 */
11185
11186 static tree
11187 c_parser_objc_keywordexpr (c_parser *parser)
11188 {
11189 tree ret;
11190 vec<tree, va_gc> *expr_list = c_parser_expr_list (parser, true, true,
11191 NULL, NULL, NULL, NULL);
11192 if (vec_safe_length (expr_list) == 1)
11193 {
11194 /* Just return the expression, remove a level of
11195 indirection. */
11196 ret = (*expr_list)[0];
11197 }
11198 else
11199 {
11200 /* We have a comma expression, we will collapse later. */
11201 ret = build_tree_list_vec (expr_list);
11202 }
11203 release_tree_vector (expr_list);
11204 return ret;
11205 }
11206
11207 /* A check, needed in several places, that ObjC interface, implementation or
11208 method definitions are not prefixed by incorrect items. */
11209 static bool
11210 c_parser_objc_diagnose_bad_element_prefix (c_parser *parser,
11211 struct c_declspecs *specs)
11212 {
11213 if (!specs->declspecs_seen_p || specs->non_sc_seen_p
11214 || specs->typespec_kind != ctsk_none)
11215 {
11216 c_parser_error (parser,
11217 "no type or storage class may be specified here,");
11218 c_parser_skip_to_end_of_block_or_statement (parser);
11219 return true;
11220 }
11221 return false;
11222 }
11223
11224 /* Parse an Objective-C @property declaration. The syntax is:
11225
11226 objc-property-declaration:
11227 '@property' objc-property-attributes[opt] struct-declaration ;
11228
11229 objc-property-attributes:
11230 '(' objc-property-attribute-list ')'
11231
11232 objc-property-attribute-list:
11233 objc-property-attribute
11234 objc-property-attribute-list, objc-property-attribute
11235
11236 objc-property-attribute
11237 'getter' = identifier
11238 'setter' = identifier
11239 'readonly'
11240 'readwrite'
11241 'assign'
11242 'retain'
11243 'copy'
11244 'nonatomic'
11245
11246 For example:
11247 @property NSString *name;
11248 @property (readonly) id object;
11249 @property (retain, nonatomic, getter=getTheName) id name;
11250 @property int a, b, c;
11251
11252 PS: This function is identical to cp_parser_objc_at_propery_declaration
11253 for C++. Keep them in sync. */
11254 static void
11255 c_parser_objc_at_property_declaration (c_parser *parser)
11256 {
11257 /* The following variables hold the attributes of the properties as
11258 parsed. They are 'false' or 'NULL_TREE' if the attribute was not
11259 seen. When we see an attribute, we set them to 'true' (if they
11260 are boolean properties) or to the identifier (if they have an
11261 argument, ie, for getter and setter). Note that here we only
11262 parse the list of attributes, check the syntax and accumulate the
11263 attributes that we find. objc_add_property_declaration() will
11264 then process the information. */
11265 bool property_assign = false;
11266 bool property_copy = false;
11267 tree property_getter_ident = NULL_TREE;
11268 bool property_nonatomic = false;
11269 bool property_readonly = false;
11270 bool property_readwrite = false;
11271 bool property_retain = false;
11272 tree property_setter_ident = NULL_TREE;
11273
11274 /* 'properties' is the list of properties that we read. Usually a
11275 single one, but maybe more (eg, in "@property int a, b, c;" there
11276 are three). */
11277 tree properties;
11278 location_t loc;
11279
11280 loc = c_parser_peek_token (parser)->location;
11281 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY));
11282
11283 c_parser_consume_token (parser); /* Eat '@property'. */
11284
11285 /* Parse the optional attribute list... */
11286 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
11287 {
11288 matching_parens parens;
11289
11290 /* Eat the '(' */
11291 parens.consume_open (parser);
11292
11293 /* Property attribute keywords are valid now. */
11294 parser->objc_property_attr_context = true;
11295
11296 while (true)
11297 {
11298 bool syntax_error = false;
11299 c_token *token = c_parser_peek_token (parser);
11300 enum rid keyword;
11301
11302 if (token->type != CPP_KEYWORD)
11303 {
11304 if (token->type == CPP_CLOSE_PAREN)
11305 c_parser_error (parser, "expected identifier");
11306 else
11307 {
11308 c_parser_consume_token (parser);
11309 c_parser_error (parser, "unknown property attribute");
11310 }
11311 break;
11312 }
11313 keyword = token->keyword;
11314 c_parser_consume_token (parser);
11315 switch (keyword)
11316 {
11317 case RID_ASSIGN: property_assign = true; break;
11318 case RID_COPY: property_copy = true; break;
11319 case RID_NONATOMIC: property_nonatomic = true; break;
11320 case RID_READONLY: property_readonly = true; break;
11321 case RID_READWRITE: property_readwrite = true; break;
11322 case RID_RETAIN: property_retain = true; break;
11323
11324 case RID_GETTER:
11325 case RID_SETTER:
11326 if (c_parser_next_token_is_not (parser, CPP_EQ))
11327 {
11328 if (keyword == RID_GETTER)
11329 c_parser_error (parser,
11330 "missing %<=%> (after %<getter%> attribute)");
11331 else
11332 c_parser_error (parser,
11333 "missing %<=%> (after %<setter%> attribute)");
11334 syntax_error = true;
11335 break;
11336 }
11337 c_parser_consume_token (parser); /* eat the = */
11338 if (c_parser_next_token_is_not (parser, CPP_NAME))
11339 {
11340 c_parser_error (parser, "expected identifier");
11341 syntax_error = true;
11342 break;
11343 }
11344 if (keyword == RID_SETTER)
11345 {
11346 if (property_setter_ident != NULL_TREE)
11347 c_parser_error (parser, "the %<setter%> attribute may only be specified once");
11348 else
11349 property_setter_ident = c_parser_peek_token (parser)->value;
11350 c_parser_consume_token (parser);
11351 if (c_parser_next_token_is_not (parser, CPP_COLON))
11352 c_parser_error (parser, "setter name must terminate with %<:%>");
11353 else
11354 c_parser_consume_token (parser);
11355 }
11356 else
11357 {
11358 if (property_getter_ident != NULL_TREE)
11359 c_parser_error (parser, "the %<getter%> attribute may only be specified once");
11360 else
11361 property_getter_ident = c_parser_peek_token (parser)->value;
11362 c_parser_consume_token (parser);
11363 }
11364 break;
11365 default:
11366 c_parser_error (parser, "unknown property attribute");
11367 syntax_error = true;
11368 break;
11369 }
11370
11371 if (syntax_error)
11372 break;
11373
11374 if (c_parser_next_token_is (parser, CPP_COMMA))
11375 c_parser_consume_token (parser);
11376 else
11377 break;
11378 }
11379 parser->objc_property_attr_context = false;
11380 parens.skip_until_found_close (parser);
11381 }
11382 /* ... and the property declaration(s). */
11383 properties = c_parser_struct_declaration (parser);
11384
11385 if (properties == error_mark_node)
11386 {
11387 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11388 parser->error = false;
11389 return;
11390 }
11391
11392 if (properties == NULL_TREE)
11393 c_parser_error (parser, "expected identifier");
11394 else
11395 {
11396 /* Comma-separated properties are chained together in
11397 reverse order; add them one by one. */
11398 properties = nreverse (properties);
11399
11400 for (; properties; properties = TREE_CHAIN (properties))
11401 objc_add_property_declaration (loc, copy_node (properties),
11402 property_readonly, property_readwrite,
11403 property_assign, property_retain,
11404 property_copy, property_nonatomic,
11405 property_getter_ident, property_setter_ident);
11406 }
11407
11408 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11409 parser->error = false;
11410 }
11411
11412 /* Parse an Objective-C @synthesize declaration. The syntax is:
11413
11414 objc-synthesize-declaration:
11415 @synthesize objc-synthesize-identifier-list ;
11416
11417 objc-synthesize-identifier-list:
11418 objc-synthesize-identifier
11419 objc-synthesize-identifier-list, objc-synthesize-identifier
11420
11421 objc-synthesize-identifier
11422 identifier
11423 identifier = identifier
11424
11425 For example:
11426 @synthesize MyProperty;
11427 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
11428
11429 PS: This function is identical to cp_parser_objc_at_synthesize_declaration
11430 for C++. Keep them in sync.
11431 */
11432 static void
11433 c_parser_objc_at_synthesize_declaration (c_parser *parser)
11434 {
11435 tree list = NULL_TREE;
11436 location_t loc;
11437 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNTHESIZE));
11438 loc = c_parser_peek_token (parser)->location;
11439
11440 c_parser_consume_token (parser);
11441 while (true)
11442 {
11443 tree property, ivar;
11444 if (c_parser_next_token_is_not (parser, CPP_NAME))
11445 {
11446 c_parser_error (parser, "expected identifier");
11447 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11448 /* Once we find the semicolon, we can resume normal parsing.
11449 We have to reset parser->error manually because
11450 c_parser_skip_until_found() won't reset it for us if the
11451 next token is precisely a semicolon. */
11452 parser->error = false;
11453 return;
11454 }
11455 property = c_parser_peek_token (parser)->value;
11456 c_parser_consume_token (parser);
11457 if (c_parser_next_token_is (parser, CPP_EQ))
11458 {
11459 c_parser_consume_token (parser);
11460 if (c_parser_next_token_is_not (parser, CPP_NAME))
11461 {
11462 c_parser_error (parser, "expected identifier");
11463 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11464 parser->error = false;
11465 return;
11466 }
11467 ivar = c_parser_peek_token (parser)->value;
11468 c_parser_consume_token (parser);
11469 }
11470 else
11471 ivar = NULL_TREE;
11472 list = chainon (list, build_tree_list (ivar, property));
11473 if (c_parser_next_token_is (parser, CPP_COMMA))
11474 c_parser_consume_token (parser);
11475 else
11476 break;
11477 }
11478 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11479 objc_add_synthesize_declaration (loc, list);
11480 }
11481
11482 /* Parse an Objective-C @dynamic declaration. The syntax is:
11483
11484 objc-dynamic-declaration:
11485 @dynamic identifier-list ;
11486
11487 For example:
11488 @dynamic MyProperty;
11489 @dynamic MyProperty, AnotherProperty;
11490
11491 PS: This function is identical to cp_parser_objc_at_dynamic_declaration
11492 for C++. Keep them in sync.
11493 */
11494 static void
11495 c_parser_objc_at_dynamic_declaration (c_parser *parser)
11496 {
11497 tree list = NULL_TREE;
11498 location_t loc;
11499 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_DYNAMIC));
11500 loc = c_parser_peek_token (parser)->location;
11501
11502 c_parser_consume_token (parser);
11503 while (true)
11504 {
11505 tree property;
11506 if (c_parser_next_token_is_not (parser, CPP_NAME))
11507 {
11508 c_parser_error (parser, "expected identifier");
11509 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
11510 parser->error = false;
11511 return;
11512 }
11513 property = c_parser_peek_token (parser)->value;
11514 list = chainon (list, build_tree_list (NULL_TREE, property));
11515 c_parser_consume_token (parser);
11516 if (c_parser_next_token_is (parser, CPP_COMMA))
11517 c_parser_consume_token (parser);
11518 else
11519 break;
11520 }
11521 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
11522 objc_add_dynamic_declaration (loc, list);
11523 }
11524
11525 \f
11526 /* Parse a pragma GCC ivdep. */
11527
11528 static bool
11529 c_parse_pragma_ivdep (c_parser *parser)
11530 {
11531 c_parser_consume_pragma (parser);
11532 c_parser_skip_to_pragma_eol (parser);
11533 return true;
11534 }
11535
11536 /* Parse a pragma GCC unroll. */
11537
11538 static unsigned short
11539 c_parser_pragma_unroll (c_parser *parser)
11540 {
11541 unsigned short unroll;
11542 c_parser_consume_pragma (parser);
11543 location_t location = c_parser_peek_token (parser)->location;
11544 tree expr = c_parser_expr_no_commas (parser, NULL).value;
11545 mark_exp_read (expr);
11546 expr = c_fully_fold (expr, false, NULL);
11547 HOST_WIDE_INT lunroll = 0;
11548 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
11549 || TREE_CODE (expr) != INTEGER_CST
11550 || (lunroll = tree_to_shwi (expr)) < 0
11551 || lunroll >= USHRT_MAX)
11552 {
11553 error_at (location, "%<#pragma GCC unroll%> requires an"
11554 " assignment-expression that evaluates to a non-negative"
11555 " integral constant less than %u", USHRT_MAX);
11556 unroll = 0;
11557 }
11558 else
11559 {
11560 unroll = (unsigned short)lunroll;
11561 if (unroll == 0)
11562 unroll = 1;
11563 }
11564
11565 c_parser_skip_to_pragma_eol (parser);
11566 return unroll;
11567 }
11568
11569 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
11570 should be considered, statements. ALLOW_STMT is true if we're within
11571 the context of a function and such pragmas are to be allowed. Returns
11572 true if we actually parsed such a pragma. */
11573
11574 static bool
11575 c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p)
11576 {
11577 unsigned int id;
11578 const char *construct = NULL;
11579
11580 id = c_parser_peek_token (parser)->pragma_kind;
11581 gcc_assert (id != PRAGMA_NONE);
11582
11583 switch (id)
11584 {
11585 case PRAGMA_OACC_DECLARE:
11586 c_parser_oacc_declare (parser);
11587 return false;
11588
11589 case PRAGMA_OACC_ENTER_DATA:
11590 if (context != pragma_compound)
11591 {
11592 construct = "acc enter data";
11593 in_compound:
11594 if (context == pragma_stmt)
11595 {
11596 error_at (c_parser_peek_token (parser)->location,
11597 "%<#pragma %s%> may only be used in compound "
11598 "statements", construct);
11599 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
11600 return false;
11601 }
11602 goto bad_stmt;
11603 }
11604 c_parser_oacc_enter_exit_data (parser, true);
11605 return false;
11606
11607 case PRAGMA_OACC_EXIT_DATA:
11608 if (context != pragma_compound)
11609 {
11610 construct = "acc exit data";
11611 goto in_compound;
11612 }
11613 c_parser_oacc_enter_exit_data (parser, false);
11614 return false;
11615
11616 case PRAGMA_OACC_ROUTINE:
11617 if (context != pragma_external)
11618 {
11619 error_at (c_parser_peek_token (parser)->location,
11620 "%<#pragma acc routine%> must be at file scope");
11621 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
11622 return false;
11623 }
11624 c_parser_oacc_routine (parser, context);
11625 return false;
11626
11627 case PRAGMA_OACC_UPDATE:
11628 if (context != pragma_compound)
11629 {
11630 construct = "acc update";
11631 goto in_compound;
11632 }
11633 c_parser_oacc_update (parser);
11634 return false;
11635
11636 case PRAGMA_OMP_BARRIER:
11637 if (context != pragma_compound)
11638 {
11639 construct = "omp barrier";
11640 goto in_compound;
11641 }
11642 c_parser_omp_barrier (parser);
11643 return false;
11644
11645 case PRAGMA_OMP_DEPOBJ:
11646 if (context != pragma_compound)
11647 {
11648 construct = "omp depobj";
11649 goto in_compound;
11650 }
11651 c_parser_omp_depobj (parser);
11652 return false;
11653
11654 case PRAGMA_OMP_FLUSH:
11655 if (context != pragma_compound)
11656 {
11657 construct = "omp flush";
11658 goto in_compound;
11659 }
11660 c_parser_omp_flush (parser);
11661 return false;
11662
11663 case PRAGMA_OMP_TASKWAIT:
11664 if (context != pragma_compound)
11665 {
11666 construct = "omp taskwait";
11667 goto in_compound;
11668 }
11669 c_parser_omp_taskwait (parser);
11670 return false;
11671
11672 case PRAGMA_OMP_TASKYIELD:
11673 if (context != pragma_compound)
11674 {
11675 construct = "omp taskyield";
11676 goto in_compound;
11677 }
11678 c_parser_omp_taskyield (parser);
11679 return false;
11680
11681 case PRAGMA_OMP_CANCEL:
11682 if (context != pragma_compound)
11683 {
11684 construct = "omp cancel";
11685 goto in_compound;
11686 }
11687 c_parser_omp_cancel (parser);
11688 return false;
11689
11690 case PRAGMA_OMP_CANCELLATION_POINT:
11691 c_parser_omp_cancellation_point (parser, context);
11692 return false;
11693
11694 case PRAGMA_OMP_THREADPRIVATE:
11695 c_parser_omp_threadprivate (parser);
11696 return false;
11697
11698 case PRAGMA_OMP_TARGET:
11699 return c_parser_omp_target (parser, context, if_p);
11700
11701 case PRAGMA_OMP_END_DECLARE_TARGET:
11702 c_parser_omp_end_declare_target (parser);
11703 return false;
11704
11705 case PRAGMA_OMP_SCAN:
11706 error_at (c_parser_peek_token (parser)->location,
11707 "%<#pragma omp scan%> may only be used in "
11708 "a loop construct with %<inscan%> %<reduction%> clause");
11709 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
11710 return false;
11711
11712 case PRAGMA_OMP_SECTION:
11713 error_at (c_parser_peek_token (parser)->location,
11714 "%<#pragma omp section%> may only be used in "
11715 "%<#pragma omp sections%> construct");
11716 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
11717 return false;
11718
11719 case PRAGMA_OMP_DECLARE:
11720 c_parser_omp_declare (parser, context);
11721 return false;
11722
11723 case PRAGMA_OMP_REQUIRES:
11724 c_parser_omp_requires (parser);
11725 return false;
11726
11727 case PRAGMA_OMP_ORDERED:
11728 return c_parser_omp_ordered (parser, context, if_p);
11729
11730 case PRAGMA_IVDEP:
11731 {
11732 const bool ivdep = c_parse_pragma_ivdep (parser);
11733 unsigned short unroll;
11734 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_UNROLL)
11735 unroll = c_parser_pragma_unroll (parser);
11736 else
11737 unroll = 0;
11738 if (!c_parser_next_token_is_keyword (parser, RID_FOR)
11739 && !c_parser_next_token_is_keyword (parser, RID_WHILE)
11740 && !c_parser_next_token_is_keyword (parser, RID_DO))
11741 {
11742 c_parser_error (parser, "for, while or do statement expected");
11743 return false;
11744 }
11745 if (c_parser_next_token_is_keyword (parser, RID_FOR))
11746 c_parser_for_statement (parser, ivdep, unroll, if_p);
11747 else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
11748 c_parser_while_statement (parser, ivdep, unroll, if_p);
11749 else
11750 c_parser_do_statement (parser, ivdep, unroll);
11751 }
11752 return false;
11753
11754 case PRAGMA_UNROLL:
11755 {
11756 unsigned short unroll = c_parser_pragma_unroll (parser);
11757 bool ivdep;
11758 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_IVDEP)
11759 ivdep = c_parse_pragma_ivdep (parser);
11760 else
11761 ivdep = false;
11762 if (!c_parser_next_token_is_keyword (parser, RID_FOR)
11763 && !c_parser_next_token_is_keyword (parser, RID_WHILE)
11764 && !c_parser_next_token_is_keyword (parser, RID_DO))
11765 {
11766 c_parser_error (parser, "for, while or do statement expected");
11767 return false;
11768 }
11769 if (c_parser_next_token_is_keyword (parser, RID_FOR))
11770 c_parser_for_statement (parser, ivdep, unroll, if_p);
11771 else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
11772 c_parser_while_statement (parser, ivdep, unroll, if_p);
11773 else
11774 c_parser_do_statement (parser, ivdep, unroll);
11775 }
11776 return false;
11777
11778 case PRAGMA_GCC_PCH_PREPROCESS:
11779 c_parser_error (parser, "%<#pragma GCC pch_preprocess%> must be first");
11780 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
11781 return false;
11782
11783 case PRAGMA_OACC_WAIT:
11784 if (context != pragma_compound)
11785 {
11786 construct = "acc wait";
11787 goto in_compound;
11788 }
11789 /* FALL THROUGH. */
11790
11791 default:
11792 if (id < PRAGMA_FIRST_EXTERNAL)
11793 {
11794 if (context != pragma_stmt && context != pragma_compound)
11795 {
11796 bad_stmt:
11797 c_parser_error (parser, "expected declaration specifiers");
11798 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
11799 return false;
11800 }
11801 c_parser_omp_construct (parser, if_p);
11802 return true;
11803 }
11804 break;
11805 }
11806
11807 c_parser_consume_pragma (parser);
11808 c_invoke_pragma_handler (id);
11809
11810 /* Skip to EOL, but suppress any error message. Those will have been
11811 generated by the handler routine through calling error, as opposed
11812 to calling c_parser_error. */
11813 parser->error = true;
11814 c_parser_skip_to_pragma_eol (parser);
11815
11816 return false;
11817 }
11818
11819 /* The interface the pragma parsers have to the lexer. */
11820
11821 enum cpp_ttype
11822 pragma_lex (tree *value, location_t *loc)
11823 {
11824 c_token *tok = c_parser_peek_token (the_parser);
11825 enum cpp_ttype ret = tok->type;
11826
11827 *value = tok->value;
11828 if (loc)
11829 *loc = tok->location;
11830
11831 if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF)
11832 ret = CPP_EOF;
11833 else if (ret == CPP_STRING)
11834 *value = c_parser_string_literal (the_parser, false, false).value;
11835 else
11836 {
11837 if (ret == CPP_KEYWORD)
11838 ret = CPP_NAME;
11839 c_parser_consume_token (the_parser);
11840 }
11841
11842 return ret;
11843 }
11844
11845 static void
11846 c_parser_pragma_pch_preprocess (c_parser *parser)
11847 {
11848 tree name = NULL;
11849
11850 parser->lex_joined_string = true;
11851 c_parser_consume_pragma (parser);
11852 if (c_parser_next_token_is (parser, CPP_STRING))
11853 {
11854 name = c_parser_peek_token (parser)->value;
11855 c_parser_consume_token (parser);
11856 }
11857 else
11858 c_parser_error (parser, "expected string literal");
11859 c_parser_skip_to_pragma_eol (parser);
11860 parser->lex_joined_string = false;
11861
11862 if (name)
11863 c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name));
11864 }
11865 \f
11866 /* OpenACC and OpenMP parsing routines. */
11867
11868 /* Returns name of the next clause.
11869 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
11870 the token is not consumed. Otherwise appropriate pragma_omp_clause is
11871 returned and the token is consumed. */
11872
11873 static pragma_omp_clause
11874 c_parser_omp_clause_name (c_parser *parser)
11875 {
11876 pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;
11877
11878 if (c_parser_next_token_is_keyword (parser, RID_AUTO))
11879 result = PRAGMA_OACC_CLAUSE_AUTO;
11880 else if (c_parser_next_token_is_keyword (parser, RID_IF))
11881 result = PRAGMA_OMP_CLAUSE_IF;
11882 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
11883 result = PRAGMA_OMP_CLAUSE_DEFAULT;
11884 else if (c_parser_next_token_is_keyword (parser, RID_FOR))
11885 result = PRAGMA_OMP_CLAUSE_FOR;
11886 else if (c_parser_next_token_is (parser, CPP_NAME))
11887 {
11888 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
11889
11890 switch (p[0])
11891 {
11892 case 'a':
11893 if (!strcmp ("aligned", p))
11894 result = PRAGMA_OMP_CLAUSE_ALIGNED;
11895 else if (!strcmp ("async", p))
11896 result = PRAGMA_OACC_CLAUSE_ASYNC;
11897 break;
11898 case 'b':
11899 if (!strcmp ("bind", p))
11900 result = PRAGMA_OMP_CLAUSE_BIND;
11901 break;
11902 case 'c':
11903 if (!strcmp ("collapse", p))
11904 result = PRAGMA_OMP_CLAUSE_COLLAPSE;
11905 else if (!strcmp ("copy", p))
11906 result = PRAGMA_OACC_CLAUSE_COPY;
11907 else if (!strcmp ("copyin", p))
11908 result = PRAGMA_OMP_CLAUSE_COPYIN;
11909 else if (!strcmp ("copyout", p))
11910 result = PRAGMA_OACC_CLAUSE_COPYOUT;
11911 else if (!strcmp ("copyprivate", p))
11912 result = PRAGMA_OMP_CLAUSE_COPYPRIVATE;
11913 else if (!strcmp ("create", p))
11914 result = PRAGMA_OACC_CLAUSE_CREATE;
11915 break;
11916 case 'd':
11917 if (!strcmp ("defaultmap", p))
11918 result = PRAGMA_OMP_CLAUSE_DEFAULTMAP;
11919 else if (!strcmp ("delete", p))
11920 result = PRAGMA_OACC_CLAUSE_DELETE;
11921 else if (!strcmp ("depend", p))
11922 result = PRAGMA_OMP_CLAUSE_DEPEND;
11923 else if (!strcmp ("device", p))
11924 result = PRAGMA_OMP_CLAUSE_DEVICE;
11925 else if (!strcmp ("deviceptr", p))
11926 result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
11927 else if (!strcmp ("device_resident", p))
11928 result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
11929 else if (!strcmp ("device_type", p))
11930 result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
11931 else if (!strcmp ("dist_schedule", p))
11932 result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
11933 break;
11934 case 'f':
11935 if (!strcmp ("final", p))
11936 result = PRAGMA_OMP_CLAUSE_FINAL;
11937 else if (!strcmp ("finalize", p))
11938 result = PRAGMA_OACC_CLAUSE_FINALIZE;
11939 else if (!strcmp ("firstprivate", p))
11940 result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
11941 else if (!strcmp ("from", p))
11942 result = PRAGMA_OMP_CLAUSE_FROM;
11943 break;
11944 case 'g':
11945 if (!strcmp ("gang", p))
11946 result = PRAGMA_OACC_CLAUSE_GANG;
11947 else if (!strcmp ("grainsize", p))
11948 result = PRAGMA_OMP_CLAUSE_GRAINSIZE;
11949 break;
11950 case 'h':
11951 if (!strcmp ("hint", p))
11952 result = PRAGMA_OMP_CLAUSE_HINT;
11953 else if (!strcmp ("host", p))
11954 result = PRAGMA_OACC_CLAUSE_HOST;
11955 break;
11956 case 'i':
11957 if (!strcmp ("if_present", p))
11958 result = PRAGMA_OACC_CLAUSE_IF_PRESENT;
11959 else if (!strcmp ("in_reduction", p))
11960 result = PRAGMA_OMP_CLAUSE_IN_REDUCTION;
11961 else if (!strcmp ("inbranch", p))
11962 result = PRAGMA_OMP_CLAUSE_INBRANCH;
11963 else if (!strcmp ("independent", p))
11964 result = PRAGMA_OACC_CLAUSE_INDEPENDENT;
11965 else if (!strcmp ("is_device_ptr", p))
11966 result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR;
11967 break;
11968 case 'l':
11969 if (!strcmp ("lastprivate", p))
11970 result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
11971 else if (!strcmp ("linear", p))
11972 result = PRAGMA_OMP_CLAUSE_LINEAR;
11973 else if (!strcmp ("link", p))
11974 result = PRAGMA_OMP_CLAUSE_LINK;
11975 break;
11976 case 'm':
11977 if (!strcmp ("map", p))
11978 result = PRAGMA_OMP_CLAUSE_MAP;
11979 else if (!strcmp ("mergeable", p))
11980 result = PRAGMA_OMP_CLAUSE_MERGEABLE;
11981 break;
11982 case 'n':
11983 if (!strcmp ("nogroup", p))
11984 result = PRAGMA_OMP_CLAUSE_NOGROUP;
11985 else if (!strcmp ("nontemporal", p))
11986 result = PRAGMA_OMP_CLAUSE_NONTEMPORAL;
11987 else if (!strcmp ("notinbranch", p))
11988 result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
11989 else if (!strcmp ("nowait", p))
11990 result = PRAGMA_OMP_CLAUSE_NOWAIT;
11991 else if (!strcmp ("num_gangs", p))
11992 result = PRAGMA_OACC_CLAUSE_NUM_GANGS;
11993 else if (!strcmp ("num_tasks", p))
11994 result = PRAGMA_OMP_CLAUSE_NUM_TASKS;
11995 else if (!strcmp ("num_teams", p))
11996 result = PRAGMA_OMP_CLAUSE_NUM_TEAMS;
11997 else if (!strcmp ("num_threads", p))
11998 result = PRAGMA_OMP_CLAUSE_NUM_THREADS;
11999 else if (!strcmp ("num_workers", p))
12000 result = PRAGMA_OACC_CLAUSE_NUM_WORKERS;
12001 break;
12002 case 'o':
12003 if (!strcmp ("ordered", p))
12004 result = PRAGMA_OMP_CLAUSE_ORDERED;
12005 else if (!strcmp ("order", p))
12006 result = PRAGMA_OMP_CLAUSE_ORDER;
12007 break;
12008 case 'p':
12009 if (!strcmp ("parallel", p))
12010 result = PRAGMA_OMP_CLAUSE_PARALLEL;
12011 else if (!strcmp ("present", p))
12012 result = PRAGMA_OACC_CLAUSE_PRESENT;
12013 /* As of OpenACC 2.5, these are now aliases of the non-present_or
12014 clauses. */
12015 else if (!strcmp ("present_or_copy", p)
12016 || !strcmp ("pcopy", p))
12017 result = PRAGMA_OACC_CLAUSE_COPY;
12018 else if (!strcmp ("present_or_copyin", p)
12019 || !strcmp ("pcopyin", p))
12020 result = PRAGMA_OACC_CLAUSE_COPYIN;
12021 else if (!strcmp ("present_or_copyout", p)
12022 || !strcmp ("pcopyout", p))
12023 result = PRAGMA_OACC_CLAUSE_COPYOUT;
12024 else if (!strcmp ("present_or_create", p)
12025 || !strcmp ("pcreate", p))
12026 result = PRAGMA_OACC_CLAUSE_CREATE;
12027 else if (!strcmp ("priority", p))
12028 result = PRAGMA_OMP_CLAUSE_PRIORITY;
12029 else if (!strcmp ("private", p))
12030 result = PRAGMA_OMP_CLAUSE_PRIVATE;
12031 else if (!strcmp ("proc_bind", p))
12032 result = PRAGMA_OMP_CLAUSE_PROC_BIND;
12033 break;
12034 case 'r':
12035 if (!strcmp ("reduction", p))
12036 result = PRAGMA_OMP_CLAUSE_REDUCTION;
12037 break;
12038 case 's':
12039 if (!strcmp ("safelen", p))
12040 result = PRAGMA_OMP_CLAUSE_SAFELEN;
12041 else if (!strcmp ("schedule", p))
12042 result = PRAGMA_OMP_CLAUSE_SCHEDULE;
12043 else if (!strcmp ("sections", p))
12044 result = PRAGMA_OMP_CLAUSE_SECTIONS;
12045 else if (!strcmp ("self", p)) /* "self" is a synonym for "host". */
12046 result = PRAGMA_OACC_CLAUSE_HOST;
12047 else if (!strcmp ("seq", p))
12048 result = PRAGMA_OACC_CLAUSE_SEQ;
12049 else if (!strcmp ("shared", p))
12050 result = PRAGMA_OMP_CLAUSE_SHARED;
12051 else if (!strcmp ("simd", p))
12052 result = PRAGMA_OMP_CLAUSE_SIMD;
12053 else if (!strcmp ("simdlen", p))
12054 result = PRAGMA_OMP_CLAUSE_SIMDLEN;
12055 break;
12056 case 't':
12057 if (!strcmp ("task_reduction", p))
12058 result = PRAGMA_OMP_CLAUSE_TASK_REDUCTION;
12059 else if (!strcmp ("taskgroup", p))
12060 result = PRAGMA_OMP_CLAUSE_TASKGROUP;
12061 else if (!strcmp ("thread_limit", p))
12062 result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT;
12063 else if (!strcmp ("threads", p))
12064 result = PRAGMA_OMP_CLAUSE_THREADS;
12065 else if (!strcmp ("tile", p))
12066 result = PRAGMA_OACC_CLAUSE_TILE;
12067 else if (!strcmp ("to", p))
12068 result = PRAGMA_OMP_CLAUSE_TO;
12069 break;
12070 case 'u':
12071 if (!strcmp ("uniform", p))
12072 result = PRAGMA_OMP_CLAUSE_UNIFORM;
12073 else if (!strcmp ("untied", p))
12074 result = PRAGMA_OMP_CLAUSE_UNTIED;
12075 else if (!strcmp ("use_device", p))
12076 result = PRAGMA_OACC_CLAUSE_USE_DEVICE;
12077 else if (!strcmp ("use_device_addr", p))
12078 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR;
12079 else if (!strcmp ("use_device_ptr", p))
12080 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR;
12081 break;
12082 case 'v':
12083 if (!strcmp ("vector", p))
12084 result = PRAGMA_OACC_CLAUSE_VECTOR;
12085 else if (!strcmp ("vector_length", p))
12086 result = PRAGMA_OACC_CLAUSE_VECTOR_LENGTH;
12087 break;
12088 case 'w':
12089 if (!strcmp ("wait", p))
12090 result = PRAGMA_OACC_CLAUSE_WAIT;
12091 else if (!strcmp ("worker", p))
12092 result = PRAGMA_OACC_CLAUSE_WORKER;
12093 break;
12094 }
12095 }
12096
12097 if (result != PRAGMA_OMP_CLAUSE_NONE)
12098 c_parser_consume_token (parser);
12099
12100 return result;
12101 }
12102
12103 /* Validate that a clause of the given type does not already exist. */
12104
12105 static void
12106 check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
12107 const char *name)
12108 {
12109 if (tree c = omp_find_clause (clauses, code))
12110 error_at (OMP_CLAUSE_LOCATION (c), "too many %qs clauses", name);
12111 }
12112
12113 /* OpenACC 2.0
12114 Parse wait clause or wait directive parameters. */
12115
12116 static tree
12117 c_parser_oacc_wait_list (c_parser *parser, location_t clause_loc, tree list)
12118 {
12119 vec<tree, va_gc> *args;
12120 tree t, args_tree;
12121
12122 matching_parens parens;
12123 if (!parens.require_open (parser))
12124 return list;
12125
12126 args = c_parser_expr_list (parser, false, true, NULL, NULL, NULL, NULL);
12127 args_tree = build_tree_list_vec (args);
12128
12129 for (t = args_tree; t; t = TREE_CHAIN (t))
12130 {
12131 tree targ = TREE_VALUE (t);
12132
12133 if (targ != error_mark_node)
12134 {
12135 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ)))
12136 {
12137 c_parser_error (parser, "expression must be integral");
12138 targ = error_mark_node;
12139 }
12140 else
12141 {
12142 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
12143
12144 OMP_CLAUSE_DECL (c) = targ;
12145 OMP_CLAUSE_CHAIN (c) = list;
12146 list = c;
12147 }
12148 }
12149 }
12150
12151 release_tree_vector (args);
12152 parens.require_close (parser);
12153 return list;
12154 }
12155
12156 /* OpenACC 2.0, OpenMP 2.5:
12157 variable-list:
12158 identifier
12159 variable-list , identifier
12160
12161 If KIND is nonzero, create the appropriate node and install the
12162 decl in OMP_CLAUSE_DECL and add the node to the head of the list.
12163 If KIND is nonzero, CLAUSE_LOC is the location of the clause.
12164
12165 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
12166 return the list created. */
12167
12168 static tree
12169 c_parser_omp_variable_list (c_parser *parser,
12170 location_t clause_loc,
12171 enum omp_clause_code kind, tree list)
12172 {
12173 auto_vec<c_token> tokens;
12174 unsigned int tokens_avail = 0;
12175 bool first = true;
12176
12177 while (1)
12178 {
12179 bool array_section_p = false;
12180 if (kind == OMP_CLAUSE_DEPEND)
12181 {
12182 if (c_parser_next_token_is_not (parser, CPP_NAME)
12183 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
12184 {
12185 struct c_expr expr = c_parser_expr_no_commas (parser, NULL);
12186 if (expr.value != error_mark_node)
12187 {
12188 tree u = build_omp_clause (clause_loc, kind);
12189 OMP_CLAUSE_DECL (u) = expr.value;
12190 OMP_CLAUSE_CHAIN (u) = list;
12191 list = u;
12192 }
12193
12194 if (c_parser_next_token_is_not (parser, CPP_COMMA))
12195 break;
12196
12197 c_parser_consume_token (parser);
12198 first = false;
12199 continue;
12200 }
12201
12202 tokens.truncate (0);
12203 unsigned int nesting_depth = 0;
12204 while (1)
12205 {
12206 c_token *token = c_parser_peek_token (parser);
12207 switch (token->type)
12208 {
12209 case CPP_EOF:
12210 case CPP_PRAGMA_EOL:
12211 break;
12212 case CPP_OPEN_BRACE:
12213 case CPP_OPEN_PAREN:
12214 case CPP_OPEN_SQUARE:
12215 ++nesting_depth;
12216 goto add;
12217 case CPP_CLOSE_BRACE:
12218 case CPP_CLOSE_PAREN:
12219 case CPP_CLOSE_SQUARE:
12220 if (nesting_depth-- == 0)
12221 break;
12222 goto add;
12223 case CPP_COMMA:
12224 if (nesting_depth == 0)
12225 break;
12226 goto add;
12227 default:
12228 add:
12229 tokens.safe_push (*token);
12230 c_parser_consume_token (parser);
12231 continue;
12232 }
12233 break;
12234 }
12235
12236 /* Make sure nothing tries to read past the end of the tokens. */
12237 c_token eof_token;
12238 memset (&eof_token, 0, sizeof (eof_token));
12239 eof_token.type = CPP_EOF;
12240 tokens.safe_push (eof_token);
12241 tokens.safe_push (eof_token);
12242
12243 tokens_avail = parser->tokens_avail;
12244 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
12245 parser->tokens = tokens.address ();
12246 parser->tokens_avail = tokens.length ();
12247 }
12248
12249 tree t = NULL_TREE;
12250
12251 if (c_parser_next_token_is (parser, CPP_NAME)
12252 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
12253 {
12254 t = lookup_name (c_parser_peek_token (parser)->value);
12255
12256 if (t == NULL_TREE)
12257 {
12258 undeclared_variable (c_parser_peek_token (parser)->location,
12259 c_parser_peek_token (parser)->value);
12260 t = error_mark_node;
12261 }
12262
12263 c_parser_consume_token (parser);
12264 }
12265 else if (c_parser_next_token_is (parser, CPP_KEYWORD)
12266 && (c_parser_peek_token (parser)->keyword == RID_FUNCTION_NAME
12267 || (c_parser_peek_token (parser)->keyword
12268 == RID_PRETTY_FUNCTION_NAME)
12269 || (c_parser_peek_token (parser)->keyword
12270 == RID_C99_FUNCTION_NAME)))
12271 t = c_parser_predefined_identifier (parser).value;
12272 else
12273 {
12274 if (first)
12275 c_parser_error (parser, "expected identifier");
12276 break;
12277 }
12278
12279 if (t == error_mark_node)
12280 ;
12281 else if (kind != 0)
12282 {
12283 switch (kind)
12284 {
12285 case OMP_CLAUSE__CACHE_:
12286 /* The OpenACC cache directive explicitly only allows "array
12287 elements or subarrays". */
12288 if (c_parser_peek_token (parser)->type != CPP_OPEN_SQUARE)
12289 {
12290 c_parser_error (parser, "expected %<[%>");
12291 t = error_mark_node;
12292 break;
12293 }
12294 /* FALLTHROUGH */
12295 case OMP_CLAUSE_MAP:
12296 case OMP_CLAUSE_FROM:
12297 case OMP_CLAUSE_TO:
12298 while (c_parser_next_token_is (parser, CPP_DOT))
12299 {
12300 location_t op_loc = c_parser_peek_token (parser)->location;
12301 c_parser_consume_token (parser);
12302 if (!c_parser_next_token_is (parser, CPP_NAME))
12303 {
12304 c_parser_error (parser, "expected identifier");
12305 t = error_mark_node;
12306 break;
12307 }
12308
12309 c_token *comp_tok = c_parser_peek_token (parser);
12310 tree ident = comp_tok->value;
12311 location_t comp_loc = comp_tok->location;
12312 c_parser_consume_token (parser);
12313 t = build_component_ref (op_loc, t, ident, comp_loc);
12314 }
12315 /* FALLTHROUGH */
12316 case OMP_CLAUSE_DEPEND:
12317 case OMP_CLAUSE_REDUCTION:
12318 case OMP_CLAUSE_IN_REDUCTION:
12319 case OMP_CLAUSE_TASK_REDUCTION:
12320 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
12321 {
12322 tree low_bound = NULL_TREE, length = NULL_TREE;
12323
12324 c_parser_consume_token (parser);
12325 if (!c_parser_next_token_is (parser, CPP_COLON))
12326 {
12327 location_t expr_loc
12328 = c_parser_peek_token (parser)->location;
12329 c_expr expr = c_parser_expression (parser);
12330 expr = convert_lvalue_to_rvalue (expr_loc, expr,
12331 false, true);
12332 low_bound = expr.value;
12333 }
12334 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
12335 length = integer_one_node;
12336 else
12337 {
12338 /* Look for `:'. */
12339 if (!c_parser_require (parser, CPP_COLON,
12340 "expected %<:%>"))
12341 {
12342 t = error_mark_node;
12343 break;
12344 }
12345 array_section_p = true;
12346 if (!c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
12347 {
12348 location_t expr_loc
12349 = c_parser_peek_token (parser)->location;
12350 c_expr expr = c_parser_expression (parser);
12351 expr = convert_lvalue_to_rvalue (expr_loc, expr,
12352 false, true);
12353 length = expr.value;
12354 }
12355 }
12356 /* Look for the closing `]'. */
12357 if (!c_parser_require (parser, CPP_CLOSE_SQUARE,
12358 "expected %<]%>"))
12359 {
12360 t = error_mark_node;
12361 break;
12362 }
12363
12364 t = tree_cons (low_bound, length, t);
12365 }
12366 if (kind == OMP_CLAUSE_DEPEND
12367 && t != error_mark_node
12368 && parser->tokens_avail != 2)
12369 {
12370 if (array_section_p)
12371 {
12372 error_at (c_parser_peek_token (parser)->location,
12373 "expected %<)%> or %<,%>");
12374 t = error_mark_node;
12375 }
12376 else
12377 {
12378 parser->tokens = tokens.address ();
12379 parser->tokens_avail = tokens.length ();
12380
12381 t = c_parser_expr_no_commas (parser, NULL).value;
12382 if (t != error_mark_node && parser->tokens_avail != 2)
12383 {
12384 error_at (c_parser_peek_token (parser)->location,
12385 "expected %<)%> or %<,%>");
12386 t = error_mark_node;
12387 }
12388 }
12389 }
12390 break;
12391 default:
12392 break;
12393 }
12394
12395 if (t != error_mark_node)
12396 {
12397 tree u = build_omp_clause (clause_loc, kind);
12398 OMP_CLAUSE_DECL (u) = t;
12399 OMP_CLAUSE_CHAIN (u) = list;
12400 list = u;
12401 }
12402 }
12403 else
12404 list = tree_cons (t, NULL_TREE, list);
12405
12406 if (kind == OMP_CLAUSE_DEPEND)
12407 {
12408 parser->tokens = &parser->tokens_buf[0];
12409 parser->tokens_avail = tokens_avail;
12410 }
12411 if (c_parser_next_token_is_not (parser, CPP_COMMA))
12412 break;
12413
12414 c_parser_consume_token (parser);
12415 first = false;
12416 }
12417
12418 return list;
12419 }
12420
12421 /* Similarly, but expect leading and trailing parenthesis. This is a very
12422 common case for OpenACC and OpenMP clauses. */
12423
12424 static tree
12425 c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind,
12426 tree list)
12427 {
12428 /* The clauses location. */
12429 location_t loc = c_parser_peek_token (parser)->location;
12430
12431 matching_parens parens;
12432 if (parens.require_open (parser))
12433 {
12434 list = c_parser_omp_variable_list (parser, loc, kind, list);
12435 parens.skip_until_found_close (parser);
12436 }
12437 return list;
12438 }
12439
12440 /* OpenACC 2.0:
12441 copy ( variable-list )
12442 copyin ( variable-list )
12443 copyout ( variable-list )
12444 create ( variable-list )
12445 delete ( variable-list )
12446 present ( variable-list ) */
12447
12448 static tree
12449 c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind,
12450 tree list)
12451 {
12452 enum gomp_map_kind kind;
12453 switch (c_kind)
12454 {
12455 case PRAGMA_OACC_CLAUSE_COPY:
12456 kind = GOMP_MAP_TOFROM;
12457 break;
12458 case PRAGMA_OACC_CLAUSE_COPYIN:
12459 kind = GOMP_MAP_TO;
12460 break;
12461 case PRAGMA_OACC_CLAUSE_COPYOUT:
12462 kind = GOMP_MAP_FROM;
12463 break;
12464 case PRAGMA_OACC_CLAUSE_CREATE:
12465 kind = GOMP_MAP_ALLOC;
12466 break;
12467 case PRAGMA_OACC_CLAUSE_DELETE:
12468 kind = GOMP_MAP_RELEASE;
12469 break;
12470 case PRAGMA_OACC_CLAUSE_DEVICE:
12471 kind = GOMP_MAP_FORCE_TO;
12472 break;
12473 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
12474 kind = GOMP_MAP_DEVICE_RESIDENT;
12475 break;
12476 case PRAGMA_OACC_CLAUSE_HOST:
12477 kind = GOMP_MAP_FORCE_FROM;
12478 break;
12479 case PRAGMA_OACC_CLAUSE_LINK:
12480 kind = GOMP_MAP_LINK;
12481 break;
12482 case PRAGMA_OACC_CLAUSE_PRESENT:
12483 kind = GOMP_MAP_FORCE_PRESENT;
12484 break;
12485 default:
12486 gcc_unreachable ();
12487 }
12488 tree nl, c;
12489 nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_MAP, list);
12490
12491 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
12492 OMP_CLAUSE_SET_MAP_KIND (c, kind);
12493
12494 return nl;
12495 }
12496
12497 /* OpenACC 2.0:
12498 deviceptr ( variable-list ) */
12499
12500 static tree
12501 c_parser_oacc_data_clause_deviceptr (c_parser *parser, tree list)
12502 {
12503 location_t loc = c_parser_peek_token (parser)->location;
12504 tree vars, t;
12505
12506 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
12507 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
12508 variable-list must only allow for pointer variables. */
12509 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
12510 for (t = vars; t && t; t = TREE_CHAIN (t))
12511 {
12512 tree v = TREE_PURPOSE (t);
12513
12514 /* FIXME diagnostics: Ideally we should keep individual
12515 locations for all the variables in the var list to make the
12516 following errors more precise. Perhaps
12517 c_parser_omp_var_list_parens() should construct a list of
12518 locations to go along with the var list. */
12519
12520 if (!VAR_P (v) && TREE_CODE (v) != PARM_DECL)
12521 error_at (loc, "%qD is not a variable", v);
12522 else if (TREE_TYPE (v) == error_mark_node)
12523 ;
12524 else if (!POINTER_TYPE_P (TREE_TYPE (v)))
12525 error_at (loc, "%qD is not a pointer variable", v);
12526
12527 tree u = build_omp_clause (loc, OMP_CLAUSE_MAP);
12528 OMP_CLAUSE_SET_MAP_KIND (u, GOMP_MAP_FORCE_DEVICEPTR);
12529 OMP_CLAUSE_DECL (u) = v;
12530 OMP_CLAUSE_CHAIN (u) = list;
12531 list = u;
12532 }
12533
12534 return list;
12535 }
12536
12537 /* OpenACC 2.0, OpenMP 3.0:
12538 collapse ( constant-expression ) */
12539
12540 static tree
12541 c_parser_omp_clause_collapse (c_parser *parser, tree list)
12542 {
12543 tree c, num = error_mark_node;
12544 HOST_WIDE_INT n;
12545 location_t loc;
12546
12547 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
12548 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
12549
12550 loc = c_parser_peek_token (parser)->location;
12551 matching_parens parens;
12552 if (parens.require_open (parser))
12553 {
12554 num = c_parser_expr_no_commas (parser, NULL).value;
12555 parens.skip_until_found_close (parser);
12556 }
12557 if (num == error_mark_node)
12558 return list;
12559 mark_exp_read (num);
12560 num = c_fully_fold (num, false, NULL);
12561 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
12562 || !tree_fits_shwi_p (num)
12563 || (n = tree_to_shwi (num)) <= 0
12564 || (int) n != n)
12565 {
12566 error_at (loc,
12567 "collapse argument needs positive constant integer expression");
12568 return list;
12569 }
12570 c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE);
12571 OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
12572 OMP_CLAUSE_CHAIN (c) = list;
12573 return c;
12574 }
12575
12576 /* OpenMP 2.5:
12577 copyin ( variable-list ) */
12578
12579 static tree
12580 c_parser_omp_clause_copyin (c_parser *parser, tree list)
12581 {
12582 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYIN, list);
12583 }
12584
12585 /* OpenMP 2.5:
12586 copyprivate ( variable-list ) */
12587
12588 static tree
12589 c_parser_omp_clause_copyprivate (c_parser *parser, tree list)
12590 {
12591 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYPRIVATE, list);
12592 }
12593
12594 /* OpenMP 2.5:
12595 default ( none | shared )
12596
12597 OpenACC:
12598 default ( none | present ) */
12599
12600 static tree
12601 c_parser_omp_clause_default (c_parser *parser, tree list, bool is_oacc)
12602 {
12603 enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
12604 location_t loc = c_parser_peek_token (parser)->location;
12605 tree c;
12606
12607 matching_parens parens;
12608 if (!parens.require_open (parser))
12609 return list;
12610 if (c_parser_next_token_is (parser, CPP_NAME))
12611 {
12612 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
12613
12614 switch (p[0])
12615 {
12616 case 'n':
12617 if (strcmp ("none", p) != 0)
12618 goto invalid_kind;
12619 kind = OMP_CLAUSE_DEFAULT_NONE;
12620 break;
12621
12622 case 'p':
12623 if (strcmp ("present", p) != 0 || !is_oacc)
12624 goto invalid_kind;
12625 kind = OMP_CLAUSE_DEFAULT_PRESENT;
12626 break;
12627
12628 case 's':
12629 if (strcmp ("shared", p) != 0 || is_oacc)
12630 goto invalid_kind;
12631 kind = OMP_CLAUSE_DEFAULT_SHARED;
12632 break;
12633
12634 default:
12635 goto invalid_kind;
12636 }
12637
12638 c_parser_consume_token (parser);
12639 }
12640 else
12641 {
12642 invalid_kind:
12643 if (is_oacc)
12644 c_parser_error (parser, "expected %<none%> or %<present%>");
12645 else
12646 c_parser_error (parser, "expected %<none%> or %<shared%>");
12647 }
12648 parens.skip_until_found_close (parser);
12649
12650 if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED)
12651 return list;
12652
12653 check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default");
12654 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULT);
12655 OMP_CLAUSE_CHAIN (c) = list;
12656 OMP_CLAUSE_DEFAULT_KIND (c) = kind;
12657
12658 return c;
12659 }
12660
12661 /* OpenMP 2.5:
12662 firstprivate ( variable-list ) */
12663
12664 static tree
12665 c_parser_omp_clause_firstprivate (c_parser *parser, tree list)
12666 {
12667 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FIRSTPRIVATE, list);
12668 }
12669
12670 /* OpenMP 3.1:
12671 final ( expression ) */
12672
12673 static tree
12674 c_parser_omp_clause_final (c_parser *parser, tree list)
12675 {
12676 location_t loc = c_parser_peek_token (parser)->location;
12677 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
12678 {
12679 matching_parens parens;
12680 tree t, c;
12681 if (!parens.require_open (parser))
12682 t = error_mark_node;
12683 else
12684 {
12685 location_t eloc = c_parser_peek_token (parser)->location;
12686 c_expr expr = c_parser_expr_no_commas (parser, NULL);
12687 t = convert_lvalue_to_rvalue (eloc, expr, true, true).value;
12688 t = c_objc_common_truthvalue_conversion (eloc, t);
12689 t = c_fully_fold (t, false, NULL);
12690 parens.skip_until_found_close (parser);
12691 }
12692
12693 check_no_duplicate_clause (list, OMP_CLAUSE_FINAL, "final");
12694
12695 c = build_omp_clause (loc, OMP_CLAUSE_FINAL);
12696 OMP_CLAUSE_FINAL_EXPR (c) = t;
12697 OMP_CLAUSE_CHAIN (c) = list;
12698 list = c;
12699 }
12700 else
12701 c_parser_error (parser, "expected %<(%>");
12702
12703 return list;
12704 }
12705
12706 /* OpenACC, OpenMP 2.5:
12707 if ( expression )
12708
12709 OpenMP 4.5:
12710 if ( directive-name-modifier : expression )
12711
12712 directive-name-modifier:
12713 parallel | task | taskloop | target data | target | target update
12714 | target enter data | target exit data
12715
12716 OpenMP 5.0:
12717 directive-name-modifier:
12718 ... | simd | cancel */
12719
12720 static tree
12721 c_parser_omp_clause_if (c_parser *parser, tree list, bool is_omp)
12722 {
12723 location_t location = c_parser_peek_token (parser)->location;
12724 enum tree_code if_modifier = ERROR_MARK;
12725
12726 matching_parens parens;
12727 if (!parens.require_open (parser))
12728 return list;
12729
12730 if (is_omp && c_parser_next_token_is (parser, CPP_NAME))
12731 {
12732 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
12733 int n = 2;
12734 if (strcmp (p, "cancel") == 0)
12735 if_modifier = VOID_CST;
12736 else if (strcmp (p, "parallel") == 0)
12737 if_modifier = OMP_PARALLEL;
12738 else if (strcmp (p, "simd") == 0)
12739 if_modifier = OMP_SIMD;
12740 else if (strcmp (p, "task") == 0)
12741 if_modifier = OMP_TASK;
12742 else if (strcmp (p, "taskloop") == 0)
12743 if_modifier = OMP_TASKLOOP;
12744 else if (strcmp (p, "target") == 0)
12745 {
12746 if_modifier = OMP_TARGET;
12747 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
12748 {
12749 p = IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser)->value);
12750 if (strcmp ("data", p) == 0)
12751 if_modifier = OMP_TARGET_DATA;
12752 else if (strcmp ("update", p) == 0)
12753 if_modifier = OMP_TARGET_UPDATE;
12754 else if (strcmp ("enter", p) == 0)
12755 if_modifier = OMP_TARGET_ENTER_DATA;
12756 else if (strcmp ("exit", p) == 0)
12757 if_modifier = OMP_TARGET_EXIT_DATA;
12758 if (if_modifier != OMP_TARGET)
12759 {
12760 n = 3;
12761 c_parser_consume_token (parser);
12762 }
12763 else
12764 {
12765 location_t loc = c_parser_peek_2nd_token (parser)->location;
12766 error_at (loc, "expected %<data%>, %<update%>, %<enter%> "
12767 "or %<exit%>");
12768 if_modifier = ERROR_MARK;
12769 }
12770 if (if_modifier == OMP_TARGET_ENTER_DATA
12771 || if_modifier == OMP_TARGET_EXIT_DATA)
12772 {
12773 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
12774 {
12775 p = IDENTIFIER_POINTER
12776 (c_parser_peek_2nd_token (parser)->value);
12777 if (strcmp ("data", p) == 0)
12778 n = 4;
12779 }
12780 if (n == 4)
12781 c_parser_consume_token (parser);
12782 else
12783 {
12784 location_t loc
12785 = c_parser_peek_2nd_token (parser)->location;
12786 error_at (loc, "expected %<data%>");
12787 if_modifier = ERROR_MARK;
12788 }
12789 }
12790 }
12791 }
12792 if (if_modifier != ERROR_MARK)
12793 {
12794 if (c_parser_peek_2nd_token (parser)->type == CPP_COLON)
12795 {
12796 c_parser_consume_token (parser);
12797 c_parser_consume_token (parser);
12798 }
12799 else
12800 {
12801 if (n > 2)
12802 {
12803 location_t loc = c_parser_peek_2nd_token (parser)->location;
12804 error_at (loc, "expected %<:%>");
12805 }
12806 if_modifier = ERROR_MARK;
12807 }
12808 }
12809 }
12810
12811 location_t loc = c_parser_peek_token (parser)->location;
12812 c_expr expr = c_parser_expr_no_commas (parser, NULL);
12813 expr = convert_lvalue_to_rvalue (loc, expr, true, true);
12814 tree t = c_objc_common_truthvalue_conversion (loc, expr.value), c;
12815 t = c_fully_fold (t, false, NULL);
12816 parens.skip_until_found_close (parser);
12817
12818 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
12819 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF)
12820 {
12821 if (if_modifier != ERROR_MARK
12822 && OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
12823 {
12824 const char *p = NULL;
12825 switch (if_modifier)
12826 {
12827 case VOID_CST: p = "cancel"; break;
12828 case OMP_PARALLEL: p = "parallel"; break;
12829 case OMP_SIMD: p = "simd"; break;
12830 case OMP_TASK: p = "task"; break;
12831 case OMP_TASKLOOP: p = "taskloop"; break;
12832 case OMP_TARGET_DATA: p = "target data"; break;
12833 case OMP_TARGET: p = "target"; break;
12834 case OMP_TARGET_UPDATE: p = "target update"; break;
12835 case OMP_TARGET_ENTER_DATA: p = "target enter data"; break;
12836 case OMP_TARGET_EXIT_DATA: p = "target exit data"; break;
12837 default: gcc_unreachable ();
12838 }
12839 error_at (location, "too many %<if%> clauses with %qs modifier",
12840 p);
12841 return list;
12842 }
12843 else if (OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
12844 {
12845 if (!is_omp)
12846 error_at (location, "too many %<if%> clauses");
12847 else
12848 error_at (location, "too many %<if%> clauses without modifier");
12849 return list;
12850 }
12851 else if (if_modifier == ERROR_MARK
12852 || OMP_CLAUSE_IF_MODIFIER (c) == ERROR_MARK)
12853 {
12854 error_at (location, "if any %<if%> clause has modifier, then all "
12855 "%<if%> clauses have to use modifier");
12856 return list;
12857 }
12858 }
12859
12860 c = build_omp_clause (location, OMP_CLAUSE_IF);
12861 OMP_CLAUSE_IF_MODIFIER (c) = if_modifier;
12862 OMP_CLAUSE_IF_EXPR (c) = t;
12863 OMP_CLAUSE_CHAIN (c) = list;
12864 return c;
12865 }
12866
12867 /* OpenMP 2.5:
12868 lastprivate ( variable-list )
12869
12870 OpenMP 5.0:
12871 lastprivate ( [ lastprivate-modifier : ] variable-list ) */
12872
12873 static tree
12874 c_parser_omp_clause_lastprivate (c_parser *parser, tree list)
12875 {
12876 /* The clauses location. */
12877 location_t loc = c_parser_peek_token (parser)->location;
12878
12879 if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
12880 {
12881 bool conditional = false;
12882 if (c_parser_next_token_is (parser, CPP_NAME)
12883 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
12884 {
12885 const char *p
12886 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
12887 if (strcmp (p, "conditional") == 0)
12888 {
12889 conditional = true;
12890 c_parser_consume_token (parser);
12891 c_parser_consume_token (parser);
12892 }
12893 }
12894 tree nlist = c_parser_omp_variable_list (parser, loc,
12895 OMP_CLAUSE_LASTPRIVATE, list);
12896 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
12897 if (conditional)
12898 for (tree c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
12899 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 1;
12900 return nlist;
12901 }
12902 return list;
12903 }
12904
12905 /* OpenMP 3.1:
12906 mergeable */
12907
12908 static tree
12909 c_parser_omp_clause_mergeable (c_parser *parser ATTRIBUTE_UNUSED, tree list)
12910 {
12911 tree c;
12912
12913 /* FIXME: Should we allow duplicates? */
12914 check_no_duplicate_clause (list, OMP_CLAUSE_MERGEABLE, "mergeable");
12915
12916 c = build_omp_clause (c_parser_peek_token (parser)->location,
12917 OMP_CLAUSE_MERGEABLE);
12918 OMP_CLAUSE_CHAIN (c) = list;
12919
12920 return c;
12921 }
12922
12923 /* OpenMP 2.5:
12924 nowait */
12925
12926 static tree
12927 c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list)
12928 {
12929 tree c;
12930 location_t loc = c_parser_peek_token (parser)->location;
12931
12932 check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait");
12933
12934 c = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
12935 OMP_CLAUSE_CHAIN (c) = list;
12936 return c;
12937 }
12938
12939 /* OpenMP 2.5:
12940 num_threads ( expression ) */
12941
12942 static tree
12943 c_parser_omp_clause_num_threads (c_parser *parser, tree list)
12944 {
12945 location_t num_threads_loc = c_parser_peek_token (parser)->location;
12946 matching_parens parens;
12947 if (parens.require_open (parser))
12948 {
12949 location_t expr_loc = c_parser_peek_token (parser)->location;
12950 c_expr expr = c_parser_expr_no_commas (parser, NULL);
12951 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
12952 tree c, t = expr.value;
12953 t = c_fully_fold (t, false, NULL);
12954
12955 parens.skip_until_found_close (parser);
12956
12957 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
12958 {
12959 c_parser_error (parser, "expected integer expression");
12960 return list;
12961 }
12962
12963 /* Attempt to statically determine when the number isn't positive. */
12964 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
12965 build_int_cst (TREE_TYPE (t), 0));
12966 protected_set_expr_location (c, expr_loc);
12967 if (c == boolean_true_node)
12968 {
12969 warning_at (expr_loc, 0,
12970 "%<num_threads%> value must be positive");
12971 t = integer_one_node;
12972 }
12973
12974 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads");
12975
12976 c = build_omp_clause (num_threads_loc, OMP_CLAUSE_NUM_THREADS);
12977 OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
12978 OMP_CLAUSE_CHAIN (c) = list;
12979 list = c;
12980 }
12981
12982 return list;
12983 }
12984
12985 /* OpenMP 4.5:
12986 num_tasks ( expression ) */
12987
12988 static tree
12989 c_parser_omp_clause_num_tasks (c_parser *parser, tree list)
12990 {
12991 location_t num_tasks_loc = c_parser_peek_token (parser)->location;
12992 matching_parens parens;
12993 if (parens.require_open (parser))
12994 {
12995 location_t expr_loc = c_parser_peek_token (parser)->location;
12996 c_expr expr = c_parser_expr_no_commas (parser, NULL);
12997 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
12998 tree c, t = expr.value;
12999 t = c_fully_fold (t, false, NULL);
13000
13001 parens.skip_until_found_close (parser);
13002
13003 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13004 {
13005 c_parser_error (parser, "expected integer expression");
13006 return list;
13007 }
13008
13009 /* Attempt to statically determine when the number isn't positive. */
13010 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13011 build_int_cst (TREE_TYPE (t), 0));
13012 if (CAN_HAVE_LOCATION_P (c))
13013 SET_EXPR_LOCATION (c, expr_loc);
13014 if (c == boolean_true_node)
13015 {
13016 warning_at (expr_loc, 0, "%<num_tasks%> value must be positive");
13017 t = integer_one_node;
13018 }
13019
13020 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TASKS, "num_tasks");
13021
13022 c = build_omp_clause (num_tasks_loc, OMP_CLAUSE_NUM_TASKS);
13023 OMP_CLAUSE_NUM_TASKS_EXPR (c) = t;
13024 OMP_CLAUSE_CHAIN (c) = list;
13025 list = c;
13026 }
13027
13028 return list;
13029 }
13030
13031 /* OpenMP 4.5:
13032 grainsize ( expression ) */
13033
13034 static tree
13035 c_parser_omp_clause_grainsize (c_parser *parser, tree list)
13036 {
13037 location_t grainsize_loc = c_parser_peek_token (parser)->location;
13038 matching_parens parens;
13039 if (parens.require_open (parser))
13040 {
13041 location_t expr_loc = c_parser_peek_token (parser)->location;
13042 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13043 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13044 tree c, t = expr.value;
13045 t = c_fully_fold (t, false, NULL);
13046
13047 parens.skip_until_found_close (parser);
13048
13049 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13050 {
13051 c_parser_error (parser, "expected integer expression");
13052 return list;
13053 }
13054
13055 /* Attempt to statically determine when the number isn't positive. */
13056 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13057 build_int_cst (TREE_TYPE (t), 0));
13058 if (CAN_HAVE_LOCATION_P (c))
13059 SET_EXPR_LOCATION (c, expr_loc);
13060 if (c == boolean_true_node)
13061 {
13062 warning_at (expr_loc, 0, "%<grainsize%> value must be positive");
13063 t = integer_one_node;
13064 }
13065
13066 check_no_duplicate_clause (list, OMP_CLAUSE_GRAINSIZE, "grainsize");
13067
13068 c = build_omp_clause (grainsize_loc, OMP_CLAUSE_GRAINSIZE);
13069 OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
13070 OMP_CLAUSE_CHAIN (c) = list;
13071 list = c;
13072 }
13073
13074 return list;
13075 }
13076
13077 /* OpenMP 4.5:
13078 priority ( expression ) */
13079
13080 static tree
13081 c_parser_omp_clause_priority (c_parser *parser, tree list)
13082 {
13083 location_t priority_loc = c_parser_peek_token (parser)->location;
13084 matching_parens parens;
13085 if (parens.require_open (parser))
13086 {
13087 location_t expr_loc = c_parser_peek_token (parser)->location;
13088 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13089 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13090 tree c, t = expr.value;
13091 t = c_fully_fold (t, false, NULL);
13092
13093 parens.skip_until_found_close (parser);
13094
13095 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13096 {
13097 c_parser_error (parser, "expected integer expression");
13098 return list;
13099 }
13100
13101 /* Attempt to statically determine when the number isn't
13102 non-negative. */
13103 c = fold_build2_loc (expr_loc, LT_EXPR, boolean_type_node, t,
13104 build_int_cst (TREE_TYPE (t), 0));
13105 if (CAN_HAVE_LOCATION_P (c))
13106 SET_EXPR_LOCATION (c, expr_loc);
13107 if (c == boolean_true_node)
13108 {
13109 warning_at (expr_loc, 0, "%<priority%> value must be non-negative");
13110 t = integer_one_node;
13111 }
13112
13113 check_no_duplicate_clause (list, OMP_CLAUSE_PRIORITY, "priority");
13114
13115 c = build_omp_clause (priority_loc, OMP_CLAUSE_PRIORITY);
13116 OMP_CLAUSE_PRIORITY_EXPR (c) = t;
13117 OMP_CLAUSE_CHAIN (c) = list;
13118 list = c;
13119 }
13120
13121 return list;
13122 }
13123
13124 /* OpenMP 4.5:
13125 hint ( expression ) */
13126
13127 static tree
13128 c_parser_omp_clause_hint (c_parser *parser, tree list)
13129 {
13130 location_t hint_loc = c_parser_peek_token (parser)->location;
13131 matching_parens parens;
13132 if (parens.require_open (parser))
13133 {
13134 location_t expr_loc = c_parser_peek_token (parser)->location;
13135 c_expr expr = c_parser_expr_no_commas (parser, NULL);
13136 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13137 tree c, t = expr.value;
13138 t = c_fully_fold (t, false, NULL);
13139
13140 parens.skip_until_found_close (parser);
13141
13142 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
13143 || TREE_CODE (t) != INTEGER_CST)
13144 {
13145 c_parser_error (parser, "expected constant integer expression");
13146 return list;
13147 }
13148
13149 check_no_duplicate_clause (list, OMP_CLAUSE_HINT, "hint");
13150
13151 c = build_omp_clause (hint_loc, OMP_CLAUSE_HINT);
13152 OMP_CLAUSE_HINT_EXPR (c) = t;
13153 OMP_CLAUSE_CHAIN (c) = list;
13154 list = c;
13155 }
13156
13157 return list;
13158 }
13159
13160 /* OpenMP 4.5:
13161 defaultmap ( tofrom : scalar )
13162
13163 OpenMP 5.0:
13164 defaultmap ( implicit-behavior [ : variable-category ] ) */
13165
13166 static tree
13167 c_parser_omp_clause_defaultmap (c_parser *parser, tree list)
13168 {
13169 location_t loc = c_parser_peek_token (parser)->location;
13170 tree c;
13171 const char *p;
13172 enum omp_clause_defaultmap_kind behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
13173 enum omp_clause_defaultmap_kind category
13174 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
13175
13176 matching_parens parens;
13177 if (!parens.require_open (parser))
13178 return list;
13179 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
13180 p = "default";
13181 else if (!c_parser_next_token_is (parser, CPP_NAME))
13182 {
13183 invalid_behavior:
13184 c_parser_error (parser, "expected %<alloc%>, %<to%>, %<from%>, "
13185 "%<tofrom%>, %<firstprivate%>, %<none%> "
13186 "or %<default%>");
13187 goto out_err;
13188 }
13189 else
13190 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13191
13192 switch (p[0])
13193 {
13194 case 'a':
13195 if (strcmp ("alloc", p) == 0)
13196 behavior = OMP_CLAUSE_DEFAULTMAP_ALLOC;
13197 else
13198 goto invalid_behavior;
13199 break;
13200
13201 case 'd':
13202 if (strcmp ("default", p) == 0)
13203 behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
13204 else
13205 goto invalid_behavior;
13206 break;
13207
13208 case 'f':
13209 if (strcmp ("firstprivate", p) == 0)
13210 behavior = OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
13211 else if (strcmp ("from", p) == 0)
13212 behavior = OMP_CLAUSE_DEFAULTMAP_FROM;
13213 else
13214 goto invalid_behavior;
13215 break;
13216
13217 case 'n':
13218 if (strcmp ("none", p) == 0)
13219 behavior = OMP_CLAUSE_DEFAULTMAP_NONE;
13220 else
13221 goto invalid_behavior;
13222 break;
13223
13224 case 't':
13225 if (strcmp ("tofrom", p) == 0)
13226 behavior = OMP_CLAUSE_DEFAULTMAP_TOFROM;
13227 else if (strcmp ("to", p) == 0)
13228 behavior = OMP_CLAUSE_DEFAULTMAP_TO;
13229 else
13230 goto invalid_behavior;
13231 break;
13232
13233 default:
13234 goto invalid_behavior;
13235 }
13236 c_parser_consume_token (parser);
13237
13238 if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
13239 {
13240 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
13241 goto out_err;
13242 if (!c_parser_next_token_is (parser, CPP_NAME))
13243 {
13244 invalid_category:
13245 c_parser_error (parser, "expected %<scalar%>, %<aggregate%> or "
13246 "%<pointer%>");
13247 goto out_err;
13248 }
13249 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13250 switch (p[0])
13251 {
13252 case 'a':
13253 if (strcmp ("aggregate", p) == 0)
13254 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE;
13255 else
13256 goto invalid_category;
13257 break;
13258
13259 case 'p':
13260 if (strcmp ("pointer", p) == 0)
13261 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER;
13262 else
13263 goto invalid_category;
13264 break;
13265
13266 case 's':
13267 if (strcmp ("scalar", p) == 0)
13268 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR;
13269 else
13270 goto invalid_category;
13271 break;
13272
13273 default:
13274 goto invalid_category;
13275 }
13276
13277 c_parser_consume_token (parser);
13278 }
13279 parens.skip_until_found_close (parser);
13280
13281 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
13282 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEFAULTMAP
13283 && (category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
13284 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c) == category
13285 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
13286 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)))
13287 {
13288 enum omp_clause_defaultmap_kind cat = category;
13289 location_t loc = OMP_CLAUSE_LOCATION (c);
13290 if (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
13291 cat = OMP_CLAUSE_DEFAULTMAP_CATEGORY (c);
13292 p = NULL;
13293 switch (cat)
13294 {
13295 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
13296 p = NULL;
13297 break;
13298 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
13299 p = "aggregate";
13300 break;
13301 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
13302 p = "pointer";
13303 break;
13304 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
13305 p = "scalar";
13306 break;
13307 default:
13308 gcc_unreachable ();
13309 }
13310 if (p)
13311 error_at (loc, "too many %<defaultmap%> clauses with %qs category",
13312 p);
13313 else
13314 error_at (loc, "too many %<defaultmap%> clauses with unspecified "
13315 "category");
13316 break;
13317 }
13318
13319 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULTMAP);
13320 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c, behavior, category);
13321 OMP_CLAUSE_CHAIN (c) = list;
13322 return c;
13323
13324 out_err:
13325 parens.skip_until_found_close (parser);
13326 return list;
13327 }
13328
13329 /* OpenACC 2.0:
13330 use_device ( variable-list )
13331
13332 OpenMP 4.5:
13333 use_device_ptr ( variable-list ) */
13334
13335 static tree
13336 c_parser_omp_clause_use_device_ptr (c_parser *parser, tree list)
13337 {
13338 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_PTR,
13339 list);
13340 }
13341
13342 /* OpenMP 5.0:
13343 use_device_addr ( variable-list ) */
13344
13345 static tree
13346 c_parser_omp_clause_use_device_addr (c_parser *parser, tree list)
13347 {
13348 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_ADDR,
13349 list);
13350 }
13351
13352 /* OpenMP 4.5:
13353 is_device_ptr ( variable-list ) */
13354
13355 static tree
13356 c_parser_omp_clause_is_device_ptr (c_parser *parser, tree list)
13357 {
13358 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_IS_DEVICE_PTR, list);
13359 }
13360
13361 /* OpenACC:
13362 num_gangs ( expression )
13363 num_workers ( expression )
13364 vector_length ( expression ) */
13365
13366 static tree
13367 c_parser_oacc_single_int_clause (c_parser *parser, omp_clause_code code,
13368 tree list)
13369 {
13370 location_t loc = c_parser_peek_token (parser)->location;
13371
13372 matching_parens parens;
13373 if (!parens.require_open (parser))
13374 return list;
13375
13376 location_t expr_loc = c_parser_peek_token (parser)->location;
13377 c_expr expr = c_parser_expression (parser);
13378 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
13379 tree c, t = expr.value;
13380 t = c_fully_fold (t, false, NULL);
13381
13382 parens.skip_until_found_close (parser);
13383
13384 if (t == error_mark_node)
13385 return list;
13386 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13387 {
13388 error_at (expr_loc, "%qs expression must be integral",
13389 omp_clause_code_name[code]);
13390 return list;
13391 }
13392
13393 /* Attempt to statically determine when the number isn't positive. */
13394 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
13395 build_int_cst (TREE_TYPE (t), 0));
13396 protected_set_expr_location (c, expr_loc);
13397 if (c == boolean_true_node)
13398 {
13399 warning_at (expr_loc, 0,
13400 "%qs value must be positive",
13401 omp_clause_code_name[code]);
13402 t = integer_one_node;
13403 }
13404
13405 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
13406
13407 c = build_omp_clause (loc, code);
13408 OMP_CLAUSE_OPERAND (c, 0) = t;
13409 OMP_CLAUSE_CHAIN (c) = list;
13410 return c;
13411 }
13412
13413 /* OpenACC:
13414
13415 gang [( gang-arg-list )]
13416 worker [( [num:] int-expr )]
13417 vector [( [length:] int-expr )]
13418
13419 where gang-arg is one of:
13420
13421 [num:] int-expr
13422 static: size-expr
13423
13424 and size-expr may be:
13425
13426 *
13427 int-expr
13428 */
13429
13430 static tree
13431 c_parser_oacc_shape_clause (c_parser *parser, location_t loc,
13432 omp_clause_code kind,
13433 const char *str, tree list)
13434 {
13435 const char *id = "num";
13436 tree ops[2] = { NULL_TREE, NULL_TREE }, c;
13437
13438 if (kind == OMP_CLAUSE_VECTOR)
13439 id = "length";
13440
13441 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
13442 {
13443 c_parser_consume_token (parser);
13444
13445 do
13446 {
13447 c_token *next = c_parser_peek_token (parser);
13448 int idx = 0;
13449
13450 /* Gang static argument. */
13451 if (kind == OMP_CLAUSE_GANG
13452 && c_parser_next_token_is_keyword (parser, RID_STATIC))
13453 {
13454 c_parser_consume_token (parser);
13455
13456 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
13457 goto cleanup_error;
13458
13459 idx = 1;
13460 if (ops[idx] != NULL_TREE)
13461 {
13462 c_parser_error (parser, "too many %<static%> arguments");
13463 goto cleanup_error;
13464 }
13465
13466 /* Check for the '*' argument. */
13467 if (c_parser_next_token_is (parser, CPP_MULT)
13468 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
13469 || c_parser_peek_2nd_token (parser)->type
13470 == CPP_CLOSE_PAREN))
13471 {
13472 c_parser_consume_token (parser);
13473 ops[idx] = integer_minus_one_node;
13474
13475 if (c_parser_next_token_is (parser, CPP_COMMA))
13476 {
13477 c_parser_consume_token (parser);
13478 continue;
13479 }
13480 else
13481 break;
13482 }
13483 }
13484 /* Worker num: argument and vector length: arguments. */
13485 else if (c_parser_next_token_is (parser, CPP_NAME)
13486 && strcmp (id, IDENTIFIER_POINTER (next->value)) == 0
13487 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
13488 {
13489 c_parser_consume_token (parser); /* id */
13490 c_parser_consume_token (parser); /* ':' */
13491 }
13492
13493 /* Now collect the actual argument. */
13494 if (ops[idx] != NULL_TREE)
13495 {
13496 c_parser_error (parser, "unexpected argument");
13497 goto cleanup_error;
13498 }
13499
13500 location_t expr_loc = c_parser_peek_token (parser)->location;
13501 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
13502 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
13503 tree expr = cexpr.value;
13504 if (expr == error_mark_node)
13505 goto cleanup_error;
13506
13507 expr = c_fully_fold (expr, false, NULL);
13508
13509 /* Attempt to statically determine when the number isn't a
13510 positive integer. */
13511
13512 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr)))
13513 {
13514 c_parser_error (parser, "expected integer expression");
13515 return list;
13516 }
13517
13518 tree c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, expr,
13519 build_int_cst (TREE_TYPE (expr), 0));
13520 if (c == boolean_true_node)
13521 {
13522 warning_at (loc, 0,
13523 "%qs value must be positive", str);
13524 expr = integer_one_node;
13525 }
13526
13527 ops[idx] = expr;
13528
13529 if (kind == OMP_CLAUSE_GANG
13530 && c_parser_next_token_is (parser, CPP_COMMA))
13531 {
13532 c_parser_consume_token (parser);
13533 continue;
13534 }
13535 break;
13536 }
13537 while (1);
13538
13539 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
13540 goto cleanup_error;
13541 }
13542
13543 check_no_duplicate_clause (list, kind, str);
13544
13545 c = build_omp_clause (loc, kind);
13546
13547 if (ops[1])
13548 OMP_CLAUSE_OPERAND (c, 1) = ops[1];
13549
13550 OMP_CLAUSE_OPERAND (c, 0) = ops[0];
13551 OMP_CLAUSE_CHAIN (c) = list;
13552
13553 return c;
13554
13555 cleanup_error:
13556 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
13557 return list;
13558 }
13559
13560 /* OpenACC 2.5:
13561 auto
13562 finalize
13563 independent
13564 nohost
13565 seq */
13566
13567 static tree
13568 c_parser_oacc_simple_clause (location_t loc, enum omp_clause_code code,
13569 tree list)
13570 {
13571 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
13572
13573 tree c = build_omp_clause (loc, code);
13574 OMP_CLAUSE_CHAIN (c) = list;
13575
13576 return c;
13577 }
13578
13579 /* OpenACC:
13580 async [( int-expr )] */
13581
13582 static tree
13583 c_parser_oacc_clause_async (c_parser *parser, tree list)
13584 {
13585 tree c, t;
13586 location_t loc = c_parser_peek_token (parser)->location;
13587
13588 t = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
13589
13590 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
13591 {
13592 c_parser_consume_token (parser);
13593
13594 t = c_parser_expression (parser).value;
13595 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
13596 c_parser_error (parser, "expected integer expression");
13597 else if (t == error_mark_node
13598 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
13599 return list;
13600 }
13601 else
13602 t = c_fully_fold (t, false, NULL);
13603
13604 check_no_duplicate_clause (list, OMP_CLAUSE_ASYNC, "async");
13605
13606 c = build_omp_clause (loc, OMP_CLAUSE_ASYNC);
13607 OMP_CLAUSE_ASYNC_EXPR (c) = t;
13608 OMP_CLAUSE_CHAIN (c) = list;
13609 list = c;
13610
13611 return list;
13612 }
13613
13614 /* OpenACC 2.0:
13615 tile ( size-expr-list ) */
13616
13617 static tree
13618 c_parser_oacc_clause_tile (c_parser *parser, tree list)
13619 {
13620 tree c, expr = error_mark_node;
13621 location_t loc;
13622 tree tile = NULL_TREE;
13623
13624 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
13625 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
13626
13627 loc = c_parser_peek_token (parser)->location;
13628 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
13629 return list;
13630
13631 do
13632 {
13633 if (tile && !c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
13634 return list;
13635
13636 if (c_parser_next_token_is (parser, CPP_MULT)
13637 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
13638 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
13639 {
13640 c_parser_consume_token (parser);
13641 expr = integer_zero_node;
13642 }
13643 else
13644 {
13645 location_t expr_loc = c_parser_peek_token (parser)->location;
13646 c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
13647 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
13648 expr = cexpr.value;
13649
13650 if (expr == error_mark_node)
13651 {
13652 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
13653 "expected %<)%>");
13654 return list;
13655 }
13656
13657 expr = c_fully_fold (expr, false, NULL);
13658
13659 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
13660 || !tree_fits_shwi_p (expr)
13661 || tree_to_shwi (expr) <= 0)
13662 {
13663 error_at (expr_loc, "%<tile%> argument needs positive"
13664 " integral constant");
13665 expr = integer_zero_node;
13666 }
13667 }
13668
13669 tile = tree_cons (NULL_TREE, expr, tile);
13670 }
13671 while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN));
13672
13673 /* Consume the trailing ')'. */
13674 c_parser_consume_token (parser);
13675
13676 c = build_omp_clause (loc, OMP_CLAUSE_TILE);
13677 tile = nreverse (tile);
13678 OMP_CLAUSE_TILE_LIST (c) = tile;
13679 OMP_CLAUSE_CHAIN (c) = list;
13680 return c;
13681 }
13682
13683 /* OpenACC:
13684 wait [( int-expr-list )] */
13685
13686 static tree
13687 c_parser_oacc_clause_wait (c_parser *parser, tree list)
13688 {
13689 location_t clause_loc = c_parser_peek_token (parser)->location;
13690
13691 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
13692 list = c_parser_oacc_wait_list (parser, clause_loc, list);
13693 else
13694 {
13695 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
13696
13697 OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
13698 OMP_CLAUSE_CHAIN (c) = list;
13699 list = c;
13700 }
13701
13702 return list;
13703 }
13704
13705
13706 /* OpenMP 5.0:
13707 order ( concurrent ) */
13708
13709 static tree
13710 c_parser_omp_clause_order (c_parser *parser, tree list)
13711 {
13712 location_t loc = c_parser_peek_token (parser)->location;
13713 tree c;
13714 const char *p;
13715
13716 matching_parens parens;
13717 if (!parens.require_open (parser))
13718 return list;
13719 if (!c_parser_next_token_is (parser, CPP_NAME))
13720 {
13721 c_parser_error (parser, "expected %<concurrent%>");
13722 goto out_err;
13723 }
13724 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13725 if (strcmp (p, "concurrent") != 0)
13726 {
13727 c_parser_error (parser, "expected %<concurrent%>");
13728 goto out_err;
13729 }
13730 c_parser_consume_token (parser);
13731 parens.skip_until_found_close (parser);
13732 /* check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order"); */
13733 c = build_omp_clause (loc, OMP_CLAUSE_ORDER);
13734 OMP_CLAUSE_CHAIN (c) = list;
13735 return c;
13736
13737 out_err:
13738 parens.skip_until_found_close (parser);
13739 return list;
13740 }
13741
13742
13743 /* OpenMP 5.0:
13744 bind ( teams | parallel | thread ) */
13745
13746 static tree
13747 c_parser_omp_clause_bind (c_parser *parser, tree list)
13748 {
13749 location_t loc = c_parser_peek_token (parser)->location;
13750 tree c;
13751 const char *p;
13752 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
13753
13754 matching_parens parens;
13755 if (!parens.require_open (parser))
13756 return list;
13757 if (!c_parser_next_token_is (parser, CPP_NAME))
13758 {
13759 invalid:
13760 c_parser_error (parser,
13761 "expected %<teams%>, %<parallel%> or %<thread%>");
13762 parens.skip_until_found_close (parser);
13763 return list;
13764 }
13765 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13766 if (strcmp (p, "teams") == 0)
13767 kind = OMP_CLAUSE_BIND_TEAMS;
13768 else if (strcmp (p, "parallel") == 0)
13769 kind = OMP_CLAUSE_BIND_PARALLEL;
13770 else if (strcmp (p, "thread") != 0)
13771 goto invalid;
13772 c_parser_consume_token (parser);
13773 parens.skip_until_found_close (parser);
13774 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
13775 c = build_omp_clause (loc, OMP_CLAUSE_BIND);
13776 OMP_CLAUSE_BIND_KIND (c) = kind;
13777 OMP_CLAUSE_CHAIN (c) = list;
13778 return c;
13779 }
13780
13781
13782 /* OpenMP 2.5:
13783 ordered
13784
13785 OpenMP 4.5:
13786 ordered ( constant-expression ) */
13787
13788 static tree
13789 c_parser_omp_clause_ordered (c_parser *parser, tree list)
13790 {
13791 check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered");
13792
13793 tree c, num = NULL_TREE;
13794 HOST_WIDE_INT n;
13795 location_t loc = c_parser_peek_token (parser)->location;
13796 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
13797 {
13798 matching_parens parens;
13799 parens.consume_open (parser);
13800 num = c_parser_expr_no_commas (parser, NULL).value;
13801 parens.skip_until_found_close (parser);
13802 }
13803 if (num == error_mark_node)
13804 return list;
13805 if (num)
13806 {
13807 mark_exp_read (num);
13808 num = c_fully_fold (num, false, NULL);
13809 if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
13810 || !tree_fits_shwi_p (num)
13811 || (n = tree_to_shwi (num)) <= 0
13812 || (int) n != n)
13813 {
13814 error_at (loc, "ordered argument needs positive "
13815 "constant integer expression");
13816 return list;
13817 }
13818 }
13819 c = build_omp_clause (loc, OMP_CLAUSE_ORDERED);
13820 OMP_CLAUSE_ORDERED_EXPR (c) = num;
13821 OMP_CLAUSE_CHAIN (c) = list;
13822 return c;
13823 }
13824
13825 /* OpenMP 2.5:
13826 private ( variable-list ) */
13827
13828 static tree
13829 c_parser_omp_clause_private (c_parser *parser, tree list)
13830 {
13831 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_PRIVATE, list);
13832 }
13833
13834 /* OpenMP 2.5:
13835 reduction ( reduction-operator : variable-list )
13836
13837 reduction-operator:
13838 One of: + * - & ^ | && ||
13839
13840 OpenMP 3.1:
13841
13842 reduction-operator:
13843 One of: + * - & ^ | && || max min
13844
13845 OpenMP 4.0:
13846
13847 reduction-operator:
13848 One of: + * - & ^ | && ||
13849 identifier
13850
13851 OpenMP 5.0:
13852 reduction ( reduction-modifier, reduction-operator : variable-list )
13853 in_reduction ( reduction-operator : variable-list )
13854 task_reduction ( reduction-operator : variable-list ) */
13855
13856 static tree
13857 c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind,
13858 bool is_omp, tree list)
13859 {
13860 location_t clause_loc = c_parser_peek_token (parser)->location;
13861 matching_parens parens;
13862 if (parens.require_open (parser))
13863 {
13864 bool task = false;
13865 bool inscan = false;
13866 enum tree_code code = ERROR_MARK;
13867 tree reduc_id = NULL_TREE;
13868
13869 if (kind == OMP_CLAUSE_REDUCTION && is_omp)
13870 {
13871 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)
13872 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
13873 {
13874 c_parser_consume_token (parser);
13875 c_parser_consume_token (parser);
13876 }
13877 else if (c_parser_next_token_is (parser, CPP_NAME)
13878 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
13879 {
13880 const char *p
13881 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13882 if (strcmp (p, "task") == 0)
13883 task = true;
13884 else if (strcmp (p, "inscan") == 0)
13885 inscan = true;
13886 if (task || inscan)
13887 {
13888 c_parser_consume_token (parser);
13889 c_parser_consume_token (parser);
13890 }
13891 }
13892 }
13893
13894 switch (c_parser_peek_token (parser)->type)
13895 {
13896 case CPP_PLUS:
13897 code = PLUS_EXPR;
13898 break;
13899 case CPP_MULT:
13900 code = MULT_EXPR;
13901 break;
13902 case CPP_MINUS:
13903 code = MINUS_EXPR;
13904 break;
13905 case CPP_AND:
13906 code = BIT_AND_EXPR;
13907 break;
13908 case CPP_XOR:
13909 code = BIT_XOR_EXPR;
13910 break;
13911 case CPP_OR:
13912 code = BIT_IOR_EXPR;
13913 break;
13914 case CPP_AND_AND:
13915 code = TRUTH_ANDIF_EXPR;
13916 break;
13917 case CPP_OR_OR:
13918 code = TRUTH_ORIF_EXPR;
13919 break;
13920 case CPP_NAME:
13921 {
13922 const char *p
13923 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
13924 if (strcmp (p, "min") == 0)
13925 {
13926 code = MIN_EXPR;
13927 break;
13928 }
13929 if (strcmp (p, "max") == 0)
13930 {
13931 code = MAX_EXPR;
13932 break;
13933 }
13934 reduc_id = c_parser_peek_token (parser)->value;
13935 break;
13936 }
13937 default:
13938 c_parser_error (parser,
13939 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
13940 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
13941 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
13942 return list;
13943 }
13944 c_parser_consume_token (parser);
13945 reduc_id = c_omp_reduction_id (code, reduc_id);
13946 if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
13947 {
13948 tree nl, c;
13949
13950 nl = c_parser_omp_variable_list (parser, clause_loc, kind, list);
13951 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
13952 {
13953 tree d = OMP_CLAUSE_DECL (c), type;
13954 if (TREE_CODE (d) != TREE_LIST)
13955 type = TREE_TYPE (d);
13956 else
13957 {
13958 int cnt = 0;
13959 tree t;
13960 for (t = d; TREE_CODE (t) == TREE_LIST; t = TREE_CHAIN (t))
13961 cnt++;
13962 type = TREE_TYPE (t);
13963 while (cnt > 0)
13964 {
13965 if (TREE_CODE (type) != POINTER_TYPE
13966 && TREE_CODE (type) != ARRAY_TYPE)
13967 break;
13968 type = TREE_TYPE (type);
13969 cnt--;
13970 }
13971 }
13972 while (TREE_CODE (type) == ARRAY_TYPE)
13973 type = TREE_TYPE (type);
13974 OMP_CLAUSE_REDUCTION_CODE (c) = code;
13975 if (task)
13976 OMP_CLAUSE_REDUCTION_TASK (c) = 1;
13977 else if (inscan)
13978 OMP_CLAUSE_REDUCTION_INSCAN (c) = 1;
13979 if (code == ERROR_MARK
13980 || !(INTEGRAL_TYPE_P (type)
13981 || TREE_CODE (type) == REAL_TYPE
13982 || TREE_CODE (type) == COMPLEX_TYPE))
13983 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
13984 = c_omp_reduction_lookup (reduc_id,
13985 TYPE_MAIN_VARIANT (type));
13986 }
13987
13988 list = nl;
13989 }
13990 parens.skip_until_found_close (parser);
13991 }
13992 return list;
13993 }
13994
13995 /* OpenMP 2.5:
13996 schedule ( schedule-kind )
13997 schedule ( schedule-kind , expression )
13998
13999 schedule-kind:
14000 static | dynamic | guided | runtime | auto
14001
14002 OpenMP 4.5:
14003 schedule ( schedule-modifier : schedule-kind )
14004 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
14005
14006 schedule-modifier:
14007 simd
14008 monotonic
14009 nonmonotonic */
14010
14011 static tree
14012 c_parser_omp_clause_schedule (c_parser *parser, tree list)
14013 {
14014 tree c, t;
14015 location_t loc = c_parser_peek_token (parser)->location;
14016 int modifiers = 0, nmodifiers = 0;
14017
14018 matching_parens parens;
14019 if (!parens.require_open (parser))
14020 return list;
14021
14022 c = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE);
14023
14024 while (c_parser_next_token_is (parser, CPP_NAME))
14025 {
14026 tree kind = c_parser_peek_token (parser)->value;
14027 const char *p = IDENTIFIER_POINTER (kind);
14028 if (strcmp ("simd", p) == 0)
14029 OMP_CLAUSE_SCHEDULE_SIMD (c) = 1;
14030 else if (strcmp ("monotonic", p) == 0)
14031 modifiers |= OMP_CLAUSE_SCHEDULE_MONOTONIC;
14032 else if (strcmp ("nonmonotonic", p) == 0)
14033 modifiers |= OMP_CLAUSE_SCHEDULE_NONMONOTONIC;
14034 else
14035 break;
14036 c_parser_consume_token (parser);
14037 if (nmodifiers++ == 0
14038 && c_parser_next_token_is (parser, CPP_COMMA))
14039 c_parser_consume_token (parser);
14040 else
14041 {
14042 c_parser_require (parser, CPP_COLON, "expected %<:%>");
14043 break;
14044 }
14045 }
14046
14047 if ((modifiers & (OMP_CLAUSE_SCHEDULE_MONOTONIC
14048 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
14049 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
14050 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
14051 {
14052 error_at (loc, "both %<monotonic%> and %<nonmonotonic%> modifiers "
14053 "specified");
14054 modifiers = 0;
14055 }
14056
14057 if (c_parser_next_token_is (parser, CPP_NAME))
14058 {
14059 tree kind = c_parser_peek_token (parser)->value;
14060 const char *p = IDENTIFIER_POINTER (kind);
14061
14062 switch (p[0])
14063 {
14064 case 'd':
14065 if (strcmp ("dynamic", p) != 0)
14066 goto invalid_kind;
14067 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
14068 break;
14069
14070 case 'g':
14071 if (strcmp ("guided", p) != 0)
14072 goto invalid_kind;
14073 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
14074 break;
14075
14076 case 'r':
14077 if (strcmp ("runtime", p) != 0)
14078 goto invalid_kind;
14079 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
14080 break;
14081
14082 default:
14083 goto invalid_kind;
14084 }
14085 }
14086 else if (c_parser_next_token_is_keyword (parser, RID_STATIC))
14087 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
14088 else if (c_parser_next_token_is_keyword (parser, RID_AUTO))
14089 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
14090 else
14091 goto invalid_kind;
14092
14093 c_parser_consume_token (parser);
14094 if (c_parser_next_token_is (parser, CPP_COMMA))
14095 {
14096 location_t here;
14097 c_parser_consume_token (parser);
14098
14099 here = c_parser_peek_token (parser)->location;
14100 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14101 expr = convert_lvalue_to_rvalue (here, expr, false, true);
14102 t = expr.value;
14103 t = c_fully_fold (t, false, NULL);
14104
14105 if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
14106 error_at (here, "schedule %<runtime%> does not take "
14107 "a %<chunk_size%> parameter");
14108 else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO)
14109 error_at (here,
14110 "schedule %<auto%> does not take "
14111 "a %<chunk_size%> parameter");
14112 else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE)
14113 {
14114 /* Attempt to statically determine when the number isn't
14115 positive. */
14116 tree s = fold_build2_loc (loc, LE_EXPR, boolean_type_node, t,
14117 build_int_cst (TREE_TYPE (t), 0));
14118 protected_set_expr_location (s, loc);
14119 if (s == boolean_true_node)
14120 {
14121 warning_at (loc, 0,
14122 "chunk size value must be positive");
14123 t = integer_one_node;
14124 }
14125 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
14126 }
14127 else
14128 c_parser_error (parser, "expected integer expression");
14129
14130 parens.skip_until_found_close (parser);
14131 }
14132 else
14133 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
14134 "expected %<,%> or %<)%>");
14135
14136 OMP_CLAUSE_SCHEDULE_KIND (c)
14137 = (enum omp_clause_schedule_kind)
14138 (OMP_CLAUSE_SCHEDULE_KIND (c) | modifiers);
14139
14140 check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule");
14141 OMP_CLAUSE_CHAIN (c) = list;
14142 return c;
14143
14144 invalid_kind:
14145 c_parser_error (parser, "invalid schedule kind");
14146 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
14147 return list;
14148 }
14149
14150 /* OpenMP 2.5:
14151 shared ( variable-list ) */
14152
14153 static tree
14154 c_parser_omp_clause_shared (c_parser *parser, tree list)
14155 {
14156 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_SHARED, list);
14157 }
14158
14159 /* OpenMP 3.0:
14160 untied */
14161
14162 static tree
14163 c_parser_omp_clause_untied (c_parser *parser ATTRIBUTE_UNUSED, tree list)
14164 {
14165 tree c;
14166
14167 /* FIXME: Should we allow duplicates? */
14168 check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied");
14169
14170 c = build_omp_clause (c_parser_peek_token (parser)->location,
14171 OMP_CLAUSE_UNTIED);
14172 OMP_CLAUSE_CHAIN (c) = list;
14173
14174 return c;
14175 }
14176
14177 /* OpenMP 4.0:
14178 inbranch
14179 notinbranch */
14180
14181 static tree
14182 c_parser_omp_clause_branch (c_parser *parser ATTRIBUTE_UNUSED,
14183 enum omp_clause_code code, tree list)
14184 {
14185 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14186
14187 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
14188 OMP_CLAUSE_CHAIN (c) = list;
14189
14190 return c;
14191 }
14192
14193 /* OpenMP 4.0:
14194 parallel
14195 for
14196 sections
14197 taskgroup */
14198
14199 static tree
14200 c_parser_omp_clause_cancelkind (c_parser *parser ATTRIBUTE_UNUSED,
14201 enum omp_clause_code code, tree list)
14202 {
14203 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
14204 OMP_CLAUSE_CHAIN (c) = list;
14205
14206 return c;
14207 }
14208
14209 /* OpenMP 4.5:
14210 nogroup */
14211
14212 static tree
14213 c_parser_omp_clause_nogroup (c_parser *parser ATTRIBUTE_UNUSED, tree list)
14214 {
14215 check_no_duplicate_clause (list, OMP_CLAUSE_NOGROUP, "nogroup");
14216 tree c = build_omp_clause (c_parser_peek_token (parser)->location,
14217 OMP_CLAUSE_NOGROUP);
14218 OMP_CLAUSE_CHAIN (c) = list;
14219 return c;
14220 }
14221
14222 /* OpenMP 4.5:
14223 simd
14224 threads */
14225
14226 static tree
14227 c_parser_omp_clause_orderedkind (c_parser *parser ATTRIBUTE_UNUSED,
14228 enum omp_clause_code code, tree list)
14229 {
14230 check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
14231 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
14232 OMP_CLAUSE_CHAIN (c) = list;
14233 return c;
14234 }
14235
14236 /* OpenMP 4.0:
14237 num_teams ( expression ) */
14238
14239 static tree
14240 c_parser_omp_clause_num_teams (c_parser *parser, tree list)
14241 {
14242 location_t num_teams_loc = c_parser_peek_token (parser)->location;
14243 matching_parens parens;
14244 if (parens.require_open (parser))
14245 {
14246 location_t expr_loc = c_parser_peek_token (parser)->location;
14247 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14248 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14249 tree c, t = expr.value;
14250 t = c_fully_fold (t, false, NULL);
14251
14252 parens.skip_until_found_close (parser);
14253
14254 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14255 {
14256 c_parser_error (parser, "expected integer expression");
14257 return list;
14258 }
14259
14260 /* Attempt to statically determine when the number isn't positive. */
14261 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14262 build_int_cst (TREE_TYPE (t), 0));
14263 protected_set_expr_location (c, expr_loc);
14264 if (c == boolean_true_node)
14265 {
14266 warning_at (expr_loc, 0, "%<num_teams%> value must be positive");
14267 t = integer_one_node;
14268 }
14269
14270 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TEAMS, "num_teams");
14271
14272 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
14273 OMP_CLAUSE_NUM_TEAMS_EXPR (c) = t;
14274 OMP_CLAUSE_CHAIN (c) = list;
14275 list = c;
14276 }
14277
14278 return list;
14279 }
14280
14281 /* OpenMP 4.0:
14282 thread_limit ( expression ) */
14283
14284 static tree
14285 c_parser_omp_clause_thread_limit (c_parser *parser, tree list)
14286 {
14287 location_t num_thread_limit_loc = c_parser_peek_token (parser)->location;
14288 matching_parens parens;
14289 if (parens.require_open (parser))
14290 {
14291 location_t expr_loc = c_parser_peek_token (parser)->location;
14292 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14293 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14294 tree c, t = expr.value;
14295 t = c_fully_fold (t, false, NULL);
14296
14297 parens.skip_until_found_close (parser);
14298
14299 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14300 {
14301 c_parser_error (parser, "expected integer expression");
14302 return list;
14303 }
14304
14305 /* Attempt to statically determine when the number isn't positive. */
14306 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
14307 build_int_cst (TREE_TYPE (t), 0));
14308 protected_set_expr_location (c, expr_loc);
14309 if (c == boolean_true_node)
14310 {
14311 warning_at (expr_loc, 0, "%<thread_limit%> value must be positive");
14312 t = integer_one_node;
14313 }
14314
14315 check_no_duplicate_clause (list, OMP_CLAUSE_THREAD_LIMIT,
14316 "thread_limit");
14317
14318 c = build_omp_clause (num_thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
14319 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
14320 OMP_CLAUSE_CHAIN (c) = list;
14321 list = c;
14322 }
14323
14324 return list;
14325 }
14326
14327 /* OpenMP 4.0:
14328 aligned ( variable-list )
14329 aligned ( variable-list : constant-expression ) */
14330
14331 static tree
14332 c_parser_omp_clause_aligned (c_parser *parser, tree list)
14333 {
14334 location_t clause_loc = c_parser_peek_token (parser)->location;
14335 tree nl, c;
14336
14337 matching_parens parens;
14338 if (!parens.require_open (parser))
14339 return list;
14340
14341 nl = c_parser_omp_variable_list (parser, clause_loc,
14342 OMP_CLAUSE_ALIGNED, list);
14343
14344 if (c_parser_next_token_is (parser, CPP_COLON))
14345 {
14346 c_parser_consume_token (parser);
14347 location_t expr_loc = c_parser_peek_token (parser)->location;
14348 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14349 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14350 tree alignment = expr.value;
14351 alignment = c_fully_fold (alignment, false, NULL);
14352 if (TREE_CODE (alignment) != INTEGER_CST
14353 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment))
14354 || tree_int_cst_sgn (alignment) != 1)
14355 {
14356 error_at (clause_loc, "%<aligned%> clause alignment expression must "
14357 "be positive constant integer expression");
14358 alignment = NULL_TREE;
14359 }
14360
14361 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
14362 OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = alignment;
14363 }
14364
14365 parens.skip_until_found_close (parser);
14366 return nl;
14367 }
14368
14369 /* OpenMP 4.0:
14370 linear ( variable-list )
14371 linear ( variable-list : expression )
14372
14373 OpenMP 4.5:
14374 linear ( modifier ( variable-list ) )
14375 linear ( modifier ( variable-list ) : expression ) */
14376
14377 static tree
14378 c_parser_omp_clause_linear (c_parser *parser, tree list)
14379 {
14380 location_t clause_loc = c_parser_peek_token (parser)->location;
14381 tree nl, c, step;
14382 enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
14383
14384 matching_parens parens;
14385 if (!parens.require_open (parser))
14386 return list;
14387
14388 if (c_parser_next_token_is (parser, CPP_NAME))
14389 {
14390 c_token *tok = c_parser_peek_token (parser);
14391 const char *p = IDENTIFIER_POINTER (tok->value);
14392 if (strcmp ("val", p) == 0)
14393 kind = OMP_CLAUSE_LINEAR_VAL;
14394 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN)
14395 kind = OMP_CLAUSE_LINEAR_DEFAULT;
14396 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
14397 {
14398 c_parser_consume_token (parser);
14399 c_parser_consume_token (parser);
14400 }
14401 }
14402
14403 nl = c_parser_omp_variable_list (parser, clause_loc,
14404 OMP_CLAUSE_LINEAR, list);
14405
14406 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
14407 parens.skip_until_found_close (parser);
14408
14409 if (c_parser_next_token_is (parser, CPP_COLON))
14410 {
14411 c_parser_consume_token (parser);
14412 location_t expr_loc = c_parser_peek_token (parser)->location;
14413 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14414 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14415 step = expr.value;
14416 step = c_fully_fold (step, false, NULL);
14417 if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
14418 {
14419 error_at (clause_loc, "%<linear%> clause step expression must "
14420 "be integral");
14421 step = integer_one_node;
14422 }
14423
14424 }
14425 else
14426 step = integer_one_node;
14427
14428 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
14429 {
14430 OMP_CLAUSE_LINEAR_STEP (c) = step;
14431 OMP_CLAUSE_LINEAR_KIND (c) = kind;
14432 }
14433
14434 parens.skip_until_found_close (parser);
14435 return nl;
14436 }
14437
14438 /* OpenMP 5.0:
14439 nontemporal ( variable-list ) */
14440
14441 static tree
14442 c_parser_omp_clause_nontemporal (c_parser *parser, tree list)
14443 {
14444 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_NONTEMPORAL, list);
14445 }
14446
14447 /* OpenMP 4.0:
14448 safelen ( constant-expression ) */
14449
14450 static tree
14451 c_parser_omp_clause_safelen (c_parser *parser, tree list)
14452 {
14453 location_t clause_loc = c_parser_peek_token (parser)->location;
14454 tree c, t;
14455
14456 matching_parens parens;
14457 if (!parens.require_open (parser))
14458 return list;
14459
14460 location_t expr_loc = c_parser_peek_token (parser)->location;
14461 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14462 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14463 t = expr.value;
14464 t = c_fully_fold (t, false, NULL);
14465 if (TREE_CODE (t) != INTEGER_CST
14466 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
14467 || tree_int_cst_sgn (t) != 1)
14468 {
14469 error_at (clause_loc, "%<safelen%> clause expression must "
14470 "be positive constant integer expression");
14471 t = NULL_TREE;
14472 }
14473
14474 parens.skip_until_found_close (parser);
14475 if (t == NULL_TREE || t == error_mark_node)
14476 return list;
14477
14478 check_no_duplicate_clause (list, OMP_CLAUSE_SAFELEN, "safelen");
14479
14480 c = build_omp_clause (clause_loc, OMP_CLAUSE_SAFELEN);
14481 OMP_CLAUSE_SAFELEN_EXPR (c) = t;
14482 OMP_CLAUSE_CHAIN (c) = list;
14483 return c;
14484 }
14485
14486 /* OpenMP 4.0:
14487 simdlen ( constant-expression ) */
14488
14489 static tree
14490 c_parser_omp_clause_simdlen (c_parser *parser, tree list)
14491 {
14492 location_t clause_loc = c_parser_peek_token (parser)->location;
14493 tree c, t;
14494
14495 matching_parens parens;
14496 if (!parens.require_open (parser))
14497 return list;
14498
14499 location_t expr_loc = c_parser_peek_token (parser)->location;
14500 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14501 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14502 t = expr.value;
14503 t = c_fully_fold (t, false, NULL);
14504 if (TREE_CODE (t) != INTEGER_CST
14505 || !INTEGRAL_TYPE_P (TREE_TYPE (t))
14506 || tree_int_cst_sgn (t) != 1)
14507 {
14508 error_at (clause_loc, "%<simdlen%> clause expression must "
14509 "be positive constant integer expression");
14510 t = NULL_TREE;
14511 }
14512
14513 parens.skip_until_found_close (parser);
14514 if (t == NULL_TREE || t == error_mark_node)
14515 return list;
14516
14517 check_no_duplicate_clause (list, OMP_CLAUSE_SIMDLEN, "simdlen");
14518
14519 c = build_omp_clause (clause_loc, OMP_CLAUSE_SIMDLEN);
14520 OMP_CLAUSE_SIMDLEN_EXPR (c) = t;
14521 OMP_CLAUSE_CHAIN (c) = list;
14522 return c;
14523 }
14524
14525 /* OpenMP 4.5:
14526 vec:
14527 identifier [+/- integer]
14528 vec , identifier [+/- integer]
14529 */
14530
14531 static tree
14532 c_parser_omp_clause_depend_sink (c_parser *parser, location_t clause_loc,
14533 tree list)
14534 {
14535 tree vec = NULL;
14536 if (c_parser_next_token_is_not (parser, CPP_NAME)
14537 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
14538 {
14539 c_parser_error (parser, "expected identifier");
14540 return list;
14541 }
14542
14543 while (c_parser_next_token_is (parser, CPP_NAME)
14544 && c_parser_peek_token (parser)->id_kind == C_ID_ID)
14545 {
14546 tree t = lookup_name (c_parser_peek_token (parser)->value);
14547 tree addend = NULL;
14548
14549 if (t == NULL_TREE)
14550 {
14551 undeclared_variable (c_parser_peek_token (parser)->location,
14552 c_parser_peek_token (parser)->value);
14553 t = error_mark_node;
14554 }
14555
14556 c_parser_consume_token (parser);
14557
14558 bool neg = false;
14559 if (c_parser_next_token_is (parser, CPP_MINUS))
14560 neg = true;
14561 else if (!c_parser_next_token_is (parser, CPP_PLUS))
14562 {
14563 addend = integer_zero_node;
14564 neg = false;
14565 goto add_to_vector;
14566 }
14567 c_parser_consume_token (parser);
14568
14569 if (c_parser_next_token_is_not (parser, CPP_NUMBER))
14570 {
14571 c_parser_error (parser, "expected integer");
14572 return list;
14573 }
14574
14575 addend = c_parser_peek_token (parser)->value;
14576 if (TREE_CODE (addend) != INTEGER_CST)
14577 {
14578 c_parser_error (parser, "expected integer");
14579 return list;
14580 }
14581 c_parser_consume_token (parser);
14582
14583 add_to_vector:
14584 if (t != error_mark_node)
14585 {
14586 vec = tree_cons (addend, t, vec);
14587 if (neg)
14588 OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec) = 1;
14589 }
14590
14591 if (c_parser_next_token_is_not (parser, CPP_COMMA))
14592 break;
14593
14594 c_parser_consume_token (parser);
14595 }
14596
14597 if (vec == NULL_TREE)
14598 return list;
14599
14600 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
14601 OMP_CLAUSE_DEPEND_KIND (u) = OMP_CLAUSE_DEPEND_SINK;
14602 OMP_CLAUSE_DECL (u) = nreverse (vec);
14603 OMP_CLAUSE_CHAIN (u) = list;
14604 return u;
14605 }
14606
14607 /* OpenMP 5.0:
14608 iterators ( iterators-definition )
14609
14610 iterators-definition:
14611 iterator-specifier
14612 iterator-specifier , iterators-definition
14613
14614 iterator-specifier:
14615 identifier = range-specification
14616 iterator-type identifier = range-specification
14617
14618 range-specification:
14619 begin : end
14620 begin : end : step */
14621
14622 static tree
14623 c_parser_omp_iterators (c_parser *parser)
14624 {
14625 tree ret = NULL_TREE, *last = &ret;
14626 c_parser_consume_token (parser);
14627
14628 push_scope ();
14629
14630 matching_parens parens;
14631 if (!parens.require_open (parser))
14632 return error_mark_node;
14633
14634 do
14635 {
14636 tree iter_type = NULL_TREE, type_expr = NULL_TREE;
14637 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
14638 {
14639 struct c_type_name *type = c_parser_type_name (parser);
14640 if (type != NULL)
14641 iter_type = groktypename (type, &type_expr, NULL);
14642 }
14643 if (iter_type == NULL_TREE)
14644 iter_type = integer_type_node;
14645
14646 location_t loc = c_parser_peek_token (parser)->location;
14647 if (!c_parser_next_token_is (parser, CPP_NAME))
14648 {
14649 c_parser_error (parser, "expected identifier");
14650 break;
14651 }
14652
14653 tree id = c_parser_peek_token (parser)->value;
14654 c_parser_consume_token (parser);
14655
14656 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
14657 break;
14658
14659 location_t eloc = c_parser_peek_token (parser)->location;
14660 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14661 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
14662 tree begin = expr.value;
14663
14664 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14665 break;
14666
14667 eloc = c_parser_peek_token (parser)->location;
14668 expr = c_parser_expr_no_commas (parser, NULL);
14669 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
14670 tree end = expr.value;
14671
14672 tree step = integer_one_node;
14673 if (c_parser_next_token_is (parser, CPP_COLON))
14674 {
14675 c_parser_consume_token (parser);
14676 eloc = c_parser_peek_token (parser)->location;
14677 expr = c_parser_expr_no_commas (parser, NULL);
14678 expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
14679 step = expr.value;
14680 }
14681
14682 tree iter_var = build_decl (loc, VAR_DECL, id, iter_type);
14683 DECL_ARTIFICIAL (iter_var) = 1;
14684 DECL_CONTEXT (iter_var) = current_function_decl;
14685 pushdecl (iter_var);
14686
14687 *last = make_tree_vec (6);
14688 TREE_VEC_ELT (*last, 0) = iter_var;
14689 TREE_VEC_ELT (*last, 1) = begin;
14690 TREE_VEC_ELT (*last, 2) = end;
14691 TREE_VEC_ELT (*last, 3) = step;
14692 last = &TREE_CHAIN (*last);
14693
14694 if (c_parser_next_token_is (parser, CPP_COMMA))
14695 {
14696 c_parser_consume_token (parser);
14697 continue;
14698 }
14699 break;
14700 }
14701 while (1);
14702
14703 parens.skip_until_found_close (parser);
14704 return ret ? ret : error_mark_node;
14705 }
14706
14707 /* OpenMP 4.0:
14708 depend ( depend-kind: variable-list )
14709
14710 depend-kind:
14711 in | out | inout
14712
14713 OpenMP 4.5:
14714 depend ( source )
14715
14716 depend ( sink : vec )
14717
14718 OpenMP 5.0:
14719 depend ( depend-modifier , depend-kind: variable-list )
14720
14721 depend-kind:
14722 in | out | inout | mutexinoutset | depobj
14723
14724 depend-modifier:
14725 iterator ( iterators-definition ) */
14726
14727 static tree
14728 c_parser_omp_clause_depend (c_parser *parser, tree list)
14729 {
14730 location_t clause_loc = c_parser_peek_token (parser)->location;
14731 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_LAST;
14732 tree nl, c, iterators = NULL_TREE;
14733
14734 matching_parens parens;
14735 if (!parens.require_open (parser))
14736 return list;
14737
14738 do
14739 {
14740 if (c_parser_next_token_is_not (parser, CPP_NAME))
14741 goto invalid_kind;
14742
14743 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14744 if (strcmp ("iterator", p) == 0 && iterators == NULL_TREE)
14745 {
14746 iterators = c_parser_omp_iterators (parser);
14747 c_parser_require (parser, CPP_COMMA, "expected %<,%>");
14748 continue;
14749 }
14750 if (strcmp ("in", p) == 0)
14751 kind = OMP_CLAUSE_DEPEND_IN;
14752 else if (strcmp ("inout", p) == 0)
14753 kind = OMP_CLAUSE_DEPEND_INOUT;
14754 else if (strcmp ("mutexinoutset", p) == 0)
14755 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
14756 else if (strcmp ("out", p) == 0)
14757 kind = OMP_CLAUSE_DEPEND_OUT;
14758 else if (strcmp ("depobj", p) == 0)
14759 kind = OMP_CLAUSE_DEPEND_DEPOBJ;
14760 else if (strcmp ("sink", p) == 0)
14761 kind = OMP_CLAUSE_DEPEND_SINK;
14762 else if (strcmp ("source", p) == 0)
14763 kind = OMP_CLAUSE_DEPEND_SOURCE;
14764 else
14765 goto invalid_kind;
14766 break;
14767 }
14768 while (1);
14769
14770 c_parser_consume_token (parser);
14771
14772 if (iterators
14773 && (kind == OMP_CLAUSE_DEPEND_SOURCE || kind == OMP_CLAUSE_DEPEND_SINK))
14774 {
14775 pop_scope ();
14776 error_at (clause_loc, "%<iterator%> modifier incompatible with %qs",
14777 kind == OMP_CLAUSE_DEPEND_SOURCE ? "source" : "sink");
14778 iterators = NULL_TREE;
14779 }
14780
14781 if (kind == OMP_CLAUSE_DEPEND_SOURCE)
14782 {
14783 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
14784 OMP_CLAUSE_DEPEND_KIND (c) = kind;
14785 OMP_CLAUSE_DECL (c) = NULL_TREE;
14786 OMP_CLAUSE_CHAIN (c) = list;
14787 parens.skip_until_found_close (parser);
14788 return c;
14789 }
14790
14791 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
14792 goto resync_fail;
14793
14794 if (kind == OMP_CLAUSE_DEPEND_SINK)
14795 nl = c_parser_omp_clause_depend_sink (parser, clause_loc, list);
14796 else
14797 {
14798 nl = c_parser_omp_variable_list (parser, clause_loc,
14799 OMP_CLAUSE_DEPEND, list);
14800
14801 if (iterators)
14802 {
14803 tree block = pop_scope ();
14804 if (iterators == error_mark_node)
14805 iterators = NULL_TREE;
14806 else
14807 TREE_VEC_ELT (iterators, 5) = block;
14808 }
14809
14810 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
14811 {
14812 OMP_CLAUSE_DEPEND_KIND (c) = kind;
14813 if (iterators)
14814 OMP_CLAUSE_DECL (c)
14815 = build_tree_list (iterators, OMP_CLAUSE_DECL (c));
14816 }
14817 }
14818
14819 parens.skip_until_found_close (parser);
14820 return nl;
14821
14822 invalid_kind:
14823 c_parser_error (parser, "invalid depend kind");
14824 resync_fail:
14825 parens.skip_until_found_close (parser);
14826 if (iterators)
14827 pop_scope ();
14828 return list;
14829 }
14830
14831 /* OpenMP 4.0:
14832 map ( map-kind: variable-list )
14833 map ( variable-list )
14834
14835 map-kind:
14836 alloc | to | from | tofrom
14837
14838 OpenMP 4.5:
14839 map-kind:
14840 alloc | to | from | tofrom | release | delete
14841
14842 map ( always [,] map-kind: variable-list ) */
14843
14844 static tree
14845 c_parser_omp_clause_map (c_parser *parser, tree list)
14846 {
14847 location_t clause_loc = c_parser_peek_token (parser)->location;
14848 enum gomp_map_kind kind = GOMP_MAP_TOFROM;
14849 int always = 0;
14850 enum c_id_kind always_id_kind = C_ID_NONE;
14851 location_t always_loc = UNKNOWN_LOCATION;
14852 tree always_id = NULL_TREE;
14853 tree nl, c;
14854
14855 matching_parens parens;
14856 if (!parens.require_open (parser))
14857 return list;
14858
14859 if (c_parser_next_token_is (parser, CPP_NAME))
14860 {
14861 c_token *tok = c_parser_peek_token (parser);
14862 const char *p = IDENTIFIER_POINTER (tok->value);
14863 always_id_kind = tok->id_kind;
14864 always_loc = tok->location;
14865 always_id = tok->value;
14866 if (strcmp ("always", p) == 0)
14867 {
14868 c_token *sectok = c_parser_peek_2nd_token (parser);
14869 if (sectok->type == CPP_COMMA)
14870 {
14871 c_parser_consume_token (parser);
14872 c_parser_consume_token (parser);
14873 always = 2;
14874 }
14875 else if (sectok->type == CPP_NAME)
14876 {
14877 p = IDENTIFIER_POINTER (sectok->value);
14878 if (strcmp ("alloc", p) == 0
14879 || strcmp ("to", p) == 0
14880 || strcmp ("from", p) == 0
14881 || strcmp ("tofrom", p) == 0
14882 || strcmp ("release", p) == 0
14883 || strcmp ("delete", p) == 0)
14884 {
14885 c_parser_consume_token (parser);
14886 always = 1;
14887 }
14888 }
14889 }
14890 }
14891
14892 if (c_parser_next_token_is (parser, CPP_NAME)
14893 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
14894 {
14895 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
14896 if (strcmp ("alloc", p) == 0)
14897 kind = GOMP_MAP_ALLOC;
14898 else if (strcmp ("to", p) == 0)
14899 kind = always ? GOMP_MAP_ALWAYS_TO : GOMP_MAP_TO;
14900 else if (strcmp ("from", p) == 0)
14901 kind = always ? GOMP_MAP_ALWAYS_FROM : GOMP_MAP_FROM;
14902 else if (strcmp ("tofrom", p) == 0)
14903 kind = always ? GOMP_MAP_ALWAYS_TOFROM : GOMP_MAP_TOFROM;
14904 else if (strcmp ("release", p) == 0)
14905 kind = GOMP_MAP_RELEASE;
14906 else if (strcmp ("delete", p) == 0)
14907 kind = GOMP_MAP_DELETE;
14908 else
14909 {
14910 c_parser_error (parser, "invalid map kind");
14911 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
14912 "expected %<)%>");
14913 return list;
14914 }
14915 c_parser_consume_token (parser);
14916 c_parser_consume_token (parser);
14917 }
14918 else if (always)
14919 {
14920 if (always_id_kind != C_ID_ID)
14921 {
14922 c_parser_error (parser, "expected identifier");
14923 parens.skip_until_found_close (parser);
14924 return list;
14925 }
14926
14927 tree t = lookup_name (always_id);
14928 if (t == NULL_TREE)
14929 {
14930 undeclared_variable (always_loc, always_id);
14931 t = error_mark_node;
14932 }
14933 if (t != error_mark_node)
14934 {
14935 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_MAP);
14936 OMP_CLAUSE_DECL (u) = t;
14937 OMP_CLAUSE_CHAIN (u) = list;
14938 OMP_CLAUSE_SET_MAP_KIND (u, kind);
14939 list = u;
14940 }
14941 if (always == 1)
14942 {
14943 parens.skip_until_found_close (parser);
14944 return list;
14945 }
14946 }
14947
14948 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_MAP, list);
14949
14950 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
14951 OMP_CLAUSE_SET_MAP_KIND (c, kind);
14952
14953 parens.skip_until_found_close (parser);
14954 return nl;
14955 }
14956
14957 /* OpenMP 4.0:
14958 device ( expression ) */
14959
14960 static tree
14961 c_parser_omp_clause_device (c_parser *parser, tree list)
14962 {
14963 location_t clause_loc = c_parser_peek_token (parser)->location;
14964 matching_parens parens;
14965 if (parens.require_open (parser))
14966 {
14967 location_t expr_loc = c_parser_peek_token (parser)->location;
14968 c_expr expr = c_parser_expr_no_commas (parser, NULL);
14969 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
14970 tree c, t = expr.value;
14971 t = c_fully_fold (t, false, NULL);
14972
14973 parens.skip_until_found_close (parser);
14974
14975 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
14976 {
14977 c_parser_error (parser, "expected integer expression");
14978 return list;
14979 }
14980
14981 check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE, "device");
14982
14983 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE);
14984 OMP_CLAUSE_DEVICE_ID (c) = t;
14985 OMP_CLAUSE_CHAIN (c) = list;
14986 list = c;
14987 }
14988
14989 return list;
14990 }
14991
14992 /* OpenMP 4.0:
14993 dist_schedule ( static )
14994 dist_schedule ( static , expression ) */
14995
14996 static tree
14997 c_parser_omp_clause_dist_schedule (c_parser *parser, tree list)
14998 {
14999 tree c, t = NULL_TREE;
15000 location_t loc = c_parser_peek_token (parser)->location;
15001
15002 matching_parens parens;
15003 if (!parens.require_open (parser))
15004 return list;
15005
15006 if (!c_parser_next_token_is_keyword (parser, RID_STATIC))
15007 {
15008 c_parser_error (parser, "invalid dist_schedule kind");
15009 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
15010 "expected %<)%>");
15011 return list;
15012 }
15013
15014 c_parser_consume_token (parser);
15015 if (c_parser_next_token_is (parser, CPP_COMMA))
15016 {
15017 c_parser_consume_token (parser);
15018
15019 location_t expr_loc = c_parser_peek_token (parser)->location;
15020 c_expr expr = c_parser_expr_no_commas (parser, NULL);
15021 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
15022 t = expr.value;
15023 t = c_fully_fold (t, false, NULL);
15024 parens.skip_until_found_close (parser);
15025 }
15026 else
15027 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
15028 "expected %<,%> or %<)%>");
15029
15030 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
15031 "dist_schedule"); */
15032 if (omp_find_clause (list, OMP_CLAUSE_DIST_SCHEDULE))
15033 warning_at (loc, 0, "too many %qs clauses", "dist_schedule");
15034 if (t == error_mark_node)
15035 return list;
15036
15037 c = build_omp_clause (loc, OMP_CLAUSE_DIST_SCHEDULE);
15038 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t;
15039 OMP_CLAUSE_CHAIN (c) = list;
15040 return c;
15041 }
15042
15043 /* OpenMP 4.0:
15044 proc_bind ( proc-bind-kind )
15045
15046 proc-bind-kind:
15047 master | close | spread */
15048
15049 static tree
15050 c_parser_omp_clause_proc_bind (c_parser *parser, tree list)
15051 {
15052 location_t clause_loc = c_parser_peek_token (parser)->location;
15053 enum omp_clause_proc_bind_kind kind;
15054 tree c;
15055
15056 matching_parens parens;
15057 if (!parens.require_open (parser))
15058 return list;
15059
15060 if (c_parser_next_token_is (parser, CPP_NAME))
15061 {
15062 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15063 if (strcmp ("master", p) == 0)
15064 kind = OMP_CLAUSE_PROC_BIND_MASTER;
15065 else if (strcmp ("close", p) == 0)
15066 kind = OMP_CLAUSE_PROC_BIND_CLOSE;
15067 else if (strcmp ("spread", p) == 0)
15068 kind = OMP_CLAUSE_PROC_BIND_SPREAD;
15069 else
15070 goto invalid_kind;
15071 }
15072 else
15073 goto invalid_kind;
15074
15075 check_no_duplicate_clause (list, OMP_CLAUSE_PROC_BIND, "proc_bind");
15076 c_parser_consume_token (parser);
15077 parens.skip_until_found_close (parser);
15078 c = build_omp_clause (clause_loc, OMP_CLAUSE_PROC_BIND);
15079 OMP_CLAUSE_PROC_BIND_KIND (c) = kind;
15080 OMP_CLAUSE_CHAIN (c) = list;
15081 return c;
15082
15083 invalid_kind:
15084 c_parser_error (parser, "invalid proc_bind kind");
15085 parens.skip_until_found_close (parser);
15086 return list;
15087 }
15088
15089 /* OpenMP 5.0:
15090 device_type ( host | nohost | any ) */
15091
15092 static tree
15093 c_parser_omp_clause_device_type (c_parser *parser, tree list)
15094 {
15095 location_t clause_loc = c_parser_peek_token (parser)->location;
15096 enum omp_clause_device_type_kind kind;
15097 tree c;
15098
15099 matching_parens parens;
15100 if (!parens.require_open (parser))
15101 return list;
15102
15103 if (c_parser_next_token_is (parser, CPP_NAME))
15104 {
15105 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15106 if (strcmp ("host", p) == 0)
15107 kind = OMP_CLAUSE_DEVICE_TYPE_HOST;
15108 else if (strcmp ("nohost", p) == 0)
15109 kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
15110 else if (strcmp ("any", p) == 0)
15111 kind = OMP_CLAUSE_DEVICE_TYPE_ANY;
15112 else
15113 goto invalid_kind;
15114 }
15115 else
15116 goto invalid_kind;
15117
15118 /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE,
15119 "device_type"); */
15120 c_parser_consume_token (parser);
15121 parens.skip_until_found_close (parser);
15122 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE_TYPE);
15123 OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind;
15124 OMP_CLAUSE_CHAIN (c) = list;
15125 return c;
15126
15127 invalid_kind:
15128 c_parser_error (parser, "expected %<host%>, %<nohost%> or %<any%>");
15129 parens.skip_until_found_close (parser);
15130 return list;
15131 }
15132
15133 /* OpenMP 4.0:
15134 to ( variable-list ) */
15135
15136 static tree
15137 c_parser_omp_clause_to (c_parser *parser, tree list)
15138 {
15139 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO, list);
15140 }
15141
15142 /* OpenMP 4.0:
15143 from ( variable-list ) */
15144
15145 static tree
15146 c_parser_omp_clause_from (c_parser *parser, tree list)
15147 {
15148 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FROM, list);
15149 }
15150
15151 /* OpenMP 4.0:
15152 uniform ( variable-list ) */
15153
15154 static tree
15155 c_parser_omp_clause_uniform (c_parser *parser, tree list)
15156 {
15157 /* The clauses location. */
15158 location_t loc = c_parser_peek_token (parser)->location;
15159
15160 matching_parens parens;
15161 if (parens.require_open (parser))
15162 {
15163 list = c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_UNIFORM,
15164 list);
15165 parens.skip_until_found_close (parser);
15166 }
15167 return list;
15168 }
15169
15170 /* Parse all OpenACC clauses. The set clauses allowed by the directive
15171 is a bitmask in MASK. Return the list of clauses found. */
15172
15173 static tree
15174 c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask,
15175 const char *where, bool finish_p = true)
15176 {
15177 tree clauses = NULL;
15178 bool first = true;
15179
15180 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
15181 {
15182 location_t here;
15183 pragma_omp_clause c_kind;
15184 const char *c_name;
15185 tree prev = clauses;
15186
15187 if (!first && c_parser_next_token_is (parser, CPP_COMMA))
15188 c_parser_consume_token (parser);
15189
15190 here = c_parser_peek_token (parser)->location;
15191 c_kind = c_parser_omp_clause_name (parser);
15192
15193 switch (c_kind)
15194 {
15195 case PRAGMA_OACC_CLAUSE_ASYNC:
15196 clauses = c_parser_oacc_clause_async (parser, clauses);
15197 c_name = "async";
15198 break;
15199 case PRAGMA_OACC_CLAUSE_AUTO:
15200 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_AUTO,
15201 clauses);
15202 c_name = "auto";
15203 break;
15204 case PRAGMA_OACC_CLAUSE_COLLAPSE:
15205 clauses = c_parser_omp_clause_collapse (parser, clauses);
15206 c_name = "collapse";
15207 break;
15208 case PRAGMA_OACC_CLAUSE_COPY:
15209 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15210 c_name = "copy";
15211 break;
15212 case PRAGMA_OACC_CLAUSE_COPYIN:
15213 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15214 c_name = "copyin";
15215 break;
15216 case PRAGMA_OACC_CLAUSE_COPYOUT:
15217 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15218 c_name = "copyout";
15219 break;
15220 case PRAGMA_OACC_CLAUSE_CREATE:
15221 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15222 c_name = "create";
15223 break;
15224 case PRAGMA_OACC_CLAUSE_DELETE:
15225 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15226 c_name = "delete";
15227 break;
15228 case PRAGMA_OMP_CLAUSE_DEFAULT:
15229 clauses = c_parser_omp_clause_default (parser, clauses, true);
15230 c_name = "default";
15231 break;
15232 case PRAGMA_OACC_CLAUSE_DEVICE:
15233 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15234 c_name = "device";
15235 break;
15236 case PRAGMA_OACC_CLAUSE_DEVICEPTR:
15237 clauses = c_parser_oacc_data_clause_deviceptr (parser, clauses);
15238 c_name = "deviceptr";
15239 break;
15240 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
15241 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15242 c_name = "device_resident";
15243 break;
15244 case PRAGMA_OACC_CLAUSE_FINALIZE:
15245 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_FINALIZE,
15246 clauses);
15247 c_name = "finalize";
15248 break;
15249 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE:
15250 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
15251 c_name = "firstprivate";
15252 break;
15253 case PRAGMA_OACC_CLAUSE_GANG:
15254 c_name = "gang";
15255 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_GANG,
15256 c_name, clauses);
15257 break;
15258 case PRAGMA_OACC_CLAUSE_HOST:
15259 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15260 c_name = "host";
15261 break;
15262 case PRAGMA_OACC_CLAUSE_IF:
15263 clauses = c_parser_omp_clause_if (parser, clauses, false);
15264 c_name = "if";
15265 break;
15266 case PRAGMA_OACC_CLAUSE_IF_PRESENT:
15267 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_IF_PRESENT,
15268 clauses);
15269 c_name = "if_present";
15270 break;
15271 case PRAGMA_OACC_CLAUSE_INDEPENDENT:
15272 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_INDEPENDENT,
15273 clauses);
15274 c_name = "independent";
15275 break;
15276 case PRAGMA_OACC_CLAUSE_LINK:
15277 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15278 c_name = "link";
15279 break;
15280 case PRAGMA_OACC_CLAUSE_NUM_GANGS:
15281 clauses = c_parser_oacc_single_int_clause (parser,
15282 OMP_CLAUSE_NUM_GANGS,
15283 clauses);
15284 c_name = "num_gangs";
15285 break;
15286 case PRAGMA_OACC_CLAUSE_NUM_WORKERS:
15287 clauses = c_parser_oacc_single_int_clause (parser,
15288 OMP_CLAUSE_NUM_WORKERS,
15289 clauses);
15290 c_name = "num_workers";
15291 break;
15292 case PRAGMA_OACC_CLAUSE_PRESENT:
15293 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
15294 c_name = "present";
15295 break;
15296 case PRAGMA_OACC_CLAUSE_PRIVATE:
15297 clauses = c_parser_omp_clause_private (parser, clauses);
15298 c_name = "private";
15299 break;
15300 case PRAGMA_OACC_CLAUSE_REDUCTION:
15301 clauses
15302 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
15303 false, clauses);
15304 c_name = "reduction";
15305 break;
15306 case PRAGMA_OACC_CLAUSE_SEQ:
15307 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_SEQ,
15308 clauses);
15309 c_name = "seq";
15310 break;
15311 case PRAGMA_OACC_CLAUSE_TILE:
15312 clauses = c_parser_oacc_clause_tile (parser, clauses);
15313 c_name = "tile";
15314 break;
15315 case PRAGMA_OACC_CLAUSE_USE_DEVICE:
15316 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
15317 c_name = "use_device";
15318 break;
15319 case PRAGMA_OACC_CLAUSE_VECTOR:
15320 c_name = "vector";
15321 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_VECTOR,
15322 c_name, clauses);
15323 break;
15324 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH:
15325 clauses = c_parser_oacc_single_int_clause (parser,
15326 OMP_CLAUSE_VECTOR_LENGTH,
15327 clauses);
15328 c_name = "vector_length";
15329 break;
15330 case PRAGMA_OACC_CLAUSE_WAIT:
15331 clauses = c_parser_oacc_clause_wait (parser, clauses);
15332 c_name = "wait";
15333 break;
15334 case PRAGMA_OACC_CLAUSE_WORKER:
15335 c_name = "worker";
15336 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_WORKER,
15337 c_name, clauses);
15338 break;
15339 default:
15340 c_parser_error (parser, "expected %<#pragma acc%> clause");
15341 goto saw_error;
15342 }
15343
15344 first = false;
15345
15346 if (((mask >> c_kind) & 1) == 0)
15347 {
15348 /* Remove the invalid clause(s) from the list to avoid
15349 confusing the rest of the compiler. */
15350 clauses = prev;
15351 error_at (here, "%qs is not valid for %qs", c_name, where);
15352 }
15353 }
15354
15355 saw_error:
15356 c_parser_skip_to_pragma_eol (parser);
15357
15358 if (finish_p)
15359 return c_finish_omp_clauses (clauses, C_ORT_ACC);
15360
15361 return clauses;
15362 }
15363
15364 /* Parse all OpenMP clauses. The set clauses allowed by the directive
15365 is a bitmask in MASK. Return the list of clauses found.
15366 FINISH_P set if c_finish_omp_clauses should be called.
15367 NESTED non-zero if clauses should be terminated by closing paren instead
15368 of end of pragma. If it is 2, additionally commas are required in between
15369 the clauses. */
15370
15371 static tree
15372 c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
15373 const char *where, bool finish_p = true,
15374 int nested = 0)
15375 {
15376 tree clauses = NULL;
15377 bool first = true;
15378
15379 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
15380 {
15381 location_t here;
15382 pragma_omp_clause c_kind;
15383 const char *c_name;
15384 tree prev = clauses;
15385
15386 if (nested && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
15387 break;
15388
15389 if (!first)
15390 {
15391 if (c_parser_next_token_is (parser, CPP_COMMA))
15392 c_parser_consume_token (parser);
15393 else if (nested == 2)
15394 error_at (c_parser_peek_token (parser)->location,
15395 "clauses in %<simd%> trait should be separated "
15396 "by %<,%>");
15397 }
15398
15399 here = c_parser_peek_token (parser)->location;
15400 c_kind = c_parser_omp_clause_name (parser);
15401
15402 switch (c_kind)
15403 {
15404 case PRAGMA_OMP_CLAUSE_BIND:
15405 clauses = c_parser_omp_clause_bind (parser, clauses);
15406 c_name = "bind";
15407 break;
15408 case PRAGMA_OMP_CLAUSE_COLLAPSE:
15409 clauses = c_parser_omp_clause_collapse (parser, clauses);
15410 c_name = "collapse";
15411 break;
15412 case PRAGMA_OMP_CLAUSE_COPYIN:
15413 clauses = c_parser_omp_clause_copyin (parser, clauses);
15414 c_name = "copyin";
15415 break;
15416 case PRAGMA_OMP_CLAUSE_COPYPRIVATE:
15417 clauses = c_parser_omp_clause_copyprivate (parser, clauses);
15418 c_name = "copyprivate";
15419 break;
15420 case PRAGMA_OMP_CLAUSE_DEFAULT:
15421 clauses = c_parser_omp_clause_default (parser, clauses, false);
15422 c_name = "default";
15423 break;
15424 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
15425 clauses = c_parser_omp_clause_firstprivate (parser, clauses);
15426 c_name = "firstprivate";
15427 break;
15428 case PRAGMA_OMP_CLAUSE_FINAL:
15429 clauses = c_parser_omp_clause_final (parser, clauses);
15430 c_name = "final";
15431 break;
15432 case PRAGMA_OMP_CLAUSE_GRAINSIZE:
15433 clauses = c_parser_omp_clause_grainsize (parser, clauses);
15434 c_name = "grainsize";
15435 break;
15436 case PRAGMA_OMP_CLAUSE_HINT:
15437 clauses = c_parser_omp_clause_hint (parser, clauses);
15438 c_name = "hint";
15439 break;
15440 case PRAGMA_OMP_CLAUSE_DEFAULTMAP:
15441 clauses = c_parser_omp_clause_defaultmap (parser, clauses);
15442 c_name = "defaultmap";
15443 break;
15444 case PRAGMA_OMP_CLAUSE_IF:
15445 clauses = c_parser_omp_clause_if (parser, clauses, true);
15446 c_name = "if";
15447 break;
15448 case PRAGMA_OMP_CLAUSE_IN_REDUCTION:
15449 clauses
15450 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION,
15451 true, clauses);
15452 c_name = "in_reduction";
15453 break;
15454 case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
15455 clauses = c_parser_omp_clause_lastprivate (parser, clauses);
15456 c_name = "lastprivate";
15457 break;
15458 case PRAGMA_OMP_CLAUSE_MERGEABLE:
15459 clauses = c_parser_omp_clause_mergeable (parser, clauses);
15460 c_name = "mergeable";
15461 break;
15462 case PRAGMA_OMP_CLAUSE_NOWAIT:
15463 clauses = c_parser_omp_clause_nowait (parser, clauses);
15464 c_name = "nowait";
15465 break;
15466 case PRAGMA_OMP_CLAUSE_NUM_TASKS:
15467 clauses = c_parser_omp_clause_num_tasks (parser, clauses);
15468 c_name = "num_tasks";
15469 break;
15470 case PRAGMA_OMP_CLAUSE_NUM_THREADS:
15471 clauses = c_parser_omp_clause_num_threads (parser, clauses);
15472 c_name = "num_threads";
15473 break;
15474 case PRAGMA_OMP_CLAUSE_ORDER:
15475 clauses = c_parser_omp_clause_order (parser, clauses);
15476 c_name = "order";
15477 break;
15478 case PRAGMA_OMP_CLAUSE_ORDERED:
15479 clauses = c_parser_omp_clause_ordered (parser, clauses);
15480 c_name = "ordered";
15481 break;
15482 case PRAGMA_OMP_CLAUSE_PRIORITY:
15483 clauses = c_parser_omp_clause_priority (parser, clauses);
15484 c_name = "priority";
15485 break;
15486 case PRAGMA_OMP_CLAUSE_PRIVATE:
15487 clauses = c_parser_omp_clause_private (parser, clauses);
15488 c_name = "private";
15489 break;
15490 case PRAGMA_OMP_CLAUSE_REDUCTION:
15491 clauses
15492 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
15493 true, clauses);
15494 c_name = "reduction";
15495 break;
15496 case PRAGMA_OMP_CLAUSE_SCHEDULE:
15497 clauses = c_parser_omp_clause_schedule (parser, clauses);
15498 c_name = "schedule";
15499 break;
15500 case PRAGMA_OMP_CLAUSE_SHARED:
15501 clauses = c_parser_omp_clause_shared (parser, clauses);
15502 c_name = "shared";
15503 break;
15504 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION:
15505 clauses
15506 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_TASK_REDUCTION,
15507 true, clauses);
15508 c_name = "task_reduction";
15509 break;
15510 case PRAGMA_OMP_CLAUSE_UNTIED:
15511 clauses = c_parser_omp_clause_untied (parser, clauses);
15512 c_name = "untied";
15513 break;
15514 case PRAGMA_OMP_CLAUSE_INBRANCH:
15515 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_INBRANCH,
15516 clauses);
15517 c_name = "inbranch";
15518 break;
15519 case PRAGMA_OMP_CLAUSE_NONTEMPORAL:
15520 clauses = c_parser_omp_clause_nontemporal (parser, clauses);
15521 c_name = "nontemporal";
15522 break;
15523 case PRAGMA_OMP_CLAUSE_NOTINBRANCH:
15524 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_NOTINBRANCH,
15525 clauses);
15526 c_name = "notinbranch";
15527 break;
15528 case PRAGMA_OMP_CLAUSE_PARALLEL:
15529 clauses
15530 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_PARALLEL,
15531 clauses);
15532 c_name = "parallel";
15533 if (!first)
15534 {
15535 clause_not_first:
15536 error_at (here, "%qs must be the first clause of %qs",
15537 c_name, where);
15538 clauses = prev;
15539 }
15540 break;
15541 case PRAGMA_OMP_CLAUSE_FOR:
15542 clauses
15543 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_FOR,
15544 clauses);
15545 c_name = "for";
15546 if (!first)
15547 goto clause_not_first;
15548 break;
15549 case PRAGMA_OMP_CLAUSE_SECTIONS:
15550 clauses
15551 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_SECTIONS,
15552 clauses);
15553 c_name = "sections";
15554 if (!first)
15555 goto clause_not_first;
15556 break;
15557 case PRAGMA_OMP_CLAUSE_TASKGROUP:
15558 clauses
15559 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_TASKGROUP,
15560 clauses);
15561 c_name = "taskgroup";
15562 if (!first)
15563 goto clause_not_first;
15564 break;
15565 case PRAGMA_OMP_CLAUSE_LINK:
15566 clauses
15567 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LINK, clauses);
15568 c_name = "link";
15569 break;
15570 case PRAGMA_OMP_CLAUSE_TO:
15571 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0)
15572 clauses
15573 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO_DECLARE,
15574 clauses);
15575 else
15576 clauses = c_parser_omp_clause_to (parser, clauses);
15577 c_name = "to";
15578 break;
15579 case PRAGMA_OMP_CLAUSE_FROM:
15580 clauses = c_parser_omp_clause_from (parser, clauses);
15581 c_name = "from";
15582 break;
15583 case PRAGMA_OMP_CLAUSE_UNIFORM:
15584 clauses = c_parser_omp_clause_uniform (parser, clauses);
15585 c_name = "uniform";
15586 break;
15587 case PRAGMA_OMP_CLAUSE_NUM_TEAMS:
15588 clauses = c_parser_omp_clause_num_teams (parser, clauses);
15589 c_name = "num_teams";
15590 break;
15591 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT:
15592 clauses = c_parser_omp_clause_thread_limit (parser, clauses);
15593 c_name = "thread_limit";
15594 break;
15595 case PRAGMA_OMP_CLAUSE_ALIGNED:
15596 clauses = c_parser_omp_clause_aligned (parser, clauses);
15597 c_name = "aligned";
15598 break;
15599 case PRAGMA_OMP_CLAUSE_LINEAR:
15600 clauses = c_parser_omp_clause_linear (parser, clauses);
15601 c_name = "linear";
15602 break;
15603 case PRAGMA_OMP_CLAUSE_DEPEND:
15604 clauses = c_parser_omp_clause_depend (parser, clauses);
15605 c_name = "depend";
15606 break;
15607 case PRAGMA_OMP_CLAUSE_MAP:
15608 clauses = c_parser_omp_clause_map (parser, clauses);
15609 c_name = "map";
15610 break;
15611 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR:
15612 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
15613 c_name = "use_device_ptr";
15614 break;
15615 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR:
15616 clauses = c_parser_omp_clause_use_device_addr (parser, clauses);
15617 c_name = "use_device_addr";
15618 break;
15619 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR:
15620 clauses = c_parser_omp_clause_is_device_ptr (parser, clauses);
15621 c_name = "is_device_ptr";
15622 break;
15623 case PRAGMA_OMP_CLAUSE_DEVICE:
15624 clauses = c_parser_omp_clause_device (parser, clauses);
15625 c_name = "device";
15626 break;
15627 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE:
15628 clauses = c_parser_omp_clause_dist_schedule (parser, clauses);
15629 c_name = "dist_schedule";
15630 break;
15631 case PRAGMA_OMP_CLAUSE_PROC_BIND:
15632 clauses = c_parser_omp_clause_proc_bind (parser, clauses);
15633 c_name = "proc_bind";
15634 break;
15635 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE:
15636 clauses = c_parser_omp_clause_device_type (parser, clauses);
15637 c_name = "device_type";
15638 break;
15639 case PRAGMA_OMP_CLAUSE_SAFELEN:
15640 clauses = c_parser_omp_clause_safelen (parser, clauses);
15641 c_name = "safelen";
15642 break;
15643 case PRAGMA_OMP_CLAUSE_SIMDLEN:
15644 clauses = c_parser_omp_clause_simdlen (parser, clauses);
15645 c_name = "simdlen";
15646 break;
15647 case PRAGMA_OMP_CLAUSE_NOGROUP:
15648 clauses = c_parser_omp_clause_nogroup (parser, clauses);
15649 c_name = "nogroup";
15650 break;
15651 case PRAGMA_OMP_CLAUSE_THREADS:
15652 clauses
15653 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_THREADS,
15654 clauses);
15655 c_name = "threads";
15656 break;
15657 case PRAGMA_OMP_CLAUSE_SIMD:
15658 clauses
15659 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_SIMD,
15660 clauses);
15661 c_name = "simd";
15662 break;
15663 default:
15664 c_parser_error (parser, "expected %<#pragma omp%> clause");
15665 goto saw_error;
15666 }
15667
15668 first = false;
15669
15670 if (((mask >> c_kind) & 1) == 0)
15671 {
15672 /* Remove the invalid clause(s) from the list to avoid
15673 confusing the rest of the compiler. */
15674 clauses = prev;
15675 error_at (here, "%qs is not valid for %qs", c_name, where);
15676 }
15677 }
15678
15679 saw_error:
15680 if (!nested)
15681 c_parser_skip_to_pragma_eol (parser);
15682
15683 if (finish_p)
15684 {
15685 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)) != 0)
15686 return c_finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD);
15687 return c_finish_omp_clauses (clauses, C_ORT_OMP);
15688 }
15689
15690 return clauses;
15691 }
15692
15693 /* OpenACC 2.0, OpenMP 2.5:
15694 structured-block:
15695 statement
15696
15697 In practice, we're also interested in adding the statement to an
15698 outer node. So it is convenient if we work around the fact that
15699 c_parser_statement calls add_stmt. */
15700
15701 static tree
15702 c_parser_omp_structured_block (c_parser *parser, bool *if_p)
15703 {
15704 tree stmt = push_stmt_list ();
15705 c_parser_statement (parser, if_p);
15706 return pop_stmt_list (stmt);
15707 }
15708
15709 /* OpenACC 2.0:
15710 # pragma acc cache (variable-list) new-line
15711
15712 LOC is the location of the #pragma token.
15713 */
15714
15715 static tree
15716 c_parser_oacc_cache (location_t loc, c_parser *parser)
15717 {
15718 tree stmt, clauses;
15719
15720 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE__CACHE_, NULL);
15721 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
15722
15723 c_parser_skip_to_pragma_eol (parser);
15724
15725 stmt = make_node (OACC_CACHE);
15726 TREE_TYPE (stmt) = void_type_node;
15727 OACC_CACHE_CLAUSES (stmt) = clauses;
15728 SET_EXPR_LOCATION (stmt, loc);
15729 add_stmt (stmt);
15730
15731 return stmt;
15732 }
15733
15734 /* OpenACC 2.0:
15735 # pragma acc data oacc-data-clause[optseq] new-line
15736 structured-block
15737
15738 LOC is the location of the #pragma token.
15739 */
15740
15741 #define OACC_DATA_CLAUSE_MASK \
15742 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
15743 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
15744 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
15745 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
15746 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
15747 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
15748 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
15749
15750 static tree
15751 c_parser_oacc_data (location_t loc, c_parser *parser, bool *if_p)
15752 {
15753 tree stmt, clauses, block;
15754
15755 clauses = c_parser_oacc_all_clauses (parser, OACC_DATA_CLAUSE_MASK,
15756 "#pragma acc data");
15757
15758 block = c_begin_omp_parallel ();
15759 add_stmt (c_parser_omp_structured_block (parser, if_p));
15760
15761 stmt = c_finish_oacc_data (loc, clauses, block);
15762
15763 return stmt;
15764 }
15765
15766 /* OpenACC 2.0:
15767 # pragma acc declare oacc-data-clause[optseq] new-line
15768 */
15769
15770 #define OACC_DECLARE_CLAUSE_MASK \
15771 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
15772 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
15773 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
15774 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
15775 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
15776 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
15777 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
15778 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
15779
15780 static void
15781 c_parser_oacc_declare (c_parser *parser)
15782 {
15783 location_t pragma_loc = c_parser_peek_token (parser)->location;
15784 tree clauses, stmt, t, decl;
15785
15786 bool error = false;
15787
15788 c_parser_consume_pragma (parser);
15789
15790 clauses = c_parser_oacc_all_clauses (parser, OACC_DECLARE_CLAUSE_MASK,
15791 "#pragma acc declare");
15792 if (!clauses)
15793 {
15794 error_at (pragma_loc,
15795 "no valid clauses specified in %<#pragma acc declare%>");
15796 return;
15797 }
15798
15799 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
15800 {
15801 location_t loc = OMP_CLAUSE_LOCATION (t);
15802 decl = OMP_CLAUSE_DECL (t);
15803 if (!DECL_P (decl))
15804 {
15805 error_at (loc, "array section in %<#pragma acc declare%>");
15806 error = true;
15807 continue;
15808 }
15809
15810 switch (OMP_CLAUSE_MAP_KIND (t))
15811 {
15812 case GOMP_MAP_FIRSTPRIVATE_POINTER:
15813 case GOMP_MAP_ALLOC:
15814 case GOMP_MAP_TO:
15815 case GOMP_MAP_FORCE_DEVICEPTR:
15816 case GOMP_MAP_DEVICE_RESIDENT:
15817 break;
15818
15819 case GOMP_MAP_LINK:
15820 if (!global_bindings_p ()
15821 && (TREE_STATIC (decl)
15822 || !DECL_EXTERNAL (decl)))
15823 {
15824 error_at (loc,
15825 "%qD must be a global variable in "
15826 "%<#pragma acc declare link%>",
15827 decl);
15828 error = true;
15829 continue;
15830 }
15831 break;
15832
15833 default:
15834 if (global_bindings_p ())
15835 {
15836 error_at (loc, "invalid OpenACC clause at file scope");
15837 error = true;
15838 continue;
15839 }
15840 if (DECL_EXTERNAL (decl))
15841 {
15842 error_at (loc,
15843 "invalid use of %<extern%> variable %qD "
15844 "in %<#pragma acc declare%>", decl);
15845 error = true;
15846 continue;
15847 }
15848 else if (TREE_PUBLIC (decl))
15849 {
15850 error_at (loc,
15851 "invalid use of %<global%> variable %qD "
15852 "in %<#pragma acc declare%>", decl);
15853 error = true;
15854 continue;
15855 }
15856 break;
15857 }
15858
15859 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl))
15860 || lookup_attribute ("omp declare target link",
15861 DECL_ATTRIBUTES (decl)))
15862 {
15863 error_at (loc, "variable %qD used more than once with "
15864 "%<#pragma acc declare%>", decl);
15865 error = true;
15866 continue;
15867 }
15868
15869 if (!error)
15870 {
15871 tree id;
15872
15873 if (OMP_CLAUSE_MAP_KIND (t) == GOMP_MAP_LINK)
15874 id = get_identifier ("omp declare target link");
15875 else
15876 id = get_identifier ("omp declare target");
15877
15878 DECL_ATTRIBUTES (decl)
15879 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
15880
15881 if (global_bindings_p ())
15882 {
15883 symtab_node *node = symtab_node::get (decl);
15884 if (node != NULL)
15885 {
15886 node->offloadable = 1;
15887 if (ENABLE_OFFLOADING)
15888 {
15889 g->have_offload = true;
15890 if (is_a <varpool_node *> (node))
15891 vec_safe_push (offload_vars, decl);
15892 }
15893 }
15894 }
15895 }
15896 }
15897
15898 if (error || global_bindings_p ())
15899 return;
15900
15901 stmt = make_node (OACC_DECLARE);
15902 TREE_TYPE (stmt) = void_type_node;
15903 OACC_DECLARE_CLAUSES (stmt) = clauses;
15904 SET_EXPR_LOCATION (stmt, pragma_loc);
15905
15906 add_stmt (stmt);
15907
15908 return;
15909 }
15910
15911 /* OpenACC 2.0:
15912 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
15913
15914 or
15915
15916 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
15917
15918
15919 LOC is the location of the #pragma token.
15920 */
15921
15922 #define OACC_ENTER_DATA_CLAUSE_MASK \
15923 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
15924 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
15925 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
15926 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
15927 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
15928
15929 #define OACC_EXIT_DATA_CLAUSE_MASK \
15930 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
15931 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
15932 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
15933 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
15934 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \
15935 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
15936
15937 static void
15938 c_parser_oacc_enter_exit_data (c_parser *parser, bool enter)
15939 {
15940 location_t loc = c_parser_peek_token (parser)->location;
15941 tree clauses, stmt;
15942 const char *p = "";
15943
15944 c_parser_consume_pragma (parser);
15945
15946 if (c_parser_next_token_is (parser, CPP_NAME))
15947 {
15948 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
15949 c_parser_consume_token (parser);
15950 }
15951
15952 if (strcmp (p, "data") != 0)
15953 {
15954 error_at (loc, "expected %<data%> after %<#pragma acc %s%>",
15955 enter ? "enter" : "exit");
15956 parser->error = true;
15957 c_parser_skip_to_pragma_eol (parser);
15958 return;
15959 }
15960
15961 if (enter)
15962 clauses = c_parser_oacc_all_clauses (parser, OACC_ENTER_DATA_CLAUSE_MASK,
15963 "#pragma acc enter data");
15964 else
15965 clauses = c_parser_oacc_all_clauses (parser, OACC_EXIT_DATA_CLAUSE_MASK,
15966 "#pragma acc exit data");
15967
15968 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
15969 {
15970 error_at (loc, "%<#pragma acc %s data%> has no data movement clause",
15971 enter ? "enter" : "exit");
15972 return;
15973 }
15974
15975 stmt = enter ? make_node (OACC_ENTER_DATA) : make_node (OACC_EXIT_DATA);
15976 TREE_TYPE (stmt) = void_type_node;
15977 OMP_STANDALONE_CLAUSES (stmt) = clauses;
15978 SET_EXPR_LOCATION (stmt, loc);
15979 add_stmt (stmt);
15980 }
15981
15982
15983 /* OpenACC 2.0:
15984 # pragma acc host_data oacc-data-clause[optseq] new-line
15985 structured-block
15986 */
15987
15988 #define OACC_HOST_DATA_CLAUSE_MASK \
15989 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) )
15990
15991 static tree
15992 c_parser_oacc_host_data (location_t loc, c_parser *parser, bool *if_p)
15993 {
15994 tree stmt, clauses, block;
15995
15996 clauses = c_parser_oacc_all_clauses (parser, OACC_HOST_DATA_CLAUSE_MASK,
15997 "#pragma acc host_data");
15998
15999 block = c_begin_omp_parallel ();
16000 add_stmt (c_parser_omp_structured_block (parser, if_p));
16001 stmt = c_finish_oacc_host_data (loc, clauses, block);
16002 return stmt;
16003 }
16004
16005
16006 /* OpenACC 2.0:
16007
16008 # pragma acc loop oacc-loop-clause[optseq] new-line
16009 structured-block
16010
16011 LOC is the location of the #pragma token.
16012 */
16013
16014 #define OACC_LOOP_CLAUSE_MASK \
16015 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
16016 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
16017 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
16018 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
16019 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
16020 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
16021 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
16022 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
16023 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
16024 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
16025 static tree
16026 c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name,
16027 omp_clause_mask mask, tree *cclauses, bool *if_p)
16028 {
16029 bool is_parallel = ((mask >> PRAGMA_OACC_CLAUSE_REDUCTION) & 1) == 1;
16030
16031 strcat (p_name, " loop");
16032 mask |= OACC_LOOP_CLAUSE_MASK;
16033
16034 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name,
16035 cclauses == NULL);
16036 if (cclauses)
16037 {
16038 clauses = c_oacc_split_loop_clauses (clauses, cclauses, is_parallel);
16039 if (*cclauses)
16040 *cclauses = c_finish_omp_clauses (*cclauses, C_ORT_ACC);
16041 if (clauses)
16042 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
16043 }
16044
16045 tree block = c_begin_compound_stmt (true);
16046 tree stmt = c_parser_omp_for_loop (loc, parser, OACC_LOOP, clauses, NULL,
16047 if_p);
16048 block = c_end_compound_stmt (loc, block, true);
16049 add_stmt (block);
16050
16051 return stmt;
16052 }
16053
16054 /* OpenACC 2.0:
16055 # pragma acc kernels oacc-kernels-clause[optseq] new-line
16056 structured-block
16057
16058 or
16059
16060 # pragma acc parallel oacc-parallel-clause[optseq] new-line
16061 structured-block
16062
16063 LOC is the location of the #pragma token.
16064 */
16065
16066 #define OACC_KERNELS_CLAUSE_MASK \
16067 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16068 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16069 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16070 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16071 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16072 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
16073 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16074 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16075 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
16076 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
16077 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
16078 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
16079 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16080
16081 #define OACC_PARALLEL_CLAUSE_MASK \
16082 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16083 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
16084 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
16085 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
16086 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
16087 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
16088 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
16089 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16090 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
16091 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
16092 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
16093 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
16094 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
16095 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
16096 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
16097 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16098
16099 static tree
16100 c_parser_oacc_kernels_parallel (location_t loc, c_parser *parser,
16101 enum pragma_kind p_kind, char *p_name,
16102 bool *if_p)
16103 {
16104 omp_clause_mask mask;
16105 enum tree_code code;
16106 switch (p_kind)
16107 {
16108 case PRAGMA_OACC_KERNELS:
16109 strcat (p_name, " kernels");
16110 mask = OACC_KERNELS_CLAUSE_MASK;
16111 code = OACC_KERNELS;
16112 break;
16113 case PRAGMA_OACC_PARALLEL:
16114 strcat (p_name, " parallel");
16115 mask = OACC_PARALLEL_CLAUSE_MASK;
16116 code = OACC_PARALLEL;
16117 break;
16118 default:
16119 gcc_unreachable ();
16120 }
16121
16122 if (c_parser_next_token_is (parser, CPP_NAME))
16123 {
16124 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16125 if (strcmp (p, "loop") == 0)
16126 {
16127 c_parser_consume_token (parser);
16128 tree block = c_begin_omp_parallel ();
16129 tree clauses;
16130 c_parser_oacc_loop (loc, parser, p_name, mask, &clauses, if_p);
16131 return c_finish_omp_construct (loc, code, block, clauses);
16132 }
16133 }
16134
16135 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name);
16136
16137 tree block = c_begin_omp_parallel ();
16138 add_stmt (c_parser_omp_structured_block (parser, if_p));
16139
16140 return c_finish_omp_construct (loc, code, block, clauses);
16141 }
16142
16143 /* OpenACC 2.0:
16144 # pragma acc routine oacc-routine-clause[optseq] new-line
16145 function-definition
16146
16147 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
16148 */
16149
16150 #define OACC_ROUTINE_CLAUSE_MASK \
16151 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
16152 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
16153 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
16154 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) )
16155
16156 /* Parse an OpenACC routine directive. For named directives, we apply
16157 immediately to the named function. For unnamed ones we then parse
16158 a declaration or definition, which must be for a function. */
16159
16160 static void
16161 c_parser_oacc_routine (c_parser *parser, enum pragma_context context)
16162 {
16163 gcc_checking_assert (context == pragma_external);
16164
16165 oacc_routine_data data;
16166 data.error_seen = false;
16167 data.fndecl_seen = false;
16168 data.clauses = NULL_TREE;
16169 data.loc = c_parser_peek_token (parser)->location;
16170
16171 c_parser_consume_pragma (parser);
16172
16173 /* Look for optional '( name )'. */
16174 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
16175 {
16176 c_parser_consume_token (parser); /* '(' */
16177
16178 tree decl = NULL_TREE;
16179 c_token *name_token = c_parser_peek_token (parser);
16180 location_t name_loc = name_token->location;
16181 if (name_token->type == CPP_NAME
16182 && (name_token->id_kind == C_ID_ID
16183 || name_token->id_kind == C_ID_TYPENAME))
16184 {
16185 decl = lookup_name (name_token->value);
16186 if (!decl)
16187 error_at (name_loc,
16188 "%qE has not been declared", name_token->value);
16189 c_parser_consume_token (parser);
16190 }
16191 else
16192 c_parser_error (parser, "expected function name");
16193
16194 if (!decl
16195 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
16196 {
16197 c_parser_skip_to_pragma_eol (parser, false);
16198 return;
16199 }
16200
16201 data.clauses
16202 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
16203 "#pragma acc routine");
16204 /* The clauses are in reverse order; fix that to make later diagnostic
16205 emission easier. */
16206 data.clauses = nreverse (data.clauses);
16207
16208 if (TREE_CODE (decl) != FUNCTION_DECL)
16209 {
16210 error_at (name_loc, "%qD does not refer to a function", decl);
16211 return;
16212 }
16213
16214 c_finish_oacc_routine (&data, decl, false);
16215 }
16216 else /* No optional '( name )'. */
16217 {
16218 data.clauses
16219 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
16220 "#pragma acc routine");
16221 /* The clauses are in reverse order; fix that to make later diagnostic
16222 emission easier. */
16223 data.clauses = nreverse (data.clauses);
16224
16225 /* Emit a helpful diagnostic if there's another pragma following this
16226 one. Also don't allow a static assertion declaration, as in the
16227 following we'll just parse a *single* "declaration or function
16228 definition", and the static assertion counts an one. */
16229 if (c_parser_next_token_is (parser, CPP_PRAGMA)
16230 || c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
16231 {
16232 error_at (data.loc,
16233 "%<#pragma acc routine%> not immediately followed by"
16234 " function declaration or definition");
16235 /* ..., and then just keep going. */
16236 return;
16237 }
16238
16239 /* We only have to consider the pragma_external case here. */
16240 if (c_parser_next_token_is (parser, CPP_KEYWORD)
16241 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
16242 {
16243 int ext = disable_extension_diagnostics ();
16244 do
16245 c_parser_consume_token (parser);
16246 while (c_parser_next_token_is (parser, CPP_KEYWORD)
16247 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
16248 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
16249 NULL, vNULL, &data);
16250 restore_extension_diagnostics (ext);
16251 }
16252 else
16253 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
16254 NULL, vNULL, &data);
16255 }
16256 }
16257
16258 /* Finalize an OpenACC routine pragma, applying it to FNDECL.
16259 IS_DEFN is true if we're applying it to the definition. */
16260
16261 static void
16262 c_finish_oacc_routine (struct oacc_routine_data *data, tree fndecl,
16263 bool is_defn)
16264 {
16265 /* Keep going if we're in error reporting mode. */
16266 if (data->error_seen
16267 || fndecl == error_mark_node)
16268 return;
16269
16270 if (data->fndecl_seen)
16271 {
16272 error_at (data->loc,
16273 "%<#pragma acc routine%> not immediately followed by"
16274 " a single function declaration or definition");
16275 data->error_seen = true;
16276 return;
16277 }
16278 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
16279 {
16280 error_at (data->loc,
16281 "%<#pragma acc routine%> not immediately followed by"
16282 " function declaration or definition");
16283 data->error_seen = true;
16284 return;
16285 }
16286
16287 int compatible
16288 = oacc_verify_routine_clauses (fndecl, &data->clauses, data->loc,
16289 "#pragma acc routine");
16290 if (compatible < 0)
16291 {
16292 data->error_seen = true;
16293 return;
16294 }
16295 if (compatible > 0)
16296 {
16297 }
16298 else
16299 {
16300 if (TREE_USED (fndecl) || (!is_defn && DECL_SAVED_TREE (fndecl)))
16301 {
16302 error_at (data->loc,
16303 TREE_USED (fndecl)
16304 ? G_("%<#pragma acc routine%> must be applied before use")
16305 : G_("%<#pragma acc routine%> must be applied before"
16306 " definition"));
16307 data->error_seen = true;
16308 return;
16309 }
16310
16311 /* Set the routine's level of parallelism. */
16312 tree dims = oacc_build_routine_dims (data->clauses);
16313 oacc_replace_fn_attrib (fndecl, dims);
16314
16315 /* Add an "omp declare target" attribute. */
16316 DECL_ATTRIBUTES (fndecl)
16317 = tree_cons (get_identifier ("omp declare target"),
16318 data->clauses, DECL_ATTRIBUTES (fndecl));
16319 }
16320
16321 /* Remember that we've used this "#pragma acc routine". */
16322 data->fndecl_seen = true;
16323 }
16324
16325 /* OpenACC 2.0:
16326 # pragma acc update oacc-update-clause[optseq] new-line
16327 */
16328
16329 #define OACC_UPDATE_CLAUSE_MASK \
16330 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
16331 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
16332 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
16333 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
16334 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
16335 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
16336
16337 static void
16338 c_parser_oacc_update (c_parser *parser)
16339 {
16340 location_t loc = c_parser_peek_token (parser)->location;
16341
16342 c_parser_consume_pragma (parser);
16343
16344 tree clauses = c_parser_oacc_all_clauses (parser, OACC_UPDATE_CLAUSE_MASK,
16345 "#pragma acc update");
16346 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
16347 {
16348 error_at (loc,
16349 "%<#pragma acc update%> must contain at least one "
16350 "%<device%> or %<host%> or %<self%> clause");
16351 return;
16352 }
16353
16354 if (parser->error)
16355 return;
16356
16357 tree stmt = make_node (OACC_UPDATE);
16358 TREE_TYPE (stmt) = void_type_node;
16359 OACC_UPDATE_CLAUSES (stmt) = clauses;
16360 SET_EXPR_LOCATION (stmt, loc);
16361 add_stmt (stmt);
16362 }
16363
16364 /* OpenACC 2.0:
16365 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
16366
16367 LOC is the location of the #pragma token.
16368 */
16369
16370 #define OACC_WAIT_CLAUSE_MASK \
16371 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) )
16372
16373 static tree
16374 c_parser_oacc_wait (location_t loc, c_parser *parser, char *p_name)
16375 {
16376 tree clauses, list = NULL_TREE, stmt = NULL_TREE;
16377
16378 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
16379 list = c_parser_oacc_wait_list (parser, loc, list);
16380
16381 strcpy (p_name, " wait");
16382 clauses = c_parser_oacc_all_clauses (parser, OACC_WAIT_CLAUSE_MASK, p_name);
16383 stmt = c_finish_oacc_wait (loc, list, clauses);
16384 add_stmt (stmt);
16385
16386 return stmt;
16387 }
16388
16389 /* OpenMP 2.5:
16390 # pragma omp atomic new-line
16391 expression-stmt
16392
16393 expression-stmt:
16394 x binop= expr | x++ | ++x | x-- | --x
16395 binop:
16396 +, *, -, /, &, ^, |, <<, >>
16397
16398 where x is an lvalue expression with scalar type.
16399
16400 OpenMP 3.1:
16401 # pragma omp atomic new-line
16402 update-stmt
16403
16404 # pragma omp atomic read new-line
16405 read-stmt
16406
16407 # pragma omp atomic write new-line
16408 write-stmt
16409
16410 # pragma omp atomic update new-line
16411 update-stmt
16412
16413 # pragma omp atomic capture new-line
16414 capture-stmt
16415
16416 # pragma omp atomic capture new-line
16417 capture-block
16418
16419 read-stmt:
16420 v = x
16421 write-stmt:
16422 x = expr
16423 update-stmt:
16424 expression-stmt | x = x binop expr
16425 capture-stmt:
16426 v = expression-stmt
16427 capture-block:
16428 { v = x; update-stmt; } | { update-stmt; v = x; }
16429
16430 OpenMP 4.0:
16431 update-stmt:
16432 expression-stmt | x = x binop expr | x = expr binop x
16433 capture-stmt:
16434 v = update-stmt
16435 capture-block:
16436 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
16437
16438 where x and v are lvalue expressions with scalar type.
16439
16440 LOC is the location of the #pragma token. */
16441
16442 static void
16443 c_parser_omp_atomic (location_t loc, c_parser *parser)
16444 {
16445 tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE;
16446 tree lhs1 = NULL_TREE, rhs1 = NULL_TREE;
16447 tree stmt, orig_lhs, unfolded_lhs = NULL_TREE, unfolded_lhs1 = NULL_TREE;
16448 enum tree_code code = ERROR_MARK, opcode = NOP_EXPR;
16449 enum omp_memory_order memory_order = OMP_MEMORY_ORDER_UNSPECIFIED;
16450 struct c_expr expr;
16451 location_t eloc;
16452 bool structured_block = false;
16453 bool swapped = false;
16454 bool non_lvalue_p;
16455 bool first = true;
16456 tree clauses = NULL_TREE;
16457
16458 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
16459 {
16460 if (!first && c_parser_next_token_is (parser, CPP_COMMA))
16461 c_parser_consume_token (parser);
16462
16463 first = false;
16464
16465 if (c_parser_next_token_is (parser, CPP_NAME))
16466 {
16467 const char *p
16468 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
16469 location_t cloc = c_parser_peek_token (parser)->location;
16470 enum tree_code new_code = ERROR_MARK;
16471 enum omp_memory_order new_memory_order
16472 = OMP_MEMORY_ORDER_UNSPECIFIED;
16473
16474 if (!strcmp (p, "read"))
16475 new_code = OMP_ATOMIC_READ;
16476 else if (!strcmp (p, "write"))
16477 new_code = NOP_EXPR;
16478 else if (!strcmp (p, "update"))
16479 new_code = OMP_ATOMIC;
16480 else if (!strcmp (p, "capture"))
16481 new_code = OMP_ATOMIC_CAPTURE_NEW;
16482 else if (!strcmp (p, "seq_cst"))
16483 new_memory_order = OMP_MEMORY_ORDER_SEQ_CST;
16484 else if (!strcmp (p, "acq_rel"))
16485 new_memory_order = OMP_MEMORY_ORDER_ACQ_REL;
16486 else if (!strcmp (p, "release"))
16487 new_memory_order = OMP_MEMORY_ORDER_RELEASE;
16488 else if (!strcmp (p, "acquire"))
16489 new_memory_order = OMP_MEMORY_ORDER_ACQUIRE;
16490 else if (!strcmp (p, "relaxed"))
16491 new_memory_order = OMP_MEMORY_ORDER_RELAXED;
16492 else if (!strcmp (p, "hint"))
16493 {
16494 c_parser_consume_token (parser);
16495 clauses = c_parser_omp_clause_hint (parser, clauses);
16496 continue;
16497 }
16498 else
16499 {
16500 p = NULL;
16501 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
16502 "%<capture%>, %<seq_cst%>, %<acq_rel%>, "
16503 "%<release%>, %<relaxed%> or %<hint%> clause");
16504 }
16505 if (p)
16506 {
16507 if (new_code != ERROR_MARK)
16508 {
16509 if (code != ERROR_MARK)
16510 error_at (cloc, "too many atomic clauses");
16511 else
16512 code = new_code;
16513 }
16514 else if (new_memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
16515 {
16516 if (memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
16517 error_at (cloc, "too many memory order clauses");
16518 else
16519 memory_order = new_memory_order;
16520 }
16521 c_parser_consume_token (parser);
16522 continue;
16523 }
16524 }
16525 break;
16526 }
16527 c_parser_skip_to_pragma_eol (parser);
16528
16529 if (code == ERROR_MARK)
16530 code = OMP_ATOMIC;
16531 if (memory_order == OMP_MEMORY_ORDER_UNSPECIFIED)
16532 {
16533 omp_requires_mask
16534 = (enum omp_requires) (omp_requires_mask
16535 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED);
16536 switch ((enum omp_memory_order)
16537 (omp_requires_mask & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER))
16538 {
16539 case OMP_MEMORY_ORDER_UNSPECIFIED:
16540 case OMP_MEMORY_ORDER_RELAXED:
16541 memory_order = OMP_MEMORY_ORDER_RELAXED;
16542 break;
16543 case OMP_MEMORY_ORDER_SEQ_CST:
16544 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
16545 break;
16546 case OMP_MEMORY_ORDER_ACQ_REL:
16547 switch (code)
16548 {
16549 case OMP_ATOMIC_READ:
16550 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
16551 break;
16552 case NOP_EXPR: /* atomic write */
16553 case OMP_ATOMIC:
16554 memory_order = OMP_MEMORY_ORDER_RELEASE;
16555 break;
16556 default:
16557 memory_order = OMP_MEMORY_ORDER_ACQ_REL;
16558 break;
16559 }
16560 break;
16561 default:
16562 gcc_unreachable ();
16563 }
16564 }
16565 else
16566 switch (code)
16567 {
16568 case OMP_ATOMIC_READ:
16569 if (memory_order == OMP_MEMORY_ORDER_ACQ_REL
16570 || memory_order == OMP_MEMORY_ORDER_RELEASE)
16571 {
16572 error_at (loc, "%<#pragma omp atomic read%> incompatible with "
16573 "%<acq_rel%> or %<release%> clauses");
16574 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
16575 }
16576 break;
16577 case NOP_EXPR: /* atomic write */
16578 if (memory_order == OMP_MEMORY_ORDER_ACQ_REL
16579 || memory_order == OMP_MEMORY_ORDER_ACQUIRE)
16580 {
16581 error_at (loc, "%<#pragma omp atomic write%> incompatible with "
16582 "%<acq_rel%> or %<acquire%> clauses");
16583 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
16584 }
16585 break;
16586 case OMP_ATOMIC:
16587 if (memory_order == OMP_MEMORY_ORDER_ACQ_REL
16588 || memory_order == OMP_MEMORY_ORDER_ACQUIRE)
16589 {
16590 error_at (loc, "%<#pragma omp atomic update%> incompatible with "
16591 "%<acq_rel%> or %<acquire%> clauses");
16592 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
16593 }
16594 break;
16595 default:
16596 break;
16597 }
16598
16599 switch (code)
16600 {
16601 case OMP_ATOMIC_READ:
16602 case NOP_EXPR: /* atomic write */
16603 v = c_parser_cast_expression (parser, NULL).value;
16604 non_lvalue_p = !lvalue_p (v);
16605 v = c_fully_fold (v, false, NULL, true);
16606 if (v == error_mark_node)
16607 goto saw_error;
16608 if (non_lvalue_p)
16609 v = non_lvalue (v);
16610 loc = c_parser_peek_token (parser)->location;
16611 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
16612 goto saw_error;
16613 if (code == NOP_EXPR)
16614 {
16615 lhs = c_parser_expression (parser).value;
16616 lhs = c_fully_fold (lhs, false, NULL);
16617 if (lhs == error_mark_node)
16618 goto saw_error;
16619 }
16620 else
16621 {
16622 lhs = c_parser_cast_expression (parser, NULL).value;
16623 non_lvalue_p = !lvalue_p (lhs);
16624 lhs = c_fully_fold (lhs, false, NULL, true);
16625 if (lhs == error_mark_node)
16626 goto saw_error;
16627 if (non_lvalue_p)
16628 lhs = non_lvalue (lhs);
16629 }
16630 if (code == NOP_EXPR)
16631 {
16632 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
16633 opcode. */
16634 code = OMP_ATOMIC;
16635 rhs = lhs;
16636 lhs = v;
16637 v = NULL_TREE;
16638 }
16639 goto done;
16640 case OMP_ATOMIC_CAPTURE_NEW:
16641 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
16642 {
16643 c_parser_consume_token (parser);
16644 structured_block = true;
16645 }
16646 else
16647 {
16648 v = c_parser_cast_expression (parser, NULL).value;
16649 non_lvalue_p = !lvalue_p (v);
16650 v = c_fully_fold (v, false, NULL, true);
16651 if (v == error_mark_node)
16652 goto saw_error;
16653 if (non_lvalue_p)
16654 v = non_lvalue (v);
16655 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
16656 goto saw_error;
16657 }
16658 break;
16659 default:
16660 break;
16661 }
16662
16663 /* For structured_block case we don't know yet whether
16664 old or new x should be captured. */
16665 restart:
16666 eloc = c_parser_peek_token (parser)->location;
16667 expr = c_parser_cast_expression (parser, NULL);
16668 lhs = expr.value;
16669 expr = default_function_array_conversion (eloc, expr);
16670 unfolded_lhs = expr.value;
16671 lhs = c_fully_fold (lhs, false, NULL, true);
16672 orig_lhs = lhs;
16673 switch (TREE_CODE (lhs))
16674 {
16675 case ERROR_MARK:
16676 saw_error:
16677 c_parser_skip_to_end_of_block_or_statement (parser);
16678 if (structured_block)
16679 {
16680 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
16681 c_parser_consume_token (parser);
16682 else if (code == OMP_ATOMIC_CAPTURE_NEW)
16683 {
16684 c_parser_skip_to_end_of_block_or_statement (parser);
16685 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
16686 c_parser_consume_token (parser);
16687 }
16688 }
16689 return;
16690
16691 case POSTINCREMENT_EXPR:
16692 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
16693 code = OMP_ATOMIC_CAPTURE_OLD;
16694 /* FALLTHROUGH */
16695 case PREINCREMENT_EXPR:
16696 lhs = TREE_OPERAND (lhs, 0);
16697 unfolded_lhs = NULL_TREE;
16698 opcode = PLUS_EXPR;
16699 rhs = integer_one_node;
16700 break;
16701
16702 case POSTDECREMENT_EXPR:
16703 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
16704 code = OMP_ATOMIC_CAPTURE_OLD;
16705 /* FALLTHROUGH */
16706 case PREDECREMENT_EXPR:
16707 lhs = TREE_OPERAND (lhs, 0);
16708 unfolded_lhs = NULL_TREE;
16709 opcode = MINUS_EXPR;
16710 rhs = integer_one_node;
16711 break;
16712
16713 case COMPOUND_EXPR:
16714 if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR
16715 && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR
16716 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR
16717 && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0)
16718 && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
16719 (TREE_OPERAND (lhs, 1), 0), 0)))
16720 == BOOLEAN_TYPE)
16721 /* Undo effects of boolean_increment for post {in,de}crement. */
16722 lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
16723 /* FALLTHRU */
16724 case MODIFY_EXPR:
16725 if (TREE_CODE (lhs) == MODIFY_EXPR
16726 && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) == BOOLEAN_TYPE)
16727 {
16728 /* Undo effects of boolean_increment. */
16729 if (integer_onep (TREE_OPERAND (lhs, 1)))
16730 {
16731 /* This is pre or post increment. */
16732 rhs = TREE_OPERAND (lhs, 1);
16733 lhs = TREE_OPERAND (lhs, 0);
16734 unfolded_lhs = NULL_TREE;
16735 opcode = NOP_EXPR;
16736 if (code == OMP_ATOMIC_CAPTURE_NEW
16737 && !structured_block
16738 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
16739 code = OMP_ATOMIC_CAPTURE_OLD;
16740 break;
16741 }
16742 if (TREE_CODE (TREE_OPERAND (lhs, 1)) == TRUTH_NOT_EXPR
16743 && TREE_OPERAND (lhs, 0)
16744 == TREE_OPERAND (TREE_OPERAND (lhs, 1), 0))
16745 {
16746 /* This is pre or post decrement. */
16747 rhs = TREE_OPERAND (lhs, 1);
16748 lhs = TREE_OPERAND (lhs, 0);
16749 unfolded_lhs = NULL_TREE;
16750 opcode = NOP_EXPR;
16751 if (code == OMP_ATOMIC_CAPTURE_NEW
16752 && !structured_block
16753 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
16754 code = OMP_ATOMIC_CAPTURE_OLD;
16755 break;
16756 }
16757 }
16758 /* FALLTHRU */
16759 default:
16760 if (!lvalue_p (unfolded_lhs))
16761 lhs = non_lvalue (lhs);
16762 switch (c_parser_peek_token (parser)->type)
16763 {
16764 case CPP_MULT_EQ:
16765 opcode = MULT_EXPR;
16766 break;
16767 case CPP_DIV_EQ:
16768 opcode = TRUNC_DIV_EXPR;
16769 break;
16770 case CPP_PLUS_EQ:
16771 opcode = PLUS_EXPR;
16772 break;
16773 case CPP_MINUS_EQ:
16774 opcode = MINUS_EXPR;
16775 break;
16776 case CPP_LSHIFT_EQ:
16777 opcode = LSHIFT_EXPR;
16778 break;
16779 case CPP_RSHIFT_EQ:
16780 opcode = RSHIFT_EXPR;
16781 break;
16782 case CPP_AND_EQ:
16783 opcode = BIT_AND_EXPR;
16784 break;
16785 case CPP_OR_EQ:
16786 opcode = BIT_IOR_EXPR;
16787 break;
16788 case CPP_XOR_EQ:
16789 opcode = BIT_XOR_EXPR;
16790 break;
16791 case CPP_EQ:
16792 c_parser_consume_token (parser);
16793 eloc = c_parser_peek_token (parser)->location;
16794 expr = c_parser_expr_no_commas (parser, NULL, unfolded_lhs);
16795 rhs1 = expr.value;
16796 switch (TREE_CODE (rhs1))
16797 {
16798 case MULT_EXPR:
16799 case TRUNC_DIV_EXPR:
16800 case RDIV_EXPR:
16801 case PLUS_EXPR:
16802 case MINUS_EXPR:
16803 case LSHIFT_EXPR:
16804 case RSHIFT_EXPR:
16805 case BIT_AND_EXPR:
16806 case BIT_IOR_EXPR:
16807 case BIT_XOR_EXPR:
16808 if (c_tree_equal (TREE_OPERAND (rhs1, 0), unfolded_lhs))
16809 {
16810 opcode = TREE_CODE (rhs1);
16811 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
16812 true);
16813 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
16814 true);
16815 goto stmt_done;
16816 }
16817 if (c_tree_equal (TREE_OPERAND (rhs1, 1), unfolded_lhs))
16818 {
16819 opcode = TREE_CODE (rhs1);
16820 rhs = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
16821 true);
16822 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
16823 true);
16824 swapped = !commutative_tree_code (opcode);
16825 goto stmt_done;
16826 }
16827 break;
16828 case ERROR_MARK:
16829 goto saw_error;
16830 default:
16831 break;
16832 }
16833 if (c_parser_peek_token (parser)->type == CPP_SEMICOLON)
16834 {
16835 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
16836 {
16837 code = OMP_ATOMIC_CAPTURE_OLD;
16838 v = lhs;
16839 lhs = NULL_TREE;
16840 expr = default_function_array_read_conversion (eloc, expr);
16841 unfolded_lhs1 = expr.value;
16842 lhs1 = c_fully_fold (unfolded_lhs1, false, NULL, true);
16843 rhs1 = NULL_TREE;
16844 c_parser_consume_token (parser);
16845 goto restart;
16846 }
16847 if (structured_block)
16848 {
16849 opcode = NOP_EXPR;
16850 expr = default_function_array_read_conversion (eloc, expr);
16851 rhs = c_fully_fold (expr.value, false, NULL, true);
16852 rhs1 = NULL_TREE;
16853 goto stmt_done;
16854 }
16855 }
16856 c_parser_error (parser, "invalid form of %<#pragma omp atomic%>");
16857 goto saw_error;
16858 default:
16859 c_parser_error (parser,
16860 "invalid operator for %<#pragma omp atomic%>");
16861 goto saw_error;
16862 }
16863
16864 /* Arrange to pass the location of the assignment operator to
16865 c_finish_omp_atomic. */
16866 loc = c_parser_peek_token (parser)->location;
16867 c_parser_consume_token (parser);
16868 eloc = c_parser_peek_token (parser)->location;
16869 expr = c_parser_expression (parser);
16870 expr = default_function_array_read_conversion (eloc, expr);
16871 rhs = expr.value;
16872 rhs = c_fully_fold (rhs, false, NULL, true);
16873 break;
16874 }
16875 stmt_done:
16876 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
16877 {
16878 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
16879 goto saw_error;
16880 v = c_parser_cast_expression (parser, NULL).value;
16881 non_lvalue_p = !lvalue_p (v);
16882 v = c_fully_fold (v, false, NULL, true);
16883 if (v == error_mark_node)
16884 goto saw_error;
16885 if (non_lvalue_p)
16886 v = non_lvalue (v);
16887 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
16888 goto saw_error;
16889 eloc = c_parser_peek_token (parser)->location;
16890 expr = c_parser_cast_expression (parser, NULL);
16891 lhs1 = expr.value;
16892 expr = default_function_array_read_conversion (eloc, expr);
16893 unfolded_lhs1 = expr.value;
16894 lhs1 = c_fully_fold (lhs1, false, NULL, true);
16895 if (lhs1 == error_mark_node)
16896 goto saw_error;
16897 if (!lvalue_p (unfolded_lhs1))
16898 lhs1 = non_lvalue (lhs1);
16899 }
16900 if (structured_block)
16901 {
16902 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
16903 c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>");
16904 }
16905 done:
16906 if (unfolded_lhs && unfolded_lhs1
16907 && !c_tree_equal (unfolded_lhs, unfolded_lhs1))
16908 {
16909 error ("%<#pragma omp atomic capture%> uses two different "
16910 "expressions for memory");
16911 stmt = error_mark_node;
16912 }
16913 else
16914 stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs, v, lhs1, rhs1,
16915 swapped, memory_order);
16916 if (stmt != error_mark_node)
16917 add_stmt (stmt);
16918
16919 if (!structured_block)
16920 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
16921 }
16922
16923
16924 /* OpenMP 2.5:
16925 # pragma omp barrier new-line
16926 */
16927
16928 static void
16929 c_parser_omp_barrier (c_parser *parser)
16930 {
16931 location_t loc = c_parser_peek_token (parser)->location;
16932 c_parser_consume_pragma (parser);
16933 c_parser_skip_to_pragma_eol (parser);
16934
16935 c_finish_omp_barrier (loc);
16936 }
16937
16938 /* OpenMP 2.5:
16939 # pragma omp critical [(name)] new-line
16940 structured-block
16941
16942 OpenMP 4.5:
16943 # pragma omp critical [(name) [hint(expression)]] new-line
16944
16945 LOC is the location of the #pragma itself. */
16946
16947 #define OMP_CRITICAL_CLAUSE_MASK \
16948 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
16949
16950 static tree
16951 c_parser_omp_critical (location_t loc, c_parser *parser, bool *if_p)
16952 {
16953 tree stmt, name = NULL_TREE, clauses = NULL_TREE;
16954
16955 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
16956 {
16957 c_parser_consume_token (parser);
16958 if (c_parser_next_token_is (parser, CPP_NAME))
16959 {
16960 name = c_parser_peek_token (parser)->value;
16961 c_parser_consume_token (parser);
16962 c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
16963 }
16964 else
16965 c_parser_error (parser, "expected identifier");
16966
16967 if (c_parser_next_token_is (parser, CPP_COMMA)
16968 && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
16969 c_parser_consume_token (parser);
16970
16971 clauses = c_parser_omp_all_clauses (parser,
16972 OMP_CRITICAL_CLAUSE_MASK,
16973 "#pragma omp critical");
16974 }
16975 else
16976 {
16977 if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
16978 c_parser_error (parser, "expected %<(%> or end of line");
16979 c_parser_skip_to_pragma_eol (parser);
16980 }
16981
16982 stmt = c_parser_omp_structured_block (parser, if_p);
16983 return c_finish_omp_critical (loc, stmt, name, clauses);
16984 }
16985
16986 /* OpenMP 5.0:
16987 # pragma omp depobj ( depobj ) depobj-clause new-line
16988
16989 depobj-clause:
16990 depend (dependence-type : locator)
16991 destroy
16992 update (dependence-type)
16993
16994 dependence-type:
16995 in
16996 out
16997 inout
16998 mutexinout */
16999
17000 static void
17001 c_parser_omp_depobj (c_parser *parser)
17002 {
17003 location_t loc = c_parser_peek_token (parser)->location;
17004 c_parser_consume_pragma (parser);
17005 matching_parens parens;
17006 if (!parens.require_open (parser))
17007 {
17008 c_parser_skip_to_pragma_eol (parser);
17009 return;
17010 }
17011
17012 tree depobj = c_parser_expr_no_commas (parser, NULL).value;
17013 if (depobj != error_mark_node)
17014 {
17015 if (!lvalue_p (depobj))
17016 {
17017 error_at (EXPR_LOC_OR_LOC (depobj, loc),
17018 "%<depobj%> expression is not lvalue expression");
17019 depobj = error_mark_node;
17020 }
17021 else
17022 {
17023 tree addr = build_unary_op (EXPR_LOC_OR_LOC (depobj, loc), ADDR_EXPR,
17024 depobj, false);
17025 if (addr == error_mark_node)
17026 depobj = error_mark_node;
17027 else
17028 depobj = build_indirect_ref (EXPR_LOC_OR_LOC (depobj, loc),
17029 addr, RO_UNARY_STAR);
17030 }
17031 }
17032
17033 parens.skip_until_found_close (parser);
17034 tree clause = NULL_TREE;
17035 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_SOURCE;
17036 location_t c_loc = c_parser_peek_token (parser)->location;
17037 if (c_parser_next_token_is (parser, CPP_NAME))
17038 {
17039 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17040
17041 c_parser_consume_token (parser);
17042 if (!strcmp ("depend", p))
17043 {
17044 clause = c_parser_omp_clause_depend (parser, NULL_TREE);
17045 clause = c_finish_omp_clauses (clause, C_ORT_OMP);
17046 if (!clause)
17047 clause = error_mark_node;
17048 }
17049 else if (!strcmp ("destroy", p))
17050 kind = OMP_CLAUSE_DEPEND_LAST;
17051 else if (!strcmp ("update", p))
17052 {
17053 matching_parens c_parens;
17054 if (c_parens.require_open (parser))
17055 {
17056 location_t c2_loc = c_parser_peek_token (parser)->location;
17057 if (c_parser_next_token_is (parser, CPP_NAME))
17058 {
17059 const char *p2
17060 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17061
17062 c_parser_consume_token (parser);
17063 if (!strcmp ("in", p2))
17064 kind = OMP_CLAUSE_DEPEND_IN;
17065 else if (!strcmp ("out", p2))
17066 kind = OMP_CLAUSE_DEPEND_OUT;
17067 else if (!strcmp ("inout", p2))
17068 kind = OMP_CLAUSE_DEPEND_INOUT;
17069 else if (!strcmp ("mutexinoutset", p2))
17070 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
17071 }
17072 if (kind == OMP_CLAUSE_DEPEND_SOURCE)
17073 {
17074 clause = error_mark_node;
17075 error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%> or "
17076 "%<mutexinoutset%>");
17077 }
17078 c_parens.skip_until_found_close (parser);
17079 }
17080 else
17081 clause = error_mark_node;
17082 }
17083 }
17084 if (!clause && kind == OMP_CLAUSE_DEPEND_SOURCE)
17085 {
17086 clause = error_mark_node;
17087 error_at (c_loc, "expected %<depend%>, %<destroy%> or %<update%> clause");
17088 }
17089 c_parser_skip_to_pragma_eol (parser);
17090
17091 c_finish_omp_depobj (loc, depobj, kind, clause);
17092 }
17093
17094
17095 /* OpenMP 2.5:
17096 # pragma omp flush flush-vars[opt] new-line
17097
17098 flush-vars:
17099 ( variable-list )
17100
17101 OpenMP 5.0:
17102 # pragma omp flush memory-order-clause new-line */
17103
17104 static void
17105 c_parser_omp_flush (c_parser *parser)
17106 {
17107 location_t loc = c_parser_peek_token (parser)->location;
17108 c_parser_consume_pragma (parser);
17109 enum memmodel mo = MEMMODEL_LAST;
17110 if (c_parser_next_token_is (parser, CPP_NAME))
17111 {
17112 const char *p
17113 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17114
17115 if (!strcmp (p, "acq_rel"))
17116 mo = MEMMODEL_ACQ_REL;
17117 else if (!strcmp (p, "release"))
17118 mo = MEMMODEL_RELEASE;
17119 else if (!strcmp (p, "acquire"))
17120 mo = MEMMODEL_ACQUIRE;
17121 else
17122 error_at (c_parser_peek_token (parser)->location,
17123 "expected %<acq_rel%>, %<release%> or %<acquire%>");
17124 c_parser_consume_token (parser);
17125 }
17126 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
17127 {
17128 if (mo != MEMMODEL_LAST)
17129 error_at (c_parser_peek_token (parser)->location,
17130 "%<flush%> list specified together with memory order "
17131 "clause");
17132 c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
17133 }
17134 else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
17135 c_parser_error (parser, "expected %<(%> or end of line");
17136 c_parser_skip_to_pragma_eol (parser);
17137
17138 c_finish_omp_flush (loc, mo);
17139 }
17140
17141 /* OpenMP 5.0:
17142
17143 scan-loop-body:
17144 { structured-block scan-directive structured-block } */
17145
17146 static void
17147 c_parser_omp_scan_loop_body (c_parser *parser, bool open_brace_parsed)
17148 {
17149 tree substmt;
17150 location_t loc;
17151 tree clauses = NULL_TREE;
17152
17153 loc = c_parser_peek_token (parser)->location;
17154 if (!open_brace_parsed
17155 && !c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
17156 {
17157 /* Avoid skipping until the end of the block. */
17158 parser->error = false;
17159 return;
17160 }
17161
17162 substmt = c_parser_omp_structured_block (parser, NULL);
17163 substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE);
17164 SET_EXPR_LOCATION (substmt, loc);
17165 add_stmt (substmt);
17166
17167 loc = c_parser_peek_token (parser)->location;
17168 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SCAN)
17169 {
17170 enum omp_clause_code clause = OMP_CLAUSE_ERROR;
17171
17172 c_parser_consume_pragma (parser);
17173
17174 if (c_parser_next_token_is (parser, CPP_NAME))
17175 {
17176 const char *p
17177 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17178 if (strcmp (p, "inclusive") == 0)
17179 clause = OMP_CLAUSE_INCLUSIVE;
17180 else if (strcmp (p, "exclusive") == 0)
17181 clause = OMP_CLAUSE_EXCLUSIVE;
17182 }
17183 if (clause != OMP_CLAUSE_ERROR)
17184 {
17185 c_parser_consume_token (parser);
17186 clauses = c_parser_omp_var_list_parens (parser, clause, NULL_TREE);
17187 }
17188 else
17189 c_parser_error (parser, "expected %<inclusive%> or "
17190 "%<exclusive%> clause");
17191 c_parser_skip_to_pragma_eol (parser);
17192 }
17193 else
17194 error ("expected %<#pragma omp scan%>");
17195
17196 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
17197 substmt = c_parser_omp_structured_block (parser, NULL);
17198 substmt = build2 (OMP_SCAN, void_type_node, substmt, clauses);
17199 SET_EXPR_LOCATION (substmt, loc);
17200 add_stmt (substmt);
17201
17202 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
17203 "expected %<}%>");
17204 }
17205
17206 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
17207 The real trick here is to determine the loop control variable early
17208 so that we can push a new decl if necessary to make it private.
17209 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
17210 respectively. */
17211
17212 static tree
17213 c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
17214 tree clauses, tree *cclauses, bool *if_p)
17215 {
17216 tree decl, cond, incr, save_break, save_cont, body, init, stmt, cl;
17217 tree declv, condv, incrv, initv, ret = NULL_TREE;
17218 tree pre_body = NULL_TREE, this_pre_body;
17219 tree ordered_cl = NULL_TREE;
17220 bool fail = false, open_brace_parsed = false;
17221 int i, collapse = 1, ordered = 0, count, nbraces = 0;
17222 location_t for_loc;
17223 bool tiling = false;
17224 bool inscan = false;
17225 vec<tree, va_gc> *for_block = make_tree_vector ();
17226
17227 for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
17228 if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
17229 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl));
17230 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_TILE)
17231 {
17232 tiling = true;
17233 collapse = list_length (OMP_CLAUSE_TILE_LIST (cl));
17234 }
17235 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED
17236 && OMP_CLAUSE_ORDERED_EXPR (cl))
17237 {
17238 ordered_cl = cl;
17239 ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
17240 }
17241 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_REDUCTION
17242 && OMP_CLAUSE_REDUCTION_INSCAN (cl)
17243 && (code == OMP_SIMD || code == OMP_FOR))
17244 inscan = true;
17245
17246 if (ordered && ordered < collapse)
17247 {
17248 error_at (OMP_CLAUSE_LOCATION (ordered_cl),
17249 "%<ordered%> clause parameter is less than %<collapse%>");
17250 OMP_CLAUSE_ORDERED_EXPR (ordered_cl)
17251 = build_int_cst (NULL_TREE, collapse);
17252 ordered = collapse;
17253 }
17254 if (ordered)
17255 {
17256 for (tree *pc = &clauses; *pc; )
17257 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LINEAR)
17258 {
17259 error_at (OMP_CLAUSE_LOCATION (*pc),
17260 "%<linear%> clause may not be specified together "
17261 "with %<ordered%> clause with a parameter");
17262 *pc = OMP_CLAUSE_CHAIN (*pc);
17263 }
17264 else
17265 pc = &OMP_CLAUSE_CHAIN (*pc);
17266 }
17267
17268 gcc_assert (tiling || (collapse >= 1 && ordered >= 0));
17269 count = ordered ? ordered : collapse;
17270
17271 declv = make_tree_vec (count);
17272 initv = make_tree_vec (count);
17273 condv = make_tree_vec (count);
17274 incrv = make_tree_vec (count);
17275
17276 if (!c_parser_next_token_is_keyword (parser, RID_FOR))
17277 {
17278 c_parser_error (parser, "for statement expected");
17279 return NULL;
17280 }
17281 for_loc = c_parser_peek_token (parser)->location;
17282 c_parser_consume_token (parser);
17283
17284 for (i = 0; i < count; i++)
17285 {
17286 int bracecount = 0;
17287
17288 matching_parens parens;
17289 if (!parens.require_open (parser))
17290 goto pop_scopes;
17291
17292 /* Parse the initialization declaration or expression. */
17293 if (c_parser_next_tokens_start_declaration (parser))
17294 {
17295 if (i > 0)
17296 vec_safe_push (for_block, c_begin_compound_stmt (true));
17297 this_pre_body = push_stmt_list ();
17298 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
17299 NULL, vNULL);
17300 if (this_pre_body)
17301 {
17302 this_pre_body = pop_stmt_list (this_pre_body);
17303 if (pre_body)
17304 {
17305 tree t = pre_body;
17306 pre_body = push_stmt_list ();
17307 add_stmt (t);
17308 add_stmt (this_pre_body);
17309 pre_body = pop_stmt_list (pre_body);
17310 }
17311 else
17312 pre_body = this_pre_body;
17313 }
17314 decl = check_for_loop_decls (for_loc, flag_isoc99);
17315 if (decl == NULL)
17316 goto error_init;
17317 if (DECL_INITIAL (decl) == error_mark_node)
17318 decl = error_mark_node;
17319 init = decl;
17320 }
17321 else if (c_parser_next_token_is (parser, CPP_NAME)
17322 && c_parser_peek_2nd_token (parser)->type == CPP_EQ)
17323 {
17324 struct c_expr decl_exp;
17325 struct c_expr init_exp;
17326 location_t init_loc;
17327
17328 decl_exp = c_parser_postfix_expression (parser);
17329 decl = decl_exp.value;
17330
17331 c_parser_require (parser, CPP_EQ, "expected %<=%>");
17332
17333 init_loc = c_parser_peek_token (parser)->location;
17334 init_exp = c_parser_expr_no_commas (parser, NULL);
17335 init_exp = default_function_array_read_conversion (init_loc,
17336 init_exp);
17337 init = build_modify_expr (init_loc, decl, decl_exp.original_type,
17338 NOP_EXPR, init_loc, init_exp.value,
17339 init_exp.original_type);
17340 init = c_process_expr_stmt (init_loc, init);
17341
17342 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
17343 }
17344 else
17345 {
17346 error_init:
17347 c_parser_error (parser,
17348 "expected iteration declaration or initialization");
17349 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
17350 "expected %<)%>");
17351 fail = true;
17352 goto parse_next;
17353 }
17354
17355 /* Parse the loop condition. */
17356 cond = NULL_TREE;
17357 if (c_parser_next_token_is_not (parser, CPP_SEMICOLON))
17358 {
17359 location_t cond_loc = c_parser_peek_token (parser)->location;
17360 struct c_expr cond_expr
17361 = c_parser_binary_expression (parser, NULL, NULL_TREE);
17362
17363 cond = cond_expr.value;
17364 cond = c_objc_common_truthvalue_conversion (cond_loc, cond);
17365 if (COMPARISON_CLASS_P (cond))
17366 {
17367 tree op0 = TREE_OPERAND (cond, 0), op1 = TREE_OPERAND (cond, 1);
17368 op0 = c_fully_fold (op0, false, NULL);
17369 op1 = c_fully_fold (op1, false, NULL);
17370 TREE_OPERAND (cond, 0) = op0;
17371 TREE_OPERAND (cond, 1) = op1;
17372 }
17373 switch (cond_expr.original_code)
17374 {
17375 case GT_EXPR:
17376 case GE_EXPR:
17377 case LT_EXPR:
17378 case LE_EXPR:
17379 break;
17380 case NE_EXPR:
17381 if (code != OACC_LOOP)
17382 break;
17383 /* FALLTHRU. */
17384 default:
17385 /* Can't be cond = error_mark_node, because we want to preserve
17386 the location until c_finish_omp_for. */
17387 cond = build1 (NOP_EXPR, boolean_type_node, error_mark_node);
17388 break;
17389 }
17390 protected_set_expr_location (cond, cond_loc);
17391 }
17392 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
17393
17394 /* Parse the increment expression. */
17395 incr = NULL_TREE;
17396 if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
17397 {
17398 location_t incr_loc = c_parser_peek_token (parser)->location;
17399
17400 incr = c_process_expr_stmt (incr_loc,
17401 c_parser_expression (parser).value);
17402 }
17403 parens.skip_until_found_close (parser);
17404
17405 if (decl == NULL || decl == error_mark_node || init == error_mark_node)
17406 fail = true;
17407 else
17408 {
17409 TREE_VEC_ELT (declv, i) = decl;
17410 TREE_VEC_ELT (initv, i) = init;
17411 TREE_VEC_ELT (condv, i) = cond;
17412 TREE_VEC_ELT (incrv, i) = incr;
17413 }
17414
17415 parse_next:
17416 if (i == count - 1)
17417 break;
17418
17419 /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
17420 in between the collapsed for loops to be still considered perfectly
17421 nested. Hopefully the final version clarifies this.
17422 For now handle (multiple) {'s and empty statements. */
17423 do
17424 {
17425 if (c_parser_next_token_is_keyword (parser, RID_FOR))
17426 {
17427 c_parser_consume_token (parser);
17428 break;
17429 }
17430 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
17431 {
17432 c_parser_consume_token (parser);
17433 bracecount++;
17434 }
17435 else if (bracecount
17436 && c_parser_next_token_is (parser, CPP_SEMICOLON))
17437 c_parser_consume_token (parser);
17438 else
17439 {
17440 c_parser_error (parser, "not enough perfectly nested loops");
17441 if (bracecount)
17442 {
17443 open_brace_parsed = true;
17444 bracecount--;
17445 }
17446 fail = true;
17447 count = 0;
17448 break;
17449 }
17450 }
17451 while (1);
17452
17453 nbraces += bracecount;
17454 }
17455
17456 if (nbraces)
17457 if_p = NULL;
17458
17459 save_break = c_break_label;
17460 c_break_label = size_one_node;
17461 save_cont = c_cont_label;
17462 c_cont_label = NULL_TREE;
17463 body = push_stmt_list ();
17464
17465 if (inscan)
17466 c_parser_omp_scan_loop_body (parser, open_brace_parsed);
17467 else if (open_brace_parsed)
17468 {
17469 location_t here = c_parser_peek_token (parser)->location;
17470 stmt = c_begin_compound_stmt (true);
17471 c_parser_compound_statement_nostart (parser);
17472 add_stmt (c_end_compound_stmt (here, stmt, true));
17473 }
17474 else
17475 add_stmt (c_parser_c99_block_statement (parser, if_p));
17476 if (c_cont_label)
17477 {
17478 tree t = build1 (LABEL_EXPR, void_type_node, c_cont_label);
17479 SET_EXPR_LOCATION (t, loc);
17480 add_stmt (t);
17481 }
17482
17483 body = pop_stmt_list (body);
17484 c_break_label = save_break;
17485 c_cont_label = save_cont;
17486
17487 while (nbraces)
17488 {
17489 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
17490 {
17491 c_parser_consume_token (parser);
17492 nbraces--;
17493 }
17494 else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
17495 c_parser_consume_token (parser);
17496 else
17497 {
17498 c_parser_error (parser, "collapsed loops not perfectly nested");
17499 while (nbraces)
17500 {
17501 location_t here = c_parser_peek_token (parser)->location;
17502 stmt = c_begin_compound_stmt (true);
17503 add_stmt (body);
17504 c_parser_compound_statement_nostart (parser);
17505 body = c_end_compound_stmt (here, stmt, true);
17506 nbraces--;
17507 }
17508 goto pop_scopes;
17509 }
17510 }
17511
17512 /* Only bother calling c_finish_omp_for if we haven't already generated
17513 an error from the initialization parsing. */
17514 if (!fail)
17515 {
17516 stmt = c_finish_omp_for (loc, code, declv, NULL, initv, condv,
17517 incrv, body, pre_body, true);
17518
17519 /* Check for iterators appearing in lb, b or incr expressions. */
17520 if (stmt && !c_omp_check_loop_iv (stmt, declv, NULL))
17521 stmt = NULL_TREE;
17522
17523 if (stmt)
17524 {
17525 add_stmt (stmt);
17526
17527 if (cclauses != NULL
17528 && cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL)
17529 {
17530 tree *c;
17531 for (c = &cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; *c ; )
17532 if (OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_FIRSTPRIVATE
17533 && OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_LASTPRIVATE)
17534 c = &OMP_CLAUSE_CHAIN (*c);
17535 else
17536 {
17537 for (i = 0; i < count; i++)
17538 if (TREE_VEC_ELT (declv, i) == OMP_CLAUSE_DECL (*c))
17539 break;
17540 if (i == count)
17541 c = &OMP_CLAUSE_CHAIN (*c);
17542 else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE)
17543 {
17544 error_at (loc,
17545 "iteration variable %qD should not be firstprivate",
17546 OMP_CLAUSE_DECL (*c));
17547 *c = OMP_CLAUSE_CHAIN (*c);
17548 }
17549 else
17550 {
17551 /* Move lastprivate (decl) clause to OMP_FOR_CLAUSES. */
17552 tree l = *c;
17553 *c = OMP_CLAUSE_CHAIN (*c);
17554 if (code == OMP_SIMD)
17555 {
17556 OMP_CLAUSE_CHAIN (l)
17557 = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
17558 cclauses[C_OMP_CLAUSE_SPLIT_FOR] = l;
17559 }
17560 else
17561 {
17562 OMP_CLAUSE_CHAIN (l) = clauses;
17563 clauses = l;
17564 }
17565 }
17566 }
17567 }
17568 OMP_FOR_CLAUSES (stmt) = clauses;
17569 }
17570 ret = stmt;
17571 }
17572 pop_scopes:
17573 while (!for_block->is_empty ())
17574 {
17575 /* FIXME diagnostics: LOC below should be the actual location of
17576 this particular for block. We need to build a list of
17577 locations to go along with FOR_BLOCK. */
17578 stmt = c_end_compound_stmt (loc, for_block->pop (), true);
17579 add_stmt (stmt);
17580 }
17581 release_tree_vector (for_block);
17582 return ret;
17583 }
17584
17585 /* Helper function for OpenMP parsing, split clauses and call
17586 finish_omp_clauses on each of the set of clauses afterwards. */
17587
17588 static void
17589 omp_split_clauses (location_t loc, enum tree_code code,
17590 omp_clause_mask mask, tree clauses, tree *cclauses)
17591 {
17592 int i;
17593 c_omp_split_clauses (loc, code, mask, clauses, cclauses);
17594 for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
17595 if (cclauses[i])
17596 cclauses[i] = c_finish_omp_clauses (cclauses[i], C_ORT_OMP);
17597 }
17598
17599 /* OpenMP 5.0:
17600 #pragma omp loop loop-clause[optseq] new-line
17601 for-loop
17602
17603 LOC is the location of the #pragma token.
17604 */
17605
17606 #define OMP_LOOP_CLAUSE_MASK \
17607 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
17608 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
17609 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
17610 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
17611 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
17612 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
17613
17614 static tree
17615 c_parser_omp_loop (location_t loc, c_parser *parser,
17616 char *p_name, omp_clause_mask mask, tree *cclauses,
17617 bool *if_p)
17618 {
17619 tree block, clauses, ret;
17620
17621 strcat (p_name, " loop");
17622 mask |= OMP_LOOP_CLAUSE_MASK;
17623
17624 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
17625 if (cclauses)
17626 {
17627 omp_split_clauses (loc, OMP_LOOP, mask, clauses, cclauses);
17628 clauses = cclauses[C_OMP_CLAUSE_SPLIT_LOOP];
17629 }
17630
17631 block = c_begin_compound_stmt (true);
17632 ret = c_parser_omp_for_loop (loc, parser, OMP_LOOP, clauses, cclauses, if_p);
17633 block = c_end_compound_stmt (loc, block, true);
17634 add_stmt (block);
17635
17636 return ret;
17637 }
17638
17639 /* OpenMP 4.0:
17640 #pragma omp simd simd-clause[optseq] new-line
17641 for-loop
17642
17643 LOC is the location of the #pragma token.
17644 */
17645
17646 #define OMP_SIMD_CLAUSE_MASK \
17647 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
17648 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
17649 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
17650 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
17651 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
17652 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
17653 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
17654 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
17655 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
17656 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
17657 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
17658
17659 static tree
17660 c_parser_omp_simd (location_t loc, c_parser *parser,
17661 char *p_name, omp_clause_mask mask, tree *cclauses,
17662 bool *if_p)
17663 {
17664 tree block, clauses, ret;
17665
17666 strcat (p_name, " simd");
17667 mask |= OMP_SIMD_CLAUSE_MASK;
17668
17669 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
17670 if (cclauses)
17671 {
17672 omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses);
17673 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
17674 tree c = omp_find_clause (cclauses[C_OMP_CLAUSE_SPLIT_FOR],
17675 OMP_CLAUSE_ORDERED);
17676 if (c && OMP_CLAUSE_ORDERED_EXPR (c))
17677 {
17678 error_at (OMP_CLAUSE_LOCATION (c),
17679 "%<ordered%> clause with parameter may not be specified "
17680 "on %qs construct", p_name);
17681 OMP_CLAUSE_ORDERED_EXPR (c) = NULL_TREE;
17682 }
17683 }
17684
17685 block = c_begin_compound_stmt (true);
17686 ret = c_parser_omp_for_loop (loc, parser, OMP_SIMD, clauses, cclauses, if_p);
17687 block = c_end_compound_stmt (loc, block, true);
17688 add_stmt (block);
17689
17690 return ret;
17691 }
17692
17693 /* OpenMP 2.5:
17694 #pragma omp for for-clause[optseq] new-line
17695 for-loop
17696
17697 OpenMP 4.0:
17698 #pragma omp for simd for-simd-clause[optseq] new-line
17699 for-loop
17700
17701 LOC is the location of the #pragma token.
17702 */
17703
17704 #define OMP_FOR_CLAUSE_MASK \
17705 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
17706 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
17707 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
17708 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
17709 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
17710 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
17711 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
17712 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
17713 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
17714 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
17715
17716 static tree
17717 c_parser_omp_for (location_t loc, c_parser *parser,
17718 char *p_name, omp_clause_mask mask, tree *cclauses,
17719 bool *if_p)
17720 {
17721 tree block, clauses, ret;
17722
17723 strcat (p_name, " for");
17724 mask |= OMP_FOR_CLAUSE_MASK;
17725 /* parallel for{, simd} disallows nowait clause, but for
17726 target {teams distribute ,}parallel for{, simd} it should be accepted. */
17727 if (cclauses && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0)
17728 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
17729 /* Composite distribute parallel for{, simd} disallows ordered clause. */
17730 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
17731 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED);
17732
17733 if (c_parser_next_token_is (parser, CPP_NAME))
17734 {
17735 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17736
17737 if (strcmp (p, "simd") == 0)
17738 {
17739 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
17740 if (cclauses == NULL)
17741 cclauses = cclauses_buf;
17742
17743 c_parser_consume_token (parser);
17744 if (!flag_openmp) /* flag_openmp_simd */
17745 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
17746 if_p);
17747 block = c_begin_compound_stmt (true);
17748 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
17749 block = c_end_compound_stmt (loc, block, true);
17750 if (ret == NULL_TREE)
17751 return ret;
17752 ret = make_node (OMP_FOR);
17753 TREE_TYPE (ret) = void_type_node;
17754 OMP_FOR_BODY (ret) = block;
17755 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
17756 SET_EXPR_LOCATION (ret, loc);
17757 add_stmt (ret);
17758 return ret;
17759 }
17760 }
17761 if (!flag_openmp) /* flag_openmp_simd */
17762 {
17763 c_parser_skip_to_pragma_eol (parser, false);
17764 return NULL_TREE;
17765 }
17766
17767 /* Composite distribute parallel for disallows linear clause. */
17768 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
17769 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR);
17770
17771 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
17772 if (cclauses)
17773 {
17774 omp_split_clauses (loc, OMP_FOR, mask, clauses, cclauses);
17775 clauses = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
17776 }
17777
17778 block = c_begin_compound_stmt (true);
17779 ret = c_parser_omp_for_loop (loc, parser, OMP_FOR, clauses, cclauses, if_p);
17780 block = c_end_compound_stmt (loc, block, true);
17781 add_stmt (block);
17782
17783 return ret;
17784 }
17785
17786 static tree c_parser_omp_taskloop (location_t, c_parser *, char *,
17787 omp_clause_mask, tree *, bool *);
17788
17789 /* OpenMP 2.5:
17790 # pragma omp master new-line
17791 structured-block
17792
17793 LOC is the location of the #pragma token.
17794 */
17795
17796 static tree
17797 c_parser_omp_master (location_t loc, c_parser *parser,
17798 char *p_name, omp_clause_mask mask, tree *cclauses,
17799 bool *if_p)
17800 {
17801 tree block, clauses, ret;
17802
17803 strcat (p_name, " master");
17804
17805 if (c_parser_next_token_is (parser, CPP_NAME))
17806 {
17807 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17808
17809 if (strcmp (p, "taskloop") == 0)
17810 {
17811 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
17812 if (cclauses == NULL)
17813 cclauses = cclauses_buf;
17814
17815 c_parser_consume_token (parser);
17816 if (!flag_openmp) /* flag_openmp_simd */
17817 return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
17818 if_p);
17819 block = c_begin_compound_stmt (true);
17820 ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
17821 if_p);
17822 block = c_end_compound_stmt (loc, block, true);
17823 if (ret == NULL_TREE)
17824 return ret;
17825 ret = c_finish_omp_master (loc, block);
17826 return ret;
17827 }
17828 }
17829 if (!flag_openmp) /* flag_openmp_simd */
17830 {
17831 c_parser_skip_to_pragma_eol (parser, false);
17832 return NULL_TREE;
17833 }
17834
17835 if (cclauses)
17836 {
17837 clauses = c_parser_omp_all_clauses (parser, mask, p_name, false);
17838 omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses);
17839 }
17840 else
17841 c_parser_skip_to_pragma_eol (parser);
17842
17843 return c_finish_omp_master (loc, c_parser_omp_structured_block (parser,
17844 if_p));
17845 }
17846
17847 /* OpenMP 2.5:
17848 # pragma omp ordered new-line
17849 structured-block
17850
17851 OpenMP 4.5:
17852 # pragma omp ordered ordered-clauses new-line
17853 structured-block
17854
17855 # pragma omp ordered depend-clauses new-line */
17856
17857 #define OMP_ORDERED_CLAUSE_MASK \
17858 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
17859 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
17860
17861 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \
17862 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
17863
17864 static bool
17865 c_parser_omp_ordered (c_parser *parser, enum pragma_context context,
17866 bool *if_p)
17867 {
17868 location_t loc = c_parser_peek_token (parser)->location;
17869 c_parser_consume_pragma (parser);
17870
17871 if (context != pragma_stmt && context != pragma_compound)
17872 {
17873 c_parser_error (parser, "expected declaration specifiers");
17874 c_parser_skip_to_pragma_eol (parser, false);
17875 return false;
17876 }
17877
17878 if (c_parser_next_token_is (parser, CPP_NAME))
17879 {
17880 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
17881
17882 if (!strcmp ("depend", p))
17883 {
17884 if (!flag_openmp) /* flag_openmp_simd */
17885 {
17886 c_parser_skip_to_pragma_eol (parser, false);
17887 return false;
17888 }
17889 if (context == pragma_stmt)
17890 {
17891 error_at (loc,
17892 "%<#pragma omp ordered%> with %<depend%> clause may "
17893 "only be used in compound statements");
17894 c_parser_skip_to_pragma_eol (parser, false);
17895 return false;
17896 }
17897
17898 tree clauses
17899 = c_parser_omp_all_clauses (parser,
17900 OMP_ORDERED_DEPEND_CLAUSE_MASK,
17901 "#pragma omp ordered");
17902 c_finish_omp_ordered (loc, clauses, NULL_TREE);
17903 return false;
17904 }
17905 }
17906
17907 tree clauses = c_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK,
17908 "#pragma omp ordered");
17909
17910 if (!flag_openmp /* flag_openmp_simd */
17911 && omp_find_clause (clauses, OMP_CLAUSE_SIMD) == NULL_TREE)
17912 return false;
17913
17914 c_finish_omp_ordered (loc, clauses,
17915 c_parser_omp_structured_block (parser, if_p));
17916 return true;
17917 }
17918
17919 /* OpenMP 2.5:
17920
17921 section-scope:
17922 { section-sequence }
17923
17924 section-sequence:
17925 section-directive[opt] structured-block
17926 section-sequence section-directive structured-block
17927
17928 SECTIONS_LOC is the location of the #pragma omp sections. */
17929
17930 static tree
17931 c_parser_omp_sections_scope (location_t sections_loc, c_parser *parser)
17932 {
17933 tree stmt, substmt;
17934 bool error_suppress = false;
17935 location_t loc;
17936
17937 loc = c_parser_peek_token (parser)->location;
17938 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
17939 {
17940 /* Avoid skipping until the end of the block. */
17941 parser->error = false;
17942 return NULL_TREE;
17943 }
17944
17945 stmt = push_stmt_list ();
17946
17947 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION)
17948 {
17949 substmt = c_parser_omp_structured_block (parser, NULL);
17950 substmt = build1 (OMP_SECTION, void_type_node, substmt);
17951 SET_EXPR_LOCATION (substmt, loc);
17952 add_stmt (substmt);
17953 }
17954
17955 while (1)
17956 {
17957 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
17958 break;
17959 if (c_parser_next_token_is (parser, CPP_EOF))
17960 break;
17961
17962 loc = c_parser_peek_token (parser)->location;
17963 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION)
17964 {
17965 c_parser_consume_pragma (parser);
17966 c_parser_skip_to_pragma_eol (parser);
17967 error_suppress = false;
17968 }
17969 else if (!error_suppress)
17970 {
17971 error_at (loc, "expected %<#pragma omp section%> or %<}%>");
17972 error_suppress = true;
17973 }
17974
17975 substmt = c_parser_omp_structured_block (parser, NULL);
17976 substmt = build1 (OMP_SECTION, void_type_node, substmt);
17977 SET_EXPR_LOCATION (substmt, loc);
17978 add_stmt (substmt);
17979 }
17980 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
17981 "expected %<#pragma omp section%> or %<}%>");
17982
17983 substmt = pop_stmt_list (stmt);
17984
17985 stmt = make_node (OMP_SECTIONS);
17986 SET_EXPR_LOCATION (stmt, sections_loc);
17987 TREE_TYPE (stmt) = void_type_node;
17988 OMP_SECTIONS_BODY (stmt) = substmt;
17989
17990 return add_stmt (stmt);
17991 }
17992
17993 /* OpenMP 2.5:
17994 # pragma omp sections sections-clause[optseq] newline
17995 sections-scope
17996
17997 LOC is the location of the #pragma token.
17998 */
17999
18000 #define OMP_SECTIONS_CLAUSE_MASK \
18001 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18002 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18003 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18004 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18005 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
18006
18007 static tree
18008 c_parser_omp_sections (location_t loc, c_parser *parser,
18009 char *p_name, omp_clause_mask mask, tree *cclauses)
18010 {
18011 tree block, clauses, ret;
18012
18013 strcat (p_name, " sections");
18014 mask |= OMP_SECTIONS_CLAUSE_MASK;
18015 if (cclauses)
18016 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
18017
18018 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
18019 if (cclauses)
18020 {
18021 omp_split_clauses (loc, OMP_SECTIONS, mask, clauses, cclauses);
18022 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS];
18023 }
18024
18025 block = c_begin_compound_stmt (true);
18026 ret = c_parser_omp_sections_scope (loc, parser);
18027 if (ret)
18028 OMP_SECTIONS_CLAUSES (ret) = clauses;
18029 block = c_end_compound_stmt (loc, block, true);
18030 add_stmt (block);
18031
18032 return ret;
18033 }
18034
18035 /* OpenMP 2.5:
18036 # pragma omp parallel parallel-clause[optseq] new-line
18037 structured-block
18038 # pragma omp parallel for parallel-for-clause[optseq] new-line
18039 structured-block
18040 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
18041 structured-block
18042
18043 OpenMP 4.0:
18044 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
18045 structured-block
18046
18047 LOC is the location of the #pragma token.
18048 */
18049
18050 #define OMP_PARALLEL_CLAUSE_MASK \
18051 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
18052 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18053 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18054 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
18055 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
18056 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
18057 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18058 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
18059 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
18060
18061 static tree
18062 c_parser_omp_parallel (location_t loc, c_parser *parser,
18063 char *p_name, omp_clause_mask mask, tree *cclauses,
18064 bool *if_p)
18065 {
18066 tree stmt, clauses, block;
18067
18068 strcat (p_name, " parallel");
18069 mask |= OMP_PARALLEL_CLAUSE_MASK;
18070 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
18071 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0
18072 && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
18073 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN);
18074
18075 if (c_parser_next_token_is_keyword (parser, RID_FOR))
18076 {
18077 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18078 if (cclauses == NULL)
18079 cclauses = cclauses_buf;
18080
18081 c_parser_consume_token (parser);
18082 if (!flag_openmp) /* flag_openmp_simd */
18083 return c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
18084 block = c_begin_omp_parallel ();
18085 tree ret = c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
18086 stmt
18087 = c_finish_omp_parallel (loc, cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
18088 block);
18089 if (ret == NULL_TREE)
18090 return ret;
18091 OMP_PARALLEL_COMBINED (stmt) = 1;
18092 return stmt;
18093 }
18094 /* When combined with distribute, parallel has to be followed by for.
18095 #pragma omp target parallel is allowed though. */
18096 else if (cclauses
18097 && (mask & (OMP_CLAUSE_MASK_1
18098 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
18099 {
18100 error_at (loc, "expected %<for%> after %qs", p_name);
18101 c_parser_skip_to_pragma_eol (parser);
18102 return NULL_TREE;
18103 }
18104 else if (c_parser_next_token_is (parser, CPP_NAME))
18105 {
18106 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18107 if (cclauses == NULL && strcmp (p, "master") == 0)
18108 {
18109 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18110 cclauses = cclauses_buf;
18111
18112 c_parser_consume_token (parser);
18113 if (!flag_openmp) /* flag_openmp_simd */
18114 return c_parser_omp_master (loc, parser, p_name, mask, cclauses,
18115 if_p);
18116 block = c_begin_omp_parallel ();
18117 tree ret = c_parser_omp_master (loc, parser, p_name, mask, cclauses,
18118 if_p);
18119 stmt = c_finish_omp_parallel (loc,
18120 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
18121 block);
18122 OMP_PARALLEL_COMBINED (stmt) = 1;
18123 if (ret == NULL)
18124 return ret;
18125 return stmt;
18126 }
18127 else if (strcmp (p, "loop") == 0)
18128 {
18129 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18130 if (cclauses == NULL)
18131 cclauses = cclauses_buf;
18132
18133 c_parser_consume_token (parser);
18134 if (!flag_openmp) /* flag_openmp_simd */
18135 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
18136 if_p);
18137 block = c_begin_omp_parallel ();
18138 tree ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
18139 if_p);
18140 stmt
18141 = c_finish_omp_parallel (loc,
18142 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
18143 block);
18144 if (ret == NULL_TREE)
18145 return ret;
18146 OMP_PARALLEL_COMBINED (stmt) = 1;
18147 return stmt;
18148 }
18149 else if (!flag_openmp) /* flag_openmp_simd */
18150 {
18151 c_parser_skip_to_pragma_eol (parser, false);
18152 return NULL_TREE;
18153 }
18154 else if (cclauses == NULL && strcmp (p, "sections") == 0)
18155 {
18156 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18157 cclauses = cclauses_buf;
18158
18159 c_parser_consume_token (parser);
18160 block = c_begin_omp_parallel ();
18161 c_parser_omp_sections (loc, parser, p_name, mask, cclauses);
18162 stmt = c_finish_omp_parallel (loc,
18163 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
18164 block);
18165 OMP_PARALLEL_COMBINED (stmt) = 1;
18166 return stmt;
18167 }
18168 }
18169 else if (!flag_openmp) /* flag_openmp_simd */
18170 {
18171 c_parser_skip_to_pragma_eol (parser, false);
18172 return NULL_TREE;
18173 }
18174
18175 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
18176 if (cclauses)
18177 {
18178 omp_split_clauses (loc, OMP_PARALLEL, mask, clauses, cclauses);
18179 clauses = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
18180 }
18181
18182 block = c_begin_omp_parallel ();
18183 c_parser_statement (parser, if_p);
18184 stmt = c_finish_omp_parallel (loc, clauses, block);
18185
18186 return stmt;
18187 }
18188
18189 /* OpenMP 2.5:
18190 # pragma omp single single-clause[optseq] new-line
18191 structured-block
18192
18193 LOC is the location of the #pragma.
18194 */
18195
18196 #define OMP_SINGLE_CLAUSE_MASK \
18197 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18198 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18199 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
18200 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
18201
18202 static tree
18203 c_parser_omp_single (location_t loc, c_parser *parser, bool *if_p)
18204 {
18205 tree stmt = make_node (OMP_SINGLE);
18206 SET_EXPR_LOCATION (stmt, loc);
18207 TREE_TYPE (stmt) = void_type_node;
18208
18209 OMP_SINGLE_CLAUSES (stmt)
18210 = c_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK,
18211 "#pragma omp single");
18212 OMP_SINGLE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
18213
18214 return add_stmt (stmt);
18215 }
18216
18217 /* OpenMP 3.0:
18218 # pragma omp task task-clause[optseq] new-line
18219
18220 LOC is the location of the #pragma.
18221 */
18222
18223 #define OMP_TASK_CLAUSE_MASK \
18224 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
18225 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
18226 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
18227 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18228 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18229 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
18230 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
18231 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
18232 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
18233 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
18234 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
18235
18236 static tree
18237 c_parser_omp_task (location_t loc, c_parser *parser, bool *if_p)
18238 {
18239 tree clauses, block;
18240
18241 clauses = c_parser_omp_all_clauses (parser, OMP_TASK_CLAUSE_MASK,
18242 "#pragma omp task");
18243
18244 block = c_begin_omp_task ();
18245 c_parser_statement (parser, if_p);
18246 return c_finish_omp_task (loc, clauses, block);
18247 }
18248
18249 /* OpenMP 3.0:
18250 # pragma omp taskwait new-line
18251
18252 OpenMP 5.0:
18253 # pragma omp taskwait taskwait-clause[optseq] new-line
18254 */
18255
18256 #define OMP_TASKWAIT_CLAUSE_MASK \
18257 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
18258
18259 static void
18260 c_parser_omp_taskwait (c_parser *parser)
18261 {
18262 location_t loc = c_parser_peek_token (parser)->location;
18263 c_parser_consume_pragma (parser);
18264
18265 tree clauses
18266 = c_parser_omp_all_clauses (parser, OMP_TASKWAIT_CLAUSE_MASK,
18267 "#pragma omp taskwait");
18268
18269 if (clauses)
18270 {
18271 tree stmt = make_node (OMP_TASK);
18272 TREE_TYPE (stmt) = void_node;
18273 OMP_TASK_CLAUSES (stmt) = clauses;
18274 OMP_TASK_BODY (stmt) = NULL_TREE;
18275 SET_EXPR_LOCATION (stmt, loc);
18276 add_stmt (stmt);
18277 }
18278 else
18279 c_finish_omp_taskwait (loc);
18280 }
18281
18282 /* OpenMP 3.1:
18283 # pragma omp taskyield new-line
18284 */
18285
18286 static void
18287 c_parser_omp_taskyield (c_parser *parser)
18288 {
18289 location_t loc = c_parser_peek_token (parser)->location;
18290 c_parser_consume_pragma (parser);
18291 c_parser_skip_to_pragma_eol (parser);
18292
18293 c_finish_omp_taskyield (loc);
18294 }
18295
18296 /* OpenMP 4.0:
18297 # pragma omp taskgroup new-line
18298
18299 OpenMP 5.0:
18300 # pragma omp taskgroup taskgroup-clause[optseq] new-line
18301 */
18302
18303 #define OMP_TASKGROUP_CLAUSE_MASK \
18304 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
18305
18306 static tree
18307 c_parser_omp_taskgroup (location_t loc, c_parser *parser, bool *if_p)
18308 {
18309 tree clauses = c_parser_omp_all_clauses (parser, OMP_TASKGROUP_CLAUSE_MASK,
18310 "#pragma omp taskgroup");
18311
18312 tree body = c_parser_omp_structured_block (parser, if_p);
18313 return c_finish_omp_taskgroup (loc, body, clauses);
18314 }
18315
18316 /* OpenMP 4.0:
18317 # pragma omp cancel cancel-clause[optseq] new-line
18318
18319 LOC is the location of the #pragma.
18320 */
18321
18322 #define OMP_CANCEL_CLAUSE_MASK \
18323 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
18324 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
18325 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
18326 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
18327 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
18328
18329 static void
18330 c_parser_omp_cancel (c_parser *parser)
18331 {
18332 location_t loc = c_parser_peek_token (parser)->location;
18333
18334 c_parser_consume_pragma (parser);
18335 tree clauses = c_parser_omp_all_clauses (parser, OMP_CANCEL_CLAUSE_MASK,
18336 "#pragma omp cancel");
18337
18338 c_finish_omp_cancel (loc, clauses);
18339 }
18340
18341 /* OpenMP 4.0:
18342 # pragma omp cancellation point cancelpt-clause[optseq] new-line
18343
18344 LOC is the location of the #pragma.
18345 */
18346
18347 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \
18348 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
18349 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
18350 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
18351 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
18352
18353 static void
18354 c_parser_omp_cancellation_point (c_parser *parser, enum pragma_context context)
18355 {
18356 location_t loc = c_parser_peek_token (parser)->location;
18357 tree clauses;
18358 bool point_seen = false;
18359
18360 c_parser_consume_pragma (parser);
18361 if (c_parser_next_token_is (parser, CPP_NAME))
18362 {
18363 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18364 if (strcmp (p, "point") == 0)
18365 {
18366 c_parser_consume_token (parser);
18367 point_seen = true;
18368 }
18369 }
18370 if (!point_seen)
18371 {
18372 c_parser_error (parser, "expected %<point%>");
18373 c_parser_skip_to_pragma_eol (parser);
18374 return;
18375 }
18376
18377 if (context != pragma_compound)
18378 {
18379 if (context == pragma_stmt)
18380 error_at (loc,
18381 "%<#pragma %s%> may only be used in compound statements",
18382 "omp cancellation point");
18383 else
18384 c_parser_error (parser, "expected declaration specifiers");
18385 c_parser_skip_to_pragma_eol (parser, false);
18386 return;
18387 }
18388
18389 clauses
18390 = c_parser_omp_all_clauses (parser, OMP_CANCELLATION_POINT_CLAUSE_MASK,
18391 "#pragma omp cancellation point");
18392
18393 c_finish_omp_cancellation_point (loc, clauses);
18394 }
18395
18396 /* OpenMP 4.0:
18397 #pragma omp distribute distribute-clause[optseq] new-line
18398 for-loop */
18399
18400 #define OMP_DISTRIBUTE_CLAUSE_MASK \
18401 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18402 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18403 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
18404 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
18405 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE))
18406
18407 static tree
18408 c_parser_omp_distribute (location_t loc, c_parser *parser,
18409 char *p_name, omp_clause_mask mask, tree *cclauses,
18410 bool *if_p)
18411 {
18412 tree clauses, block, ret;
18413
18414 strcat (p_name, " distribute");
18415 mask |= OMP_DISTRIBUTE_CLAUSE_MASK;
18416
18417 if (c_parser_next_token_is (parser, CPP_NAME))
18418 {
18419 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18420 bool simd = false;
18421 bool parallel = false;
18422
18423 if (strcmp (p, "simd") == 0)
18424 simd = true;
18425 else
18426 parallel = strcmp (p, "parallel") == 0;
18427 if (parallel || simd)
18428 {
18429 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18430 if (cclauses == NULL)
18431 cclauses = cclauses_buf;
18432 c_parser_consume_token (parser);
18433 if (!flag_openmp) /* flag_openmp_simd */
18434 {
18435 if (simd)
18436 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
18437 if_p);
18438 else
18439 return c_parser_omp_parallel (loc, parser, p_name, mask,
18440 cclauses, if_p);
18441 }
18442 block = c_begin_compound_stmt (true);
18443 if (simd)
18444 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
18445 if_p);
18446 else
18447 ret = c_parser_omp_parallel (loc, parser, p_name, mask, cclauses,
18448 if_p);
18449 block = c_end_compound_stmt (loc, block, true);
18450 if (ret == NULL)
18451 return ret;
18452 ret = make_node (OMP_DISTRIBUTE);
18453 TREE_TYPE (ret) = void_type_node;
18454 OMP_FOR_BODY (ret) = block;
18455 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
18456 SET_EXPR_LOCATION (ret, loc);
18457 add_stmt (ret);
18458 return ret;
18459 }
18460 }
18461 if (!flag_openmp) /* flag_openmp_simd */
18462 {
18463 c_parser_skip_to_pragma_eol (parser, false);
18464 return NULL_TREE;
18465 }
18466
18467 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
18468 if (cclauses)
18469 {
18470 omp_split_clauses (loc, OMP_DISTRIBUTE, mask, clauses, cclauses);
18471 clauses = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
18472 }
18473
18474 block = c_begin_compound_stmt (true);
18475 ret = c_parser_omp_for_loop (loc, parser, OMP_DISTRIBUTE, clauses, NULL,
18476 if_p);
18477 block = c_end_compound_stmt (loc, block, true);
18478 add_stmt (block);
18479
18480 return ret;
18481 }
18482
18483 /* OpenMP 4.0:
18484 # pragma omp teams teams-clause[optseq] new-line
18485 structured-block */
18486
18487 #define OMP_TEAMS_CLAUSE_MASK \
18488 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18489 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18490 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
18491 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
18492 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
18493 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
18494 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
18495
18496 static tree
18497 c_parser_omp_teams (location_t loc, c_parser *parser,
18498 char *p_name, omp_clause_mask mask, tree *cclauses,
18499 bool *if_p)
18500 {
18501 tree clauses, block, ret;
18502
18503 strcat (p_name, " teams");
18504 mask |= OMP_TEAMS_CLAUSE_MASK;
18505
18506 if (c_parser_next_token_is (parser, CPP_NAME))
18507 {
18508 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18509 if (strcmp (p, "distribute") == 0)
18510 {
18511 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18512 if (cclauses == NULL)
18513 cclauses = cclauses_buf;
18514
18515 c_parser_consume_token (parser);
18516 if (!flag_openmp) /* flag_openmp_simd */
18517 return c_parser_omp_distribute (loc, parser, p_name, mask,
18518 cclauses, if_p);
18519 block = c_begin_omp_parallel ();
18520 ret = c_parser_omp_distribute (loc, parser, p_name, mask, cclauses,
18521 if_p);
18522 block = c_end_compound_stmt (loc, block, true);
18523 if (ret == NULL)
18524 return ret;
18525 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
18526 ret = make_node (OMP_TEAMS);
18527 TREE_TYPE (ret) = void_type_node;
18528 OMP_TEAMS_CLAUSES (ret) = clauses;
18529 OMP_TEAMS_BODY (ret) = block;
18530 OMP_TEAMS_COMBINED (ret) = 1;
18531 SET_EXPR_LOCATION (ret, loc);
18532 return add_stmt (ret);
18533 }
18534 else if (strcmp (p, "loop") == 0)
18535 {
18536 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
18537 if (cclauses == NULL)
18538 cclauses = cclauses_buf;
18539
18540 c_parser_consume_token (parser);
18541 if (!flag_openmp) /* flag_openmp_simd */
18542 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
18543 if_p);
18544 block = c_begin_omp_parallel ();
18545 ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses, if_p);
18546 block = c_end_compound_stmt (loc, block, true);
18547 if (ret == NULL)
18548 return ret;
18549 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
18550 ret = make_node (OMP_TEAMS);
18551 TREE_TYPE (ret) = void_type_node;
18552 OMP_TEAMS_CLAUSES (ret) = clauses;
18553 OMP_TEAMS_BODY (ret) = block;
18554 OMP_TEAMS_COMBINED (ret) = 1;
18555 SET_EXPR_LOCATION (ret, loc);
18556 return add_stmt (ret);
18557 }
18558 }
18559 if (!flag_openmp) /* flag_openmp_simd */
18560 {
18561 c_parser_skip_to_pragma_eol (parser, false);
18562 return NULL_TREE;
18563 }
18564
18565 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
18566 if (cclauses)
18567 {
18568 omp_split_clauses (loc, OMP_TEAMS, mask, clauses, cclauses);
18569 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
18570 }
18571
18572 tree stmt = make_node (OMP_TEAMS);
18573 TREE_TYPE (stmt) = void_type_node;
18574 OMP_TEAMS_CLAUSES (stmt) = clauses;
18575 block = c_begin_omp_parallel ();
18576 add_stmt (c_parser_omp_structured_block (parser, if_p));
18577 OMP_TEAMS_BODY (stmt) = c_end_compound_stmt (loc, block, true);
18578 SET_EXPR_LOCATION (stmt, loc);
18579
18580 return add_stmt (stmt);
18581 }
18582
18583 /* OpenMP 4.0:
18584 # pragma omp target data target-data-clause[optseq] new-line
18585 structured-block */
18586
18587 #define OMP_TARGET_DATA_CLAUSE_MASK \
18588 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
18589 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
18590 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
18591 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
18592 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
18593
18594 static tree
18595 c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p)
18596 {
18597 tree clauses
18598 = c_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
18599 "#pragma omp target data");
18600 int map_seen = 0;
18601 for (tree *pc = &clauses; *pc;)
18602 {
18603 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
18604 switch (OMP_CLAUSE_MAP_KIND (*pc))
18605 {
18606 case GOMP_MAP_TO:
18607 case GOMP_MAP_ALWAYS_TO:
18608 case GOMP_MAP_FROM:
18609 case GOMP_MAP_ALWAYS_FROM:
18610 case GOMP_MAP_TOFROM:
18611 case GOMP_MAP_ALWAYS_TOFROM:
18612 case GOMP_MAP_ALLOC:
18613 map_seen = 3;
18614 break;
18615 case GOMP_MAP_FIRSTPRIVATE_POINTER:
18616 case GOMP_MAP_ALWAYS_POINTER:
18617 break;
18618 default:
18619 map_seen |= 1;
18620 error_at (OMP_CLAUSE_LOCATION (*pc),
18621 "%<#pragma omp target data%> with map-type other "
18622 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
18623 "on %<map%> clause");
18624 *pc = OMP_CLAUSE_CHAIN (*pc);
18625 continue;
18626 }
18627 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
18628 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
18629 map_seen = 3;
18630 pc = &OMP_CLAUSE_CHAIN (*pc);
18631 }
18632
18633 if (map_seen != 3)
18634 {
18635 if (map_seen == 0)
18636 error_at (loc,
18637 "%<#pragma omp target data%> must contain at least "
18638 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
18639 "clause");
18640 return NULL_TREE;
18641 }
18642
18643 tree stmt = make_node (OMP_TARGET_DATA);
18644 TREE_TYPE (stmt) = void_type_node;
18645 OMP_TARGET_DATA_CLAUSES (stmt) = clauses;
18646 keep_next_level ();
18647 tree block = c_begin_compound_stmt (true);
18648 add_stmt (c_parser_omp_structured_block (parser, if_p));
18649 OMP_TARGET_DATA_BODY (stmt) = c_end_compound_stmt (loc, block, true);
18650
18651 SET_EXPR_LOCATION (stmt, loc);
18652 return add_stmt (stmt);
18653 }
18654
18655 /* OpenMP 4.0:
18656 # pragma omp target update target-update-clause[optseq] new-line */
18657
18658 #define OMP_TARGET_UPDATE_CLAUSE_MASK \
18659 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
18660 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
18661 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
18662 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
18663 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
18664 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
18665
18666 static bool
18667 c_parser_omp_target_update (location_t loc, c_parser *parser,
18668 enum pragma_context context)
18669 {
18670 if (context == pragma_stmt)
18671 {
18672 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
18673 "omp target update");
18674 c_parser_skip_to_pragma_eol (parser, false);
18675 return false;
18676 }
18677
18678 tree clauses
18679 = c_parser_omp_all_clauses (parser, OMP_TARGET_UPDATE_CLAUSE_MASK,
18680 "#pragma omp target update");
18681 if (omp_find_clause (clauses, OMP_CLAUSE_TO) == NULL_TREE
18682 && omp_find_clause (clauses, OMP_CLAUSE_FROM) == NULL_TREE)
18683 {
18684 error_at (loc,
18685 "%<#pragma omp target update%> must contain at least one "
18686 "%<from%> or %<to%> clauses");
18687 return false;
18688 }
18689
18690 tree stmt = make_node (OMP_TARGET_UPDATE);
18691 TREE_TYPE (stmt) = void_type_node;
18692 OMP_TARGET_UPDATE_CLAUSES (stmt) = clauses;
18693 SET_EXPR_LOCATION (stmt, loc);
18694 add_stmt (stmt);
18695 return false;
18696 }
18697
18698 /* OpenMP 4.5:
18699 # pragma omp target enter data target-data-clause[optseq] new-line */
18700
18701 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
18702 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
18703 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
18704 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
18705 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
18706 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
18707
18708 static tree
18709 c_parser_omp_target_enter_data (location_t loc, c_parser *parser,
18710 enum pragma_context context)
18711 {
18712 bool data_seen = false;
18713 if (c_parser_next_token_is (parser, CPP_NAME))
18714 {
18715 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18716 if (strcmp (p, "data") == 0)
18717 {
18718 c_parser_consume_token (parser);
18719 data_seen = true;
18720 }
18721 }
18722 if (!data_seen)
18723 {
18724 c_parser_error (parser, "expected %<data%>");
18725 c_parser_skip_to_pragma_eol (parser);
18726 return NULL_TREE;
18727 }
18728
18729 if (context == pragma_stmt)
18730 {
18731 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
18732 "omp target enter data");
18733 c_parser_skip_to_pragma_eol (parser, false);
18734 return NULL_TREE;
18735 }
18736
18737 tree clauses
18738 = c_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK,
18739 "#pragma omp target enter data");
18740 int map_seen = 0;
18741 for (tree *pc = &clauses; *pc;)
18742 {
18743 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
18744 switch (OMP_CLAUSE_MAP_KIND (*pc))
18745 {
18746 case GOMP_MAP_TO:
18747 case GOMP_MAP_ALWAYS_TO:
18748 case GOMP_MAP_ALLOC:
18749 map_seen = 3;
18750 break;
18751 case GOMP_MAP_FIRSTPRIVATE_POINTER:
18752 case GOMP_MAP_ALWAYS_POINTER:
18753 break;
18754 default:
18755 map_seen |= 1;
18756 error_at (OMP_CLAUSE_LOCATION (*pc),
18757 "%<#pragma omp target enter data%> with map-type other "
18758 "than %<to%> or %<alloc%> on %<map%> clause");
18759 *pc = OMP_CLAUSE_CHAIN (*pc);
18760 continue;
18761 }
18762 pc = &OMP_CLAUSE_CHAIN (*pc);
18763 }
18764
18765 if (map_seen != 3)
18766 {
18767 if (map_seen == 0)
18768 error_at (loc,
18769 "%<#pragma omp target enter data%> must contain at least "
18770 "one %<map%> clause");
18771 return NULL_TREE;
18772 }
18773
18774 tree stmt = make_node (OMP_TARGET_ENTER_DATA);
18775 TREE_TYPE (stmt) = void_type_node;
18776 OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses;
18777 SET_EXPR_LOCATION (stmt, loc);
18778 add_stmt (stmt);
18779 return stmt;
18780 }
18781
18782 /* OpenMP 4.5:
18783 # pragma omp target exit data target-data-clause[optseq] new-line */
18784
18785 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
18786 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
18787 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
18788 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
18789 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
18790 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
18791
18792 static tree
18793 c_parser_omp_target_exit_data (location_t loc, c_parser *parser,
18794 enum pragma_context context)
18795 {
18796 bool data_seen = false;
18797 if (c_parser_next_token_is (parser, CPP_NAME))
18798 {
18799 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18800 if (strcmp (p, "data") == 0)
18801 {
18802 c_parser_consume_token (parser);
18803 data_seen = true;
18804 }
18805 }
18806 if (!data_seen)
18807 {
18808 c_parser_error (parser, "expected %<data%>");
18809 c_parser_skip_to_pragma_eol (parser);
18810 return NULL_TREE;
18811 }
18812
18813 if (context == pragma_stmt)
18814 {
18815 error_at (loc, "%<#pragma %s%> may only be used in compound statements",
18816 "omp target exit data");
18817 c_parser_skip_to_pragma_eol (parser, false);
18818 return NULL_TREE;
18819 }
18820
18821 tree clauses
18822 = c_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK,
18823 "#pragma omp target exit data");
18824
18825 int map_seen = 0;
18826 for (tree *pc = &clauses; *pc;)
18827 {
18828 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
18829 switch (OMP_CLAUSE_MAP_KIND (*pc))
18830 {
18831 case GOMP_MAP_FROM:
18832 case GOMP_MAP_ALWAYS_FROM:
18833 case GOMP_MAP_RELEASE:
18834 case GOMP_MAP_DELETE:
18835 map_seen = 3;
18836 break;
18837 case GOMP_MAP_FIRSTPRIVATE_POINTER:
18838 case GOMP_MAP_ALWAYS_POINTER:
18839 break;
18840 default:
18841 map_seen |= 1;
18842 error_at (OMP_CLAUSE_LOCATION (*pc),
18843 "%<#pragma omp target exit data%> with map-type other "
18844 "than %<from%>, %<release%> or %<delete%> on %<map%>"
18845 " clause");
18846 *pc = OMP_CLAUSE_CHAIN (*pc);
18847 continue;
18848 }
18849 pc = &OMP_CLAUSE_CHAIN (*pc);
18850 }
18851
18852 if (map_seen != 3)
18853 {
18854 if (map_seen == 0)
18855 error_at (loc,
18856 "%<#pragma omp target exit data%> must contain at least one "
18857 "%<map%> clause");
18858 return NULL_TREE;
18859 }
18860
18861 tree stmt = make_node (OMP_TARGET_EXIT_DATA);
18862 TREE_TYPE (stmt) = void_type_node;
18863 OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses;
18864 SET_EXPR_LOCATION (stmt, loc);
18865 add_stmt (stmt);
18866 return stmt;
18867 }
18868
18869 /* OpenMP 4.0:
18870 # pragma omp target target-clause[optseq] new-line
18871 structured-block */
18872
18873 #define OMP_TARGET_CLAUSE_MASK \
18874 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
18875 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
18876 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
18877 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
18878 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
18879 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
18880 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
18881 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
18882 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR))
18883
18884 static bool
18885 c_parser_omp_target (c_parser *parser, enum pragma_context context, bool *if_p)
18886 {
18887 location_t loc = c_parser_peek_token (parser)->location;
18888 c_parser_consume_pragma (parser);
18889 tree *pc = NULL, stmt, block;
18890
18891 if (context != pragma_stmt && context != pragma_compound)
18892 {
18893 c_parser_error (parser, "expected declaration specifiers");
18894 c_parser_skip_to_pragma_eol (parser);
18895 return false;
18896 }
18897
18898 if (flag_openmp)
18899 omp_requires_mask
18900 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
18901
18902 if (c_parser_next_token_is (parser, CPP_NAME))
18903 {
18904 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
18905 enum tree_code ccode = ERROR_MARK;
18906
18907 if (strcmp (p, "teams") == 0)
18908 ccode = OMP_TEAMS;
18909 else if (strcmp (p, "parallel") == 0)
18910 ccode = OMP_PARALLEL;
18911 else if (strcmp (p, "simd") == 0)
18912 ccode = OMP_SIMD;
18913 if (ccode != ERROR_MARK)
18914 {
18915 tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT];
18916 char p_name[sizeof ("#pragma omp target teams distribute "
18917 "parallel for simd")];
18918
18919 c_parser_consume_token (parser);
18920 strcpy (p_name, "#pragma omp target");
18921 if (!flag_openmp) /* flag_openmp_simd */
18922 {
18923 tree stmt;
18924 switch (ccode)
18925 {
18926 case OMP_TEAMS:
18927 stmt = c_parser_omp_teams (loc, parser, p_name,
18928 OMP_TARGET_CLAUSE_MASK,
18929 cclauses, if_p);
18930 break;
18931 case OMP_PARALLEL:
18932 stmt = c_parser_omp_parallel (loc, parser, p_name,
18933 OMP_TARGET_CLAUSE_MASK,
18934 cclauses, if_p);
18935 break;
18936 case OMP_SIMD:
18937 stmt = c_parser_omp_simd (loc, parser, p_name,
18938 OMP_TARGET_CLAUSE_MASK,
18939 cclauses, if_p);
18940 break;
18941 default:
18942 gcc_unreachable ();
18943 }
18944 return stmt != NULL_TREE;
18945 }
18946 keep_next_level ();
18947 tree block = c_begin_compound_stmt (true), ret;
18948 switch (ccode)
18949 {
18950 case OMP_TEAMS:
18951 ret = c_parser_omp_teams (loc, parser, p_name,
18952 OMP_TARGET_CLAUSE_MASK, cclauses,
18953 if_p);
18954 break;
18955 case OMP_PARALLEL:
18956 ret = c_parser_omp_parallel (loc, parser, p_name,
18957 OMP_TARGET_CLAUSE_MASK, cclauses,
18958 if_p);
18959 break;
18960 case OMP_SIMD:
18961 ret = c_parser_omp_simd (loc, parser, p_name,
18962 OMP_TARGET_CLAUSE_MASK, cclauses,
18963 if_p);
18964 break;
18965 default:
18966 gcc_unreachable ();
18967 }
18968 block = c_end_compound_stmt (loc, block, true);
18969 if (ret == NULL_TREE)
18970 return false;
18971 if (ccode == OMP_TEAMS)
18972 {
18973 /* For combined target teams, ensure the num_teams and
18974 thread_limit clause expressions are evaluated on the host,
18975 before entering the target construct. */
18976 tree c;
18977 for (c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
18978 c; c = OMP_CLAUSE_CHAIN (c))
18979 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
18980 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
18981 && TREE_CODE (OMP_CLAUSE_OPERAND (c, 0)) != INTEGER_CST)
18982 {
18983 tree expr = OMP_CLAUSE_OPERAND (c, 0);
18984 tree tmp = create_tmp_var_raw (TREE_TYPE (expr));
18985 expr = build4 (TARGET_EXPR, TREE_TYPE (expr), tmp,
18986 expr, NULL_TREE, NULL_TREE);
18987 add_stmt (expr);
18988 OMP_CLAUSE_OPERAND (c, 0) = expr;
18989 tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
18990 OMP_CLAUSE_FIRSTPRIVATE);
18991 OMP_CLAUSE_DECL (tc) = tmp;
18992 OMP_CLAUSE_CHAIN (tc)
18993 = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
18994 cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc;
18995 }
18996 }
18997 tree stmt = make_node (OMP_TARGET);
18998 TREE_TYPE (stmt) = void_type_node;
18999 OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
19000 OMP_TARGET_BODY (stmt) = block;
19001 OMP_TARGET_COMBINED (stmt) = 1;
19002 SET_EXPR_LOCATION (stmt, loc);
19003 add_stmt (stmt);
19004 pc = &OMP_TARGET_CLAUSES (stmt);
19005 goto check_clauses;
19006 }
19007 else if (!flag_openmp) /* flag_openmp_simd */
19008 {
19009 c_parser_skip_to_pragma_eol (parser, false);
19010 return false;
19011 }
19012 else if (strcmp (p, "data") == 0)
19013 {
19014 c_parser_consume_token (parser);
19015 c_parser_omp_target_data (loc, parser, if_p);
19016 return true;
19017 }
19018 else if (strcmp (p, "enter") == 0)
19019 {
19020 c_parser_consume_token (parser);
19021 c_parser_omp_target_enter_data (loc, parser, context);
19022 return false;
19023 }
19024 else if (strcmp (p, "exit") == 0)
19025 {
19026 c_parser_consume_token (parser);
19027 c_parser_omp_target_exit_data (loc, parser, context);
19028 return false;
19029 }
19030 else if (strcmp (p, "update") == 0)
19031 {
19032 c_parser_consume_token (parser);
19033 return c_parser_omp_target_update (loc, parser, context);
19034 }
19035 }
19036 if (!flag_openmp) /* flag_openmp_simd */
19037 {
19038 c_parser_skip_to_pragma_eol (parser, false);
19039 return false;
19040 }
19041
19042 stmt = make_node (OMP_TARGET);
19043 TREE_TYPE (stmt) = void_type_node;
19044
19045 OMP_TARGET_CLAUSES (stmt)
19046 = c_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK,
19047 "#pragma omp target");
19048 pc = &OMP_TARGET_CLAUSES (stmt);
19049 keep_next_level ();
19050 block = c_begin_compound_stmt (true);
19051 add_stmt (c_parser_omp_structured_block (parser, if_p));
19052 OMP_TARGET_BODY (stmt) = c_end_compound_stmt (loc, block, true);
19053
19054 SET_EXPR_LOCATION (stmt, loc);
19055 add_stmt (stmt);
19056
19057 check_clauses:
19058 while (*pc)
19059 {
19060 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
19061 switch (OMP_CLAUSE_MAP_KIND (*pc))
19062 {
19063 case GOMP_MAP_TO:
19064 case GOMP_MAP_ALWAYS_TO:
19065 case GOMP_MAP_FROM:
19066 case GOMP_MAP_ALWAYS_FROM:
19067 case GOMP_MAP_TOFROM:
19068 case GOMP_MAP_ALWAYS_TOFROM:
19069 case GOMP_MAP_ALLOC:
19070 case GOMP_MAP_FIRSTPRIVATE_POINTER:
19071 case GOMP_MAP_ALWAYS_POINTER:
19072 break;
19073 default:
19074 error_at (OMP_CLAUSE_LOCATION (*pc),
19075 "%<#pragma omp target%> with map-type other "
19076 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
19077 "on %<map%> clause");
19078 *pc = OMP_CLAUSE_CHAIN (*pc);
19079 continue;
19080 }
19081 pc = &OMP_CLAUSE_CHAIN (*pc);
19082 }
19083 return true;
19084 }
19085
19086 /* OpenMP 4.0:
19087 # pragma omp declare simd declare-simd-clauses[optseq] new-line
19088
19089 OpenMP 5.0:
19090 # pragma omp declare variant (identifier) match(context-selector) new-line
19091 */
19092
19093 #define OMP_DECLARE_SIMD_CLAUSE_MASK \
19094 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
19095 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
19096 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
19097 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
19098 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
19099 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
19100
19101 static void
19102 c_parser_omp_declare_simd (c_parser *parser, enum pragma_context context)
19103 {
19104 c_token *token = c_parser_peek_token (parser);
19105 gcc_assert (token->type == CPP_NAME);
19106 tree kind = token->value;
19107 gcc_assert (strcmp (IDENTIFIER_POINTER (kind), "simd") == 0
19108 || strcmp (IDENTIFIER_POINTER (kind), "variant") == 0);
19109
19110 auto_vec<c_token> clauses;
19111 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
19112 {
19113 c_token *token = c_parser_peek_token (parser);
19114 if (token->type == CPP_EOF)
19115 {
19116 c_parser_skip_to_pragma_eol (parser);
19117 return;
19118 }
19119 clauses.safe_push (*token);
19120 c_parser_consume_token (parser);
19121 }
19122 clauses.safe_push (*c_parser_peek_token (parser));
19123 c_parser_skip_to_pragma_eol (parser);
19124
19125 while (c_parser_next_token_is (parser, CPP_PRAGMA))
19126 {
19127 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_DECLARE
19128 || c_parser_peek_2nd_token (parser)->type != CPP_NAME
19129 || c_parser_peek_2nd_token (parser)->value != kind)
19130 {
19131 error ("%<#pragma omp declare %s%> must be followed by "
19132 "function declaration or definition or another "
19133 "%<#pragma omp declare %s%>",
19134 IDENTIFIER_POINTER (kind), IDENTIFIER_POINTER (kind));
19135 return;
19136 }
19137 c_parser_consume_pragma (parser);
19138 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
19139 {
19140 c_token *token = c_parser_peek_token (parser);
19141 if (token->type == CPP_EOF)
19142 {
19143 c_parser_skip_to_pragma_eol (parser);
19144 return;
19145 }
19146 clauses.safe_push (*token);
19147 c_parser_consume_token (parser);
19148 }
19149 clauses.safe_push (*c_parser_peek_token (parser));
19150 c_parser_skip_to_pragma_eol (parser);
19151 }
19152
19153 /* Make sure nothing tries to read past the end of the tokens. */
19154 c_token eof_token;
19155 memset (&eof_token, 0, sizeof (eof_token));
19156 eof_token.type = CPP_EOF;
19157 clauses.safe_push (eof_token);
19158 clauses.safe_push (eof_token);
19159
19160 switch (context)
19161 {
19162 case pragma_external:
19163 if (c_parser_next_token_is (parser, CPP_KEYWORD)
19164 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
19165 {
19166 int ext = disable_extension_diagnostics ();
19167 do
19168 c_parser_consume_token (parser);
19169 while (c_parser_next_token_is (parser, CPP_KEYWORD)
19170 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
19171 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
19172 NULL, clauses);
19173 restore_extension_diagnostics (ext);
19174 }
19175 else
19176 c_parser_declaration_or_fndef (parser, true, true, true, false, true,
19177 NULL, clauses);
19178 break;
19179 case pragma_struct:
19180 case pragma_param:
19181 case pragma_stmt:
19182 error ("%<#pragma omp declare %s%> must be followed by "
19183 "function declaration or definition",
19184 IDENTIFIER_POINTER (kind));
19185 break;
19186 case pragma_compound:
19187 if (c_parser_next_token_is (parser, CPP_KEYWORD)
19188 && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
19189 {
19190 int ext = disable_extension_diagnostics ();
19191 do
19192 c_parser_consume_token (parser);
19193 while (c_parser_next_token_is (parser, CPP_KEYWORD)
19194 && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
19195 if (c_parser_next_tokens_start_declaration (parser))
19196 {
19197 c_parser_declaration_or_fndef (parser, true, true, true, true,
19198 true, NULL, clauses);
19199 restore_extension_diagnostics (ext);
19200 break;
19201 }
19202 restore_extension_diagnostics (ext);
19203 }
19204 else if (c_parser_next_tokens_start_declaration (parser))
19205 {
19206 c_parser_declaration_or_fndef (parser, true, true, true, true, true,
19207 NULL, clauses);
19208 break;
19209 }
19210 error ("%<#pragma omp declare %s%> must be followed by "
19211 "function declaration or definition",
19212 IDENTIFIER_POINTER (kind));
19213 break;
19214 default:
19215 gcc_unreachable ();
19216 }
19217 }
19218
19219 static const char *const omp_construct_selectors[] = {
19220 "simd", "target", "teams", "parallel", "for", NULL };
19221 static const char *const omp_device_selectors[] = {
19222 "kind", "isa", "arch", NULL };
19223 static const char *const omp_implementation_selectors[] = {
19224 "vendor", "extension", "atomic_default_mem_order", "unified_address",
19225 "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL };
19226 static const char *const omp_user_selectors[] = {
19227 "condition", NULL };
19228
19229 /* OpenMP 5.0:
19230
19231 trait-selector:
19232 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
19233
19234 trait-score:
19235 score(score-expression) */
19236
19237 static tree
19238 c_parser_omp_context_selector (c_parser *parser, tree set, tree parms)
19239 {
19240 tree ret = NULL_TREE;
19241 do
19242 {
19243 tree selector;
19244 if (c_parser_next_token_is (parser, CPP_KEYWORD)
19245 || c_parser_next_token_is (parser, CPP_NAME))
19246 selector = c_parser_peek_token (parser)->value;
19247 else
19248 {
19249 c_parser_error (parser, "expected trait selector name");
19250 return error_mark_node;
19251 }
19252
19253 tree properties = NULL_TREE;
19254 const char *const *selectors = NULL;
19255 bool allow_score = true;
19256 bool allow_user = false;
19257 int property_limit = 0;
19258 enum { CTX_PROPERTY_NONE, CTX_PROPERTY_USER, CTX_PROPERTY_IDLIST,
19259 CTX_PROPERTY_EXPR, CTX_PROPERTY_SIMD } property_kind
19260 = CTX_PROPERTY_NONE;
19261 switch (IDENTIFIER_POINTER (set)[0])
19262 {
19263 case 'c': /* construct */
19264 selectors = omp_construct_selectors;
19265 allow_score = false;
19266 property_limit = 1;
19267 property_kind = CTX_PROPERTY_SIMD;
19268 break;
19269 case 'd': /* device */
19270 selectors = omp_device_selectors;
19271 allow_score = false;
19272 allow_user = true;
19273 property_limit = 3;
19274 property_kind = CTX_PROPERTY_IDLIST;
19275 break;
19276 case 'i': /* implementation */
19277 selectors = omp_implementation_selectors;
19278 allow_user = true;
19279 property_limit = 3;
19280 property_kind = CTX_PROPERTY_IDLIST;
19281 break;
19282 case 'u': /* user */
19283 selectors = omp_user_selectors;
19284 property_limit = 1;
19285 property_kind = CTX_PROPERTY_EXPR;
19286 break;
19287 default:
19288 gcc_unreachable ();
19289 }
19290 for (int i = 0; ; i++)
19291 {
19292 if (selectors[i] == NULL)
19293 {
19294 if (allow_user)
19295 {
19296 property_kind = CTX_PROPERTY_USER;
19297 break;
19298 }
19299 else
19300 {
19301 error_at (c_parser_peek_token (parser)->location,
19302 "selector %qs not allowed for context selector "
19303 "set %qs", IDENTIFIER_POINTER (selector),
19304 IDENTIFIER_POINTER (set));
19305 c_parser_consume_token (parser);
19306 return error_mark_node;
19307 }
19308 }
19309 if (i == property_limit)
19310 property_kind = CTX_PROPERTY_NONE;
19311 if (strcmp (selectors[i], IDENTIFIER_POINTER (selector)) == 0)
19312 break;
19313 }
19314
19315 c_parser_consume_token (parser);
19316
19317 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
19318 {
19319 if (property_kind == CTX_PROPERTY_NONE)
19320 {
19321 error_at (c_parser_peek_token (parser)->location,
19322 "selector %qs does not accept any properties",
19323 IDENTIFIER_POINTER (selector));
19324 return error_mark_node;
19325 }
19326
19327 matching_parens parens;
19328 parens.require_open (parser);
19329
19330 c_token *token = c_parser_peek_token (parser);
19331 if (allow_score
19332 && c_parser_next_token_is (parser, CPP_NAME)
19333 && strcmp (IDENTIFIER_POINTER (token->value), "score") == 0
19334 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
19335 {
19336 c_parser_consume_token (parser);
19337
19338 matching_parens parens2;
19339 parens2.require_open (parser);
19340 tree score = c_parser_expr_no_commas (parser, NULL).value;
19341 parens2.skip_until_found_close (parser);
19342 c_parser_require (parser, CPP_COLON, "expected %<:%>");
19343 if (score != error_mark_node)
19344 {
19345 mark_exp_read (score);
19346 score = c_fully_fold (score, false, NULL);
19347 if (!INTEGRAL_TYPE_P (TREE_TYPE (score))
19348 || !tree_fits_shwi_p (score))
19349 error_at (token->location, "score argument must be "
19350 "constant integer expression");
19351 else
19352 properties = tree_cons (get_identifier (" score"),
19353 score, properties);
19354 }
19355 token = c_parser_peek_token (parser);
19356 }
19357
19358 switch (property_kind)
19359 {
19360 tree t;
19361 case CTX_PROPERTY_USER:
19362 do
19363 {
19364 t = c_parser_expr_no_commas (parser, NULL).value;
19365 if (TREE_CODE (t) == STRING_CST)
19366 properties = tree_cons (NULL_TREE, t, properties);
19367 else if (t != error_mark_node)
19368 {
19369 mark_exp_read (t);
19370 t = c_fully_fold (t, false, NULL);
19371 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
19372 || !tree_fits_shwi_p (t))
19373 error_at (token->location, "property must be "
19374 "constant integer expression or string "
19375 "literal");
19376 else
19377 properties = tree_cons (NULL_TREE, t, properties);
19378 }
19379 else
19380 return error_mark_node;
19381
19382 if (c_parser_next_token_is (parser, CPP_COMMA))
19383 c_parser_consume_token (parser);
19384 else
19385 break;
19386 }
19387 while (1);
19388 break;
19389 case CTX_PROPERTY_IDLIST:
19390 do
19391 {
19392 tree prop;
19393 if (c_parser_next_token_is (parser, CPP_KEYWORD)
19394 || c_parser_next_token_is (parser, CPP_NAME))
19395 prop = c_parser_peek_token (parser)->value;
19396 else
19397 {
19398 c_parser_error (parser, "expected identifier");
19399 return error_mark_node;
19400 }
19401 c_parser_consume_token (parser);
19402
19403 properties = tree_cons (prop, NULL_TREE, properties);
19404
19405 if (c_parser_next_token_is (parser, CPP_COMMA))
19406 c_parser_consume_token (parser);
19407 else
19408 break;
19409 }
19410 while (1);
19411 break;
19412 case CTX_PROPERTY_EXPR:
19413 t = c_parser_expr_no_commas (parser, NULL).value;
19414 if (t != error_mark_node)
19415 {
19416 mark_exp_read (t);
19417 t = c_fully_fold (t, false, NULL);
19418 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
19419 || !tree_fits_shwi_p (t))
19420 error_at (token->location, "property must be "
19421 "constant integer expression");
19422 else
19423 properties = tree_cons (NULL_TREE, t, properties);
19424 }
19425 else
19426 return error_mark_node;
19427 break;
19428 case CTX_PROPERTY_SIMD:
19429 if (parms == NULL_TREE)
19430 {
19431 error_at (token->location, "properties for %<simd%> "
19432 "selector may not be specified in "
19433 "%<metadirective%>");
19434 return error_mark_node;
19435 }
19436 tree c;
19437 c = c_parser_omp_all_clauses (parser,
19438 OMP_DECLARE_SIMD_CLAUSE_MASK,
19439 "simd", true, 2);
19440 c = c_omp_declare_simd_clauses_to_numbers (parms
19441 == error_mark_node
19442 ? NULL_TREE : parms,
19443 c);
19444 properties = c;
19445 break;
19446 default:
19447 gcc_unreachable ();
19448 }
19449
19450 parens.skip_until_found_close (parser);
19451 properties = nreverse (properties);
19452 }
19453 else if (property_kind == CTX_PROPERTY_IDLIST
19454 || property_kind == CTX_PROPERTY_EXPR)
19455 {
19456 c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>");
19457 return error_mark_node;
19458 }
19459
19460 ret = tree_cons (selector, properties, ret);
19461
19462 if (c_parser_next_token_is (parser, CPP_COMMA))
19463 c_parser_consume_token (parser);
19464 else
19465 break;
19466 }
19467 while (1);
19468
19469 return nreverse (ret);
19470 }
19471
19472 /* OpenMP 5.0:
19473
19474 trait-set-selector[,trait-set-selector[,...]]
19475
19476 trait-set-selector:
19477 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
19478
19479 trait-set-selector-name:
19480 constructor
19481 device
19482 implementation
19483 user */
19484
19485 static tree
19486 c_parser_omp_context_selector_specification (c_parser *parser, tree parms)
19487 {
19488 tree ret = NULL_TREE;
19489 do
19490 {
19491 const char *setp = "";
19492 if (c_parser_next_token_is (parser, CPP_NAME))
19493 setp = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19494 switch (setp[0])
19495 {
19496 case 'c':
19497 if (strcmp (setp, "construct") == 0)
19498 setp = NULL;
19499 break;
19500 case 'd':
19501 if (strcmp (setp, "device") == 0)
19502 setp = NULL;
19503 break;
19504 case 'i':
19505 if (strcmp (setp, "implementation") == 0)
19506 setp = NULL;
19507 break;
19508 case 'u':
19509 if (strcmp (setp, "user") == 0)
19510 setp = NULL;
19511 break;
19512 default:
19513 break;
19514 }
19515 if (setp)
19516 {
19517 c_parser_error (parser, "expected %<construct%>, %<device%>, "
19518 "%<implementation%> or %<user%>");
19519 return error_mark_node;
19520 }
19521
19522 tree set = c_parser_peek_token (parser)->value;
19523 c_parser_consume_token (parser);
19524
19525 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
19526 return error_mark_node;
19527
19528 matching_braces braces;
19529 if (!braces.require_open (parser))
19530 return error_mark_node;
19531
19532 tree selectors = c_parser_omp_context_selector (parser, set, parms);
19533 if (selectors == error_mark_node)
19534 ret = error_mark_node;
19535 else if (ret != error_mark_node)
19536 ret = tree_cons (set, selectors, ret);
19537
19538 braces.skip_until_found_close (parser);
19539
19540 if (c_parser_next_token_is (parser, CPP_COMMA))
19541 c_parser_consume_token (parser);
19542 else
19543 break;
19544 }
19545 while (1);
19546
19547 if (ret == error_mark_node)
19548 return ret;
19549 return nreverse (ret);
19550 }
19551
19552 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
19553 that into "omp declare variant base" attribute. */
19554
19555 static void
19556 c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms)
19557 {
19558 matching_parens parens;
19559 if (!parens.require_open (parser))
19560 {
19561 fail:
19562 c_parser_skip_to_pragma_eol (parser, false);
19563 return;
19564 }
19565
19566 if (c_parser_next_token_is_not (parser, CPP_NAME)
19567 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
19568 {
19569 c_parser_error (parser, "expected identifier");
19570 goto fail;
19571 }
19572
19573 c_token *token = c_parser_peek_token (parser);
19574 tree variant = lookup_name (token->value);
19575
19576 if (variant == NULL_TREE)
19577 {
19578 undeclared_variable (token->location, token->value);
19579 variant = error_mark_node;
19580 }
19581
19582 c_parser_consume_token (parser);
19583
19584 parens.require_close (parser);
19585
19586 const char *clause = "";
19587 location_t match_loc = c_parser_peek_token (parser)->location;
19588 if (c_parser_next_token_is (parser, CPP_NAME))
19589 clause = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19590 if (strcmp (clause, "match"))
19591 {
19592 c_parser_error (parser, "expected %<match%>");
19593 goto fail;
19594 }
19595
19596 c_parser_consume_token (parser);
19597
19598 if (!parens.require_open (parser))
19599 goto fail;
19600
19601 if (parms == NULL_TREE)
19602 parms = error_mark_node;
19603
19604 tree ctx = c_parser_omp_context_selector_specification (parser, parms);
19605 if (ctx == error_mark_node)
19606 goto fail;
19607 ctx = c_omp_check_context_selector (match_loc, ctx);
19608 if (ctx != error_mark_node && variant != error_mark_node)
19609 {
19610 if (TREE_CODE (variant) != FUNCTION_DECL)
19611 {
19612 error_at (token->location, "variant %qD is not a function", variant);
19613 variant = error_mark_node;
19614 }
19615 else if (omp_get_context_selector (ctx, "construct", "simd") == NULL_TREE
19616 && !comptypes (TREE_TYPE (fndecl), TREE_TYPE (variant)))
19617 {
19618 error_at (token->location, "variant %qD and base %qD have "
19619 "incompatible types", variant, fndecl);
19620 variant = error_mark_node;
19621 }
19622 else if (fndecl_built_in_p (variant)
19623 && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
19624 "__builtin_", strlen ("__builtin_")) == 0
19625 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
19626 "__sync_", strlen ("__sync_")) == 0
19627 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
19628 "__atomic_", strlen ("__atomic_")) == 0))
19629 {
19630 error_at (token->location, "variant %qD is a built-in", variant);
19631 variant = error_mark_node;
19632 }
19633 if (variant != error_mark_node)
19634 {
19635 C_DECL_USED (variant) = 1;
19636 tree construct = omp_get_context_selector (ctx, "construct", NULL);
19637 c_omp_mark_declare_variant (match_loc, variant, construct);
19638 if (omp_context_selector_matches (ctx))
19639 {
19640 tree attr
19641 = tree_cons (get_identifier ("omp declare variant base"),
19642 build_tree_list (variant, ctx),
19643 DECL_ATTRIBUTES (fndecl));
19644 DECL_ATTRIBUTES (fndecl) = attr;
19645 }
19646 }
19647 }
19648
19649 parens.require_close (parser);
19650 c_parser_skip_to_pragma_eol (parser);
19651 }
19652
19653 /* Finalize #pragma omp declare simd or #pragma omp declare variant
19654 clauses after FNDECL has been parsed, and put that into "omp declare simd"
19655 or "omp declare variant base" attribute. */
19656
19657 static void
19658 c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms,
19659 vec<c_token> clauses)
19660 {
19661 /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there
19662 indicates error has been reported and CPP_PRAGMA that
19663 c_finish_omp_declare_simd has already processed the tokens. */
19664 if (clauses.exists () && clauses[0].type == CPP_EOF)
19665 return;
19666 const char *kind = "simd";
19667 if (clauses.exists ()
19668 && (clauses[0].type == CPP_NAME || clauses[0].type == CPP_PRAGMA))
19669 kind = IDENTIFIER_POINTER (clauses[0].value);
19670 gcc_assert (strcmp (kind, "simd") == 0 || strcmp (kind, "variant") == 0);
19671 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
19672 {
19673 error ("%<#pragma omp declare %s%> not immediately followed by "
19674 "a function declaration or definition", kind);
19675 clauses[0].type = CPP_EOF;
19676 return;
19677 }
19678 if (clauses.exists () && clauses[0].type != CPP_NAME)
19679 {
19680 error_at (DECL_SOURCE_LOCATION (fndecl),
19681 "%<#pragma omp declare %s%> not immediately followed by "
19682 "a single function declaration or definition", kind);
19683 clauses[0].type = CPP_EOF;
19684 return;
19685 }
19686
19687 if (parms == NULL_TREE)
19688 parms = DECL_ARGUMENTS (fndecl);
19689
19690 unsigned int tokens_avail = parser->tokens_avail;
19691 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
19692
19693 parser->tokens = clauses.address ();
19694 parser->tokens_avail = clauses.length ();
19695
19696 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */
19697 while (parser->tokens_avail > 3)
19698 {
19699 c_token *token = c_parser_peek_token (parser);
19700 gcc_assert (token->type == CPP_NAME
19701 && strcmp (IDENTIFIER_POINTER (token->value), kind) == 0);
19702 c_parser_consume_token (parser);
19703 parser->in_pragma = true;
19704
19705 if (strcmp (kind, "simd") == 0)
19706 {
19707 tree c;
19708 c = c_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
19709 "#pragma omp declare simd");
19710 c = c_omp_declare_simd_clauses_to_numbers (parms, c);
19711 if (c != NULL_TREE)
19712 c = tree_cons (NULL_TREE, c, NULL_TREE);
19713 c = build_tree_list (get_identifier ("omp declare simd"), c);
19714 TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl);
19715 DECL_ATTRIBUTES (fndecl) = c;
19716 }
19717 else
19718 {
19719 gcc_assert (strcmp (kind, "variant") == 0);
19720 c_finish_omp_declare_variant (parser, fndecl, parms);
19721 }
19722 }
19723
19724 parser->tokens = &parser->tokens_buf[0];
19725 parser->tokens_avail = tokens_avail;
19726 if (clauses.exists ())
19727 clauses[0].type = CPP_PRAGMA;
19728 }
19729
19730
19731 /* OpenMP 4.0:
19732 # pragma omp declare target new-line
19733 declarations and definitions
19734 # pragma omp end declare target new-line
19735
19736 OpenMP 4.5:
19737 # pragma omp declare target ( extended-list ) new-line
19738
19739 # pragma omp declare target declare-target-clauses[seq] new-line */
19740
19741 #define OMP_DECLARE_TARGET_CLAUSE_MASK \
19742 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
19743 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
19744 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
19745
19746 static void
19747 c_parser_omp_declare_target (c_parser *parser)
19748 {
19749 tree clauses = NULL_TREE;
19750 int device_type = 0;
19751 bool only_device_type = true;
19752 if (c_parser_next_token_is (parser, CPP_NAME))
19753 clauses = c_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
19754 "#pragma omp declare target");
19755 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
19756 {
19757 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO_DECLARE,
19758 clauses);
19759 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
19760 c_parser_skip_to_pragma_eol (parser);
19761 }
19762 else
19763 {
19764 c_parser_skip_to_pragma_eol (parser);
19765 current_omp_declare_target_attribute++;
19766 return;
19767 }
19768 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
19769 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
19770 device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
19771 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
19772 {
19773 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
19774 continue;
19775 tree t = OMP_CLAUSE_DECL (c), id;
19776 tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
19777 tree at2 = lookup_attribute ("omp declare target link",
19778 DECL_ATTRIBUTES (t));
19779 only_device_type = false;
19780 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
19781 {
19782 id = get_identifier ("omp declare target link");
19783 std::swap (at1, at2);
19784 }
19785 else
19786 id = get_identifier ("omp declare target");
19787 if (at2)
19788 {
19789 error_at (OMP_CLAUSE_LOCATION (c),
19790 "%qD specified both in declare target %<link%> and %<to%>"
19791 " clauses", t);
19792 continue;
19793 }
19794 if (!at1)
19795 {
19796 DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
19797 if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t))
19798 continue;
19799
19800 symtab_node *node = symtab_node::get (t);
19801 if (node != NULL)
19802 {
19803 node->offloadable = 1;
19804 if (ENABLE_OFFLOADING)
19805 {
19806 g->have_offload = true;
19807 if (is_a <varpool_node *> (node))
19808 vec_safe_push (offload_vars, t);
19809 }
19810 }
19811 }
19812 if (TREE_CODE (t) != FUNCTION_DECL)
19813 continue;
19814 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0)
19815 {
19816 tree at3 = lookup_attribute ("omp declare target host",
19817 DECL_ATTRIBUTES (t));
19818 if (at3 == NULL_TREE)
19819 {
19820 id = get_identifier ("omp declare target host");
19821 DECL_ATTRIBUTES (t)
19822 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
19823 }
19824 }
19825 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0)
19826 {
19827 tree at3 = lookup_attribute ("omp declare target nohost",
19828 DECL_ATTRIBUTES (t));
19829 if (at3 == NULL_TREE)
19830 {
19831 id = get_identifier ("omp declare target nohost");
19832 DECL_ATTRIBUTES (t)
19833 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
19834 }
19835 }
19836 }
19837 if (device_type && only_device_type)
19838 warning_at (OMP_CLAUSE_LOCATION (clauses), 0,
19839 "directive with only %<device_type%> clauses ignored");
19840 }
19841
19842 static void
19843 c_parser_omp_end_declare_target (c_parser *parser)
19844 {
19845 location_t loc = c_parser_peek_token (parser)->location;
19846 c_parser_consume_pragma (parser);
19847 if (c_parser_next_token_is (parser, CPP_NAME)
19848 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
19849 "declare") == 0)
19850 {
19851 c_parser_consume_token (parser);
19852 if (c_parser_next_token_is (parser, CPP_NAME)
19853 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
19854 "target") == 0)
19855 c_parser_consume_token (parser);
19856 else
19857 {
19858 c_parser_error (parser, "expected %<target%>");
19859 c_parser_skip_to_pragma_eol (parser);
19860 return;
19861 }
19862 }
19863 else
19864 {
19865 c_parser_error (parser, "expected %<declare%>");
19866 c_parser_skip_to_pragma_eol (parser);
19867 return;
19868 }
19869 c_parser_skip_to_pragma_eol (parser);
19870 if (!current_omp_declare_target_attribute)
19871 error_at (loc, "%<#pragma omp end declare target%> without corresponding "
19872 "%<#pragma omp declare target%>");
19873 else
19874 current_omp_declare_target_attribute--;
19875 }
19876
19877
19878 /* OpenMP 4.0
19879 #pragma omp declare reduction (reduction-id : typename-list : expression) \
19880 initializer-clause[opt] new-line
19881
19882 initializer-clause:
19883 initializer (omp_priv = initializer)
19884 initializer (function-name (argument-list)) */
19885
19886 static void
19887 c_parser_omp_declare_reduction (c_parser *parser, enum pragma_context context)
19888 {
19889 unsigned int tokens_avail = 0, i;
19890 vec<tree> types = vNULL;
19891 vec<c_token> clauses = vNULL;
19892 enum tree_code reduc_code = ERROR_MARK;
19893 tree reduc_id = NULL_TREE;
19894 tree type;
19895 location_t rloc = c_parser_peek_token (parser)->location;
19896
19897 if (context == pragma_struct || context == pragma_param)
19898 {
19899 error ("%<#pragma omp declare reduction%> not at file or block scope");
19900 goto fail;
19901 }
19902
19903 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
19904 goto fail;
19905
19906 switch (c_parser_peek_token (parser)->type)
19907 {
19908 case CPP_PLUS:
19909 reduc_code = PLUS_EXPR;
19910 break;
19911 case CPP_MULT:
19912 reduc_code = MULT_EXPR;
19913 break;
19914 case CPP_MINUS:
19915 reduc_code = MINUS_EXPR;
19916 break;
19917 case CPP_AND:
19918 reduc_code = BIT_AND_EXPR;
19919 break;
19920 case CPP_XOR:
19921 reduc_code = BIT_XOR_EXPR;
19922 break;
19923 case CPP_OR:
19924 reduc_code = BIT_IOR_EXPR;
19925 break;
19926 case CPP_AND_AND:
19927 reduc_code = TRUTH_ANDIF_EXPR;
19928 break;
19929 case CPP_OR_OR:
19930 reduc_code = TRUTH_ORIF_EXPR;
19931 break;
19932 case CPP_NAME:
19933 const char *p;
19934 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
19935 if (strcmp (p, "min") == 0)
19936 {
19937 reduc_code = MIN_EXPR;
19938 break;
19939 }
19940 if (strcmp (p, "max") == 0)
19941 {
19942 reduc_code = MAX_EXPR;
19943 break;
19944 }
19945 reduc_id = c_parser_peek_token (parser)->value;
19946 break;
19947 default:
19948 c_parser_error (parser,
19949 "expected %<+%>, %<*%>, %<-%>, %<&%>, "
19950 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
19951 goto fail;
19952 }
19953
19954 tree orig_reduc_id, reduc_decl;
19955 orig_reduc_id = reduc_id;
19956 reduc_id = c_omp_reduction_id (reduc_code, reduc_id);
19957 reduc_decl = c_omp_reduction_decl (reduc_id);
19958 c_parser_consume_token (parser);
19959
19960 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
19961 goto fail;
19962
19963 while (true)
19964 {
19965 location_t loc = c_parser_peek_token (parser)->location;
19966 struct c_type_name *ctype = c_parser_type_name (parser);
19967 if (ctype != NULL)
19968 {
19969 type = groktypename (ctype, NULL, NULL);
19970 if (type == error_mark_node)
19971 ;
19972 else if ((INTEGRAL_TYPE_P (type)
19973 || TREE_CODE (type) == REAL_TYPE
19974 || TREE_CODE (type) == COMPLEX_TYPE)
19975 && orig_reduc_id == NULL_TREE)
19976 error_at (loc, "predeclared arithmetic type in "
19977 "%<#pragma omp declare reduction%>");
19978 else if (TREE_CODE (type) == FUNCTION_TYPE
19979 || TREE_CODE (type) == ARRAY_TYPE)
19980 error_at (loc, "function or array type in "
19981 "%<#pragma omp declare reduction%>");
19982 else if (TYPE_ATOMIC (type))
19983 error_at (loc, "%<_Atomic%> qualified type in "
19984 "%<#pragma omp declare reduction%>");
19985 else if (TYPE_QUALS_NO_ADDR_SPACE (type))
19986 error_at (loc, "const, volatile or restrict qualified type in "
19987 "%<#pragma omp declare reduction%>");
19988 else
19989 {
19990 tree t;
19991 for (t = DECL_INITIAL (reduc_decl); t; t = TREE_CHAIN (t))
19992 if (comptypes (TREE_PURPOSE (t), type))
19993 {
19994 error_at (loc, "redeclaration of %qs "
19995 "%<#pragma omp declare reduction%> for "
19996 "type %qT",
19997 IDENTIFIER_POINTER (reduc_id)
19998 + sizeof ("omp declare reduction ") - 1,
19999 type);
20000 location_t ploc
20001 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t),
20002 0));
20003 error_at (ploc, "previous %<#pragma omp declare "
20004 "reduction%>");
20005 break;
20006 }
20007 if (t == NULL_TREE)
20008 types.safe_push (type);
20009 }
20010 if (c_parser_next_token_is (parser, CPP_COMMA))
20011 c_parser_consume_token (parser);
20012 else
20013 break;
20014 }
20015 else
20016 break;
20017 }
20018
20019 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")
20020 || types.is_empty ())
20021 {
20022 fail:
20023 clauses.release ();
20024 types.release ();
20025 while (true)
20026 {
20027 c_token *token = c_parser_peek_token (parser);
20028 if (token->type == CPP_EOF || token->type == CPP_PRAGMA_EOL)
20029 break;
20030 c_parser_consume_token (parser);
20031 }
20032 c_parser_skip_to_pragma_eol (parser);
20033 return;
20034 }
20035
20036 if (types.length () > 1)
20037 {
20038 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
20039 {
20040 c_token *token = c_parser_peek_token (parser);
20041 if (token->type == CPP_EOF)
20042 goto fail;
20043 clauses.safe_push (*token);
20044 c_parser_consume_token (parser);
20045 }
20046 clauses.safe_push (*c_parser_peek_token (parser));
20047 c_parser_skip_to_pragma_eol (parser);
20048
20049 /* Make sure nothing tries to read past the end of the tokens. */
20050 c_token eof_token;
20051 memset (&eof_token, 0, sizeof (eof_token));
20052 eof_token.type = CPP_EOF;
20053 clauses.safe_push (eof_token);
20054 clauses.safe_push (eof_token);
20055 }
20056
20057 int errs = errorcount;
20058 FOR_EACH_VEC_ELT (types, i, type)
20059 {
20060 tokens_avail = parser->tokens_avail;
20061 gcc_assert (parser->tokens == &parser->tokens_buf[0]);
20062 if (!clauses.is_empty ())
20063 {
20064 parser->tokens = clauses.address ();
20065 parser->tokens_avail = clauses.length ();
20066 parser->in_pragma = true;
20067 }
20068
20069 bool nested = current_function_decl != NULL_TREE;
20070 if (nested)
20071 c_push_function_context ();
20072 tree fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
20073 reduc_id, default_function_type);
20074 current_function_decl = fndecl;
20075 allocate_struct_function (fndecl, true);
20076 push_scope ();
20077 tree stmt = push_stmt_list ();
20078 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
20079 warn about these. */
20080 tree omp_out = build_decl (BUILTINS_LOCATION, VAR_DECL,
20081 get_identifier ("omp_out"), type);
20082 DECL_ARTIFICIAL (omp_out) = 1;
20083 DECL_CONTEXT (omp_out) = fndecl;
20084 pushdecl (omp_out);
20085 tree omp_in = build_decl (BUILTINS_LOCATION, VAR_DECL,
20086 get_identifier ("omp_in"), type);
20087 DECL_ARTIFICIAL (omp_in) = 1;
20088 DECL_CONTEXT (omp_in) = fndecl;
20089 pushdecl (omp_in);
20090 struct c_expr combiner = c_parser_expression (parser);
20091 struct c_expr initializer;
20092 tree omp_priv = NULL_TREE, omp_orig = NULL_TREE;
20093 bool bad = false;
20094 initializer.set_error ();
20095 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
20096 bad = true;
20097 else if (c_parser_next_token_is (parser, CPP_NAME)
20098 && strcmp (IDENTIFIER_POINTER
20099 (c_parser_peek_token (parser)->value),
20100 "initializer") == 0)
20101 {
20102 c_parser_consume_token (parser);
20103 pop_scope ();
20104 push_scope ();
20105 omp_priv = build_decl (BUILTINS_LOCATION, VAR_DECL,
20106 get_identifier ("omp_priv"), type);
20107 DECL_ARTIFICIAL (omp_priv) = 1;
20108 DECL_INITIAL (omp_priv) = error_mark_node;
20109 DECL_CONTEXT (omp_priv) = fndecl;
20110 pushdecl (omp_priv);
20111 omp_orig = build_decl (BUILTINS_LOCATION, VAR_DECL,
20112 get_identifier ("omp_orig"), type);
20113 DECL_ARTIFICIAL (omp_orig) = 1;
20114 DECL_CONTEXT (omp_orig) = fndecl;
20115 pushdecl (omp_orig);
20116 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
20117 bad = true;
20118 else if (!c_parser_next_token_is (parser, CPP_NAME))
20119 {
20120 c_parser_error (parser, "expected %<omp_priv%> or "
20121 "function-name");
20122 bad = true;
20123 }
20124 else if (strcmp (IDENTIFIER_POINTER
20125 (c_parser_peek_token (parser)->value),
20126 "omp_priv") != 0)
20127 {
20128 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
20129 || c_parser_peek_token (parser)->id_kind != C_ID_ID)
20130 {
20131 c_parser_error (parser, "expected function-name %<(%>");
20132 bad = true;
20133 }
20134 else
20135 initializer = c_parser_postfix_expression (parser);
20136 if (initializer.value
20137 && TREE_CODE (initializer.value) == CALL_EXPR)
20138 {
20139 int j;
20140 tree c = initializer.value;
20141 for (j = 0; j < call_expr_nargs (c); j++)
20142 {
20143 tree a = CALL_EXPR_ARG (c, j);
20144 STRIP_NOPS (a);
20145 if (TREE_CODE (a) == ADDR_EXPR
20146 && TREE_OPERAND (a, 0) == omp_priv)
20147 break;
20148 }
20149 if (j == call_expr_nargs (c))
20150 error ("one of the initializer call arguments should be "
20151 "%<&omp_priv%>");
20152 }
20153 }
20154 else
20155 {
20156 c_parser_consume_token (parser);
20157 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
20158 bad = true;
20159 else
20160 {
20161 tree st = push_stmt_list ();
20162 location_t loc = c_parser_peek_token (parser)->location;
20163 rich_location richloc (line_table, loc);
20164 start_init (omp_priv, NULL_TREE, 0, &richloc);
20165 struct c_expr init = c_parser_initializer (parser);
20166 finish_init ();
20167 finish_decl (omp_priv, loc, init.value,
20168 init.original_type, NULL_TREE);
20169 pop_stmt_list (st);
20170 }
20171 }
20172 if (!bad
20173 && !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
20174 bad = true;
20175 }
20176
20177 if (!bad)
20178 {
20179 c_parser_skip_to_pragma_eol (parser);
20180
20181 tree t = tree_cons (type, make_tree_vec (omp_priv ? 6 : 3),
20182 DECL_INITIAL (reduc_decl));
20183 DECL_INITIAL (reduc_decl) = t;
20184 DECL_SOURCE_LOCATION (omp_out) = rloc;
20185 TREE_VEC_ELT (TREE_VALUE (t), 0) = omp_out;
20186 TREE_VEC_ELT (TREE_VALUE (t), 1) = omp_in;
20187 TREE_VEC_ELT (TREE_VALUE (t), 2) = combiner.value;
20188 walk_tree (&combiner.value, c_check_omp_declare_reduction_r,
20189 &TREE_VEC_ELT (TREE_VALUE (t), 0), NULL);
20190 if (omp_priv)
20191 {
20192 DECL_SOURCE_LOCATION (omp_priv) = rloc;
20193 TREE_VEC_ELT (TREE_VALUE (t), 3) = omp_priv;
20194 TREE_VEC_ELT (TREE_VALUE (t), 4) = omp_orig;
20195 TREE_VEC_ELT (TREE_VALUE (t), 5) = initializer.value;
20196 walk_tree (&initializer.value, c_check_omp_declare_reduction_r,
20197 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
20198 walk_tree (&DECL_INITIAL (omp_priv),
20199 c_check_omp_declare_reduction_r,
20200 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
20201 }
20202 }
20203
20204 pop_stmt_list (stmt);
20205 pop_scope ();
20206 if (cfun->language != NULL)
20207 {
20208 ggc_free (cfun->language);
20209 cfun->language = NULL;
20210 }
20211 set_cfun (NULL);
20212 current_function_decl = NULL_TREE;
20213 if (nested)
20214 c_pop_function_context ();
20215
20216 if (!clauses.is_empty ())
20217 {
20218 parser->tokens = &parser->tokens_buf[0];
20219 parser->tokens_avail = tokens_avail;
20220 }
20221 if (bad)
20222 goto fail;
20223 if (errs != errorcount)
20224 break;
20225 }
20226
20227 clauses.release ();
20228 types.release ();
20229 }
20230
20231
20232 /* OpenMP 4.0
20233 #pragma omp declare simd declare-simd-clauses[optseq] new-line
20234 #pragma omp declare reduction (reduction-id : typename-list : expression) \
20235 initializer-clause[opt] new-line
20236 #pragma omp declare target new-line
20237
20238 OpenMP 5.0
20239 #pragma omp declare variant (identifier) match (context-selector) */
20240
20241 static void
20242 c_parser_omp_declare (c_parser *parser, enum pragma_context context)
20243 {
20244 c_parser_consume_pragma (parser);
20245 if (c_parser_next_token_is (parser, CPP_NAME))
20246 {
20247 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20248 if (strcmp (p, "simd") == 0)
20249 {
20250 /* c_parser_consume_token (parser); done in
20251 c_parser_omp_declare_simd. */
20252 c_parser_omp_declare_simd (parser, context);
20253 return;
20254 }
20255 if (strcmp (p, "reduction") == 0)
20256 {
20257 c_parser_consume_token (parser);
20258 c_parser_omp_declare_reduction (parser, context);
20259 return;
20260 }
20261 if (!flag_openmp) /* flag_openmp_simd */
20262 {
20263 c_parser_skip_to_pragma_eol (parser, false);
20264 return;
20265 }
20266 if (strcmp (p, "target") == 0)
20267 {
20268 c_parser_consume_token (parser);
20269 c_parser_omp_declare_target (parser);
20270 return;
20271 }
20272 if (strcmp (p, "variant") == 0)
20273 {
20274 /* c_parser_consume_token (parser); done in
20275 c_parser_omp_declare_simd. */
20276 c_parser_omp_declare_simd (parser, context);
20277 return;
20278 }
20279 }
20280
20281 c_parser_error (parser, "expected %<simd%>, %<reduction%>, "
20282 "%<target%> or %<variant%>");
20283 c_parser_skip_to_pragma_eol (parser);
20284 }
20285
20286 /* OpenMP 5.0
20287 #pragma omp requires clauses[optseq] new-line */
20288
20289 static void
20290 c_parser_omp_requires (c_parser *parser)
20291 {
20292 bool first = true;
20293 enum omp_requires new_req = (enum omp_requires) 0;
20294
20295 c_parser_consume_pragma (parser);
20296
20297 location_t loc = c_parser_peek_token (parser)->location;
20298 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
20299 {
20300 if (!first && c_parser_next_token_is (parser, CPP_COMMA))
20301 c_parser_consume_token (parser);
20302
20303 first = false;
20304
20305 if (c_parser_next_token_is (parser, CPP_NAME))
20306 {
20307 const char *p
20308 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20309 location_t cloc = c_parser_peek_token (parser)->location;
20310 enum omp_requires this_req = (enum omp_requires) 0;
20311
20312 if (!strcmp (p, "unified_address"))
20313 this_req = OMP_REQUIRES_UNIFIED_ADDRESS;
20314 else if (!strcmp (p, "unified_shared_memory"))
20315 this_req = OMP_REQUIRES_UNIFIED_SHARED_MEMORY;
20316 else if (!strcmp (p, "dynamic_allocators"))
20317 this_req = OMP_REQUIRES_DYNAMIC_ALLOCATORS;
20318 else if (!strcmp (p, "reverse_offload"))
20319 this_req = OMP_REQUIRES_REVERSE_OFFLOAD;
20320 else if (!strcmp (p, "atomic_default_mem_order"))
20321 {
20322 c_parser_consume_token (parser);
20323
20324 matching_parens parens;
20325 if (parens.require_open (parser))
20326 {
20327 if (c_parser_next_token_is (parser, CPP_NAME))
20328 {
20329 tree v = c_parser_peek_token (parser)->value;
20330 p = IDENTIFIER_POINTER (v);
20331
20332 if (!strcmp (p, "seq_cst"))
20333 this_req
20334 = (enum omp_requires) OMP_MEMORY_ORDER_SEQ_CST;
20335 else if (!strcmp (p, "relaxed"))
20336 this_req
20337 = (enum omp_requires) OMP_MEMORY_ORDER_RELAXED;
20338 else if (!strcmp (p, "acq_rel"))
20339 this_req
20340 = (enum omp_requires) OMP_MEMORY_ORDER_ACQ_REL;
20341 }
20342 if (this_req == 0)
20343 {
20344 error_at (c_parser_peek_token (parser)->location,
20345 "expected %<seq_cst%>, %<relaxed%> or "
20346 "%<acq_rel%>");
20347 if (c_parser_peek_2nd_token (parser)->type
20348 == CPP_CLOSE_PAREN)
20349 c_parser_consume_token (parser);
20350 }
20351 else
20352 c_parser_consume_token (parser);
20353
20354 parens.skip_until_found_close (parser);
20355 if (this_req == 0)
20356 {
20357 c_parser_skip_to_pragma_eol (parser, false);
20358 return;
20359 }
20360 }
20361 p = NULL;
20362 }
20363 else
20364 {
20365 error_at (cloc, "expected %<unified_address%>, "
20366 "%<unified_shared_memory%>, "
20367 "%<dynamic_allocators%>, "
20368 "%<reverse_offload%> "
20369 "or %<atomic_default_mem_order%> clause");
20370 c_parser_skip_to_pragma_eol (parser, false);
20371 return;
20372 }
20373 if (p)
20374 sorry_at (cloc, "%qs clause on %<requires%> directive not "
20375 "supported yet", p);
20376 if (p)
20377 c_parser_consume_token (parser);
20378 if (this_req)
20379 {
20380 if ((this_req & ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
20381 {
20382 if ((this_req & new_req) != 0)
20383 error_at (cloc, "too many %qs clauses", p);
20384 if (this_req != OMP_REQUIRES_DYNAMIC_ALLOCATORS
20385 && (omp_requires_mask & OMP_REQUIRES_TARGET_USED) != 0)
20386 error_at (cloc, "%qs clause used lexically after first "
20387 "target construct or offloading API", p);
20388 }
20389 else if ((new_req & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
20390 {
20391 error_at (cloc, "too many %qs clauses",
20392 "atomic_default_mem_order");
20393 this_req = (enum omp_requires) 0;
20394 }
20395 else if ((omp_requires_mask
20396 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
20397 {
20398 error_at (cloc, "more than one %<atomic_default_mem_order%>"
20399 " clause in a single compilation unit");
20400 this_req
20401 = (enum omp_requires)
20402 (omp_requires_mask
20403 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER);
20404 }
20405 else if ((omp_requires_mask
20406 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED) != 0)
20407 error_at (cloc, "%<atomic_default_mem_order%> clause used "
20408 "lexically after first %<atomic%> construct "
20409 "without memory order clause");
20410 new_req = (enum omp_requires) (new_req | this_req);
20411 omp_requires_mask
20412 = (enum omp_requires) (omp_requires_mask | this_req);
20413 continue;
20414 }
20415 }
20416 break;
20417 }
20418 c_parser_skip_to_pragma_eol (parser);
20419
20420 if (new_req == 0)
20421 error_at (loc, "%<pragma omp requires%> requires at least one clause");
20422 }
20423
20424 /* Helper function for c_parser_omp_taskloop.
20425 Disallow zero sized or potentially zero sized task reductions. */
20426
20427 static tree
20428 c_finish_taskloop_clauses (tree clauses)
20429 {
20430 tree *pc = &clauses;
20431 for (tree c = clauses; c; c = *pc)
20432 {
20433 bool remove = false;
20434 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
20435 {
20436 tree type = strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c)));
20437 if (integer_zerop (TYPE_SIZE_UNIT (type)))
20438 {
20439 error_at (OMP_CLAUSE_LOCATION (c),
20440 "zero sized type %qT in %<reduction%> clause", type);
20441 remove = true;
20442 }
20443 else if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
20444 {
20445 error_at (OMP_CLAUSE_LOCATION (c),
20446 "variable sized type %qT in %<reduction%> clause",
20447 type);
20448 remove = true;
20449 }
20450 }
20451 if (remove)
20452 *pc = OMP_CLAUSE_CHAIN (c);
20453 else
20454 pc = &OMP_CLAUSE_CHAIN (c);
20455 }
20456 return clauses;
20457 }
20458
20459 /* OpenMP 4.5:
20460 #pragma omp taskloop taskloop-clause[optseq] new-line
20461 for-loop
20462
20463 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
20464 for-loop */
20465
20466 #define OMP_TASKLOOP_CLAUSE_MASK \
20467 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
20468 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
20469 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
20470 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
20471 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
20472 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
20473 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
20474 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
20475 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
20476 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
20477 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
20478 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
20479 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
20480 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
20481 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
20482 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
20483
20484 static tree
20485 c_parser_omp_taskloop (location_t loc, c_parser *parser,
20486 char *p_name, omp_clause_mask mask, tree *cclauses,
20487 bool *if_p)
20488 {
20489 tree clauses, block, ret;
20490
20491 strcat (p_name, " taskloop");
20492 mask |= OMP_TASKLOOP_CLAUSE_MASK;
20493 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
20494 clause. */
20495 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
20496 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION);
20497
20498 if (c_parser_next_token_is (parser, CPP_NAME))
20499 {
20500 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
20501
20502 if (strcmp (p, "simd") == 0)
20503 {
20504 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
20505 if (cclauses == NULL)
20506 cclauses = cclauses_buf;
20507 c_parser_consume_token (parser);
20508 if (!flag_openmp) /* flag_openmp_simd */
20509 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
20510 if_p);
20511 block = c_begin_compound_stmt (true);
20512 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
20513 block = c_end_compound_stmt (loc, block, true);
20514 if (ret == NULL)
20515 return ret;
20516 ret = make_node (OMP_TASKLOOP);
20517 TREE_TYPE (ret) = void_type_node;
20518 OMP_FOR_BODY (ret) = block;
20519 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
20520 OMP_FOR_CLAUSES (ret)
20521 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret));
20522 SET_EXPR_LOCATION (ret, loc);
20523 add_stmt (ret);
20524 return ret;
20525 }
20526 }
20527 if (!flag_openmp) /* flag_openmp_simd */
20528 {
20529 c_parser_skip_to_pragma_eol (parser, false);
20530 return NULL_TREE;
20531 }
20532
20533 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
20534 if (cclauses)
20535 {
20536 omp_split_clauses (loc, OMP_TASKLOOP, mask, clauses, cclauses);
20537 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
20538 }
20539
20540 clauses = c_finish_taskloop_clauses (clauses);
20541 block = c_begin_compound_stmt (true);
20542 ret = c_parser_omp_for_loop (loc, parser, OMP_TASKLOOP, clauses, NULL, if_p);
20543 block = c_end_compound_stmt (loc, block, true);
20544 add_stmt (block);
20545
20546 return ret;
20547 }
20548
20549 /* Main entry point to parsing most OpenMP pragmas. */
20550
20551 static void
20552 c_parser_omp_construct (c_parser *parser, bool *if_p)
20553 {
20554 enum pragma_kind p_kind;
20555 location_t loc;
20556 tree stmt;
20557 char p_name[sizeof "#pragma omp teams distribute parallel for simd"];
20558 omp_clause_mask mask (0);
20559
20560 loc = c_parser_peek_token (parser)->location;
20561 p_kind = c_parser_peek_token (parser)->pragma_kind;
20562 c_parser_consume_pragma (parser);
20563
20564 switch (p_kind)
20565 {
20566 case PRAGMA_OACC_ATOMIC:
20567 c_parser_omp_atomic (loc, parser);
20568 return;
20569 case PRAGMA_OACC_CACHE:
20570 strcpy (p_name, "#pragma acc");
20571 stmt = c_parser_oacc_cache (loc, parser);
20572 break;
20573 case PRAGMA_OACC_DATA:
20574 stmt = c_parser_oacc_data (loc, parser, if_p);
20575 break;
20576 case PRAGMA_OACC_HOST_DATA:
20577 stmt = c_parser_oacc_host_data (loc, parser, if_p);
20578 break;
20579 case PRAGMA_OACC_KERNELS:
20580 case PRAGMA_OACC_PARALLEL:
20581 strcpy (p_name, "#pragma acc");
20582 stmt = c_parser_oacc_kernels_parallel (loc, parser, p_kind, p_name,
20583 if_p);
20584 break;
20585 case PRAGMA_OACC_LOOP:
20586 strcpy (p_name, "#pragma acc");
20587 stmt = c_parser_oacc_loop (loc, parser, p_name, mask, NULL, if_p);
20588 break;
20589 case PRAGMA_OACC_WAIT:
20590 strcpy (p_name, "#pragma wait");
20591 stmt = c_parser_oacc_wait (loc, parser, p_name);
20592 break;
20593 case PRAGMA_OMP_ATOMIC:
20594 c_parser_omp_atomic (loc, parser);
20595 return;
20596 case PRAGMA_OMP_CRITICAL:
20597 stmt = c_parser_omp_critical (loc, parser, if_p);
20598 break;
20599 case PRAGMA_OMP_DISTRIBUTE:
20600 strcpy (p_name, "#pragma omp");
20601 stmt = c_parser_omp_distribute (loc, parser, p_name, mask, NULL, if_p);
20602 break;
20603 case PRAGMA_OMP_FOR:
20604 strcpy (p_name, "#pragma omp");
20605 stmt = c_parser_omp_for (loc, parser, p_name, mask, NULL, if_p);
20606 break;
20607 case PRAGMA_OMP_LOOP:
20608 strcpy (p_name, "#pragma omp");
20609 stmt = c_parser_omp_loop (loc, parser, p_name, mask, NULL, if_p);
20610 break;
20611 case PRAGMA_OMP_MASTER:
20612 strcpy (p_name, "#pragma omp");
20613 stmt = c_parser_omp_master (loc, parser, p_name, mask, NULL, if_p);
20614 break;
20615 case PRAGMA_OMP_PARALLEL:
20616 strcpy (p_name, "#pragma omp");
20617 stmt = c_parser_omp_parallel (loc, parser, p_name, mask, NULL, if_p);
20618 break;
20619 case PRAGMA_OMP_SECTIONS:
20620 strcpy (p_name, "#pragma omp");
20621 stmt = c_parser_omp_sections (loc, parser, p_name, mask, NULL);
20622 break;
20623 case PRAGMA_OMP_SIMD:
20624 strcpy (p_name, "#pragma omp");
20625 stmt = c_parser_omp_simd (loc, parser, p_name, mask, NULL, if_p);
20626 break;
20627 case PRAGMA_OMP_SINGLE:
20628 stmt = c_parser_omp_single (loc, parser, if_p);
20629 break;
20630 case PRAGMA_OMP_TASK:
20631 stmt = c_parser_omp_task (loc, parser, if_p);
20632 break;
20633 case PRAGMA_OMP_TASKGROUP:
20634 stmt = c_parser_omp_taskgroup (loc, parser, if_p);
20635 break;
20636 case PRAGMA_OMP_TASKLOOP:
20637 strcpy (p_name, "#pragma omp");
20638 stmt = c_parser_omp_taskloop (loc, parser, p_name, mask, NULL, if_p);
20639 break;
20640 case PRAGMA_OMP_TEAMS:
20641 strcpy (p_name, "#pragma omp");
20642 stmt = c_parser_omp_teams (loc, parser, p_name, mask, NULL, if_p);
20643 break;
20644 default:
20645 gcc_unreachable ();
20646 }
20647
20648 if (stmt)
20649 gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION);
20650 }
20651
20652
20653 /* OpenMP 2.5:
20654 # pragma omp threadprivate (variable-list) */
20655
20656 static void
20657 c_parser_omp_threadprivate (c_parser *parser)
20658 {
20659 tree vars, t;
20660 location_t loc;
20661
20662 c_parser_consume_pragma (parser);
20663 loc = c_parser_peek_token (parser)->location;
20664 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
20665
20666 /* Mark every variable in VARS to be assigned thread local storage. */
20667 for (t = vars; t; t = TREE_CHAIN (t))
20668 {
20669 tree v = TREE_PURPOSE (t);
20670
20671 /* FIXME diagnostics: Ideally we should keep individual
20672 locations for all the variables in the var list to make the
20673 following errors more precise. Perhaps
20674 c_parser_omp_var_list_parens() should construct a list of
20675 locations to go along with the var list. */
20676
20677 /* If V had already been marked threadprivate, it doesn't matter
20678 whether it had been used prior to this point. */
20679 if (!VAR_P (v))
20680 error_at (loc, "%qD is not a variable", v);
20681 else if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v))
20682 error_at (loc, "%qE declared %<threadprivate%> after first use", v);
20683 else if (! is_global_var (v))
20684 error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v);
20685 else if (TREE_TYPE (v) == error_mark_node)
20686 ;
20687 else if (! COMPLETE_TYPE_P (TREE_TYPE (v)))
20688 error_at (loc, "%<threadprivate%> %qE has incomplete type", v);
20689 else
20690 {
20691 if (! DECL_THREAD_LOCAL_P (v))
20692 {
20693 set_decl_tls_model (v, decl_default_tls_model (v));
20694 /* If rtl has been already set for this var, call
20695 make_decl_rtl once again, so that encode_section_info
20696 has a chance to look at the new decl flags. */
20697 if (DECL_RTL_SET_P (v))
20698 make_decl_rtl (v);
20699 }
20700 C_DECL_THREADPRIVATE_P (v) = 1;
20701 }
20702 }
20703
20704 c_parser_skip_to_pragma_eol (parser);
20705 }
20706
20707 /* Parse a transaction attribute (GCC Extension).
20708
20709 transaction-attribute:
20710 gnu-attributes
20711 [ [ any-word ] ]
20712
20713 The transactional memory language description is written for C++,
20714 and uses the C++0x attribute syntax. For compatibility, allow the
20715 bracket style for transactions in C as well. */
20716
20717 static tree
20718 c_parser_transaction_attributes (c_parser *parser)
20719 {
20720 tree attr_name, attr = NULL;
20721
20722 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
20723 return c_parser_gnu_attributes (parser);
20724
20725 if (!c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
20726 return NULL_TREE;
20727 c_parser_consume_token (parser);
20728 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
20729 goto error1;
20730
20731 attr_name = c_parser_gnu_attribute_any_word (parser);
20732 if (attr_name)
20733 {
20734 c_parser_consume_token (parser);
20735 attr = build_tree_list (attr_name, NULL_TREE);
20736 }
20737 else
20738 c_parser_error (parser, "expected identifier");
20739
20740 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
20741 error1:
20742 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
20743 return attr;
20744 }
20745
20746 /* Parse a __transaction_atomic or __transaction_relaxed statement
20747 (GCC Extension).
20748
20749 transaction-statement:
20750 __transaction_atomic transaction-attribute[opt] compound-statement
20751 __transaction_relaxed compound-statement
20752
20753 Note that the only valid attribute is: "outer".
20754 */
20755
20756 static tree
20757 c_parser_transaction (c_parser *parser, enum rid keyword)
20758 {
20759 unsigned int old_in = parser->in_transaction;
20760 unsigned int this_in = 1, new_in;
20761 location_t loc = c_parser_peek_token (parser)->location;
20762 tree stmt, attrs;
20763
20764 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
20765 || keyword == RID_TRANSACTION_RELAXED)
20766 && c_parser_next_token_is_keyword (parser, keyword));
20767 c_parser_consume_token (parser);
20768
20769 if (keyword == RID_TRANSACTION_RELAXED)
20770 this_in |= TM_STMT_ATTR_RELAXED;
20771 else
20772 {
20773 attrs = c_parser_transaction_attributes (parser);
20774 if (attrs)
20775 this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
20776 }
20777
20778 /* Keep track if we're in the lexical scope of an outer transaction. */
20779 new_in = this_in | (old_in & TM_STMT_ATTR_OUTER);
20780
20781 parser->in_transaction = new_in;
20782 stmt = c_parser_compound_statement (parser);
20783 parser->in_transaction = old_in;
20784
20785 if (flag_tm)
20786 stmt = c_finish_transaction (loc, stmt, this_in);
20787 else
20788 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
20789 "%<__transaction_atomic%> without transactional memory support enabled"
20790 : "%<__transaction_relaxed %> "
20791 "without transactional memory support enabled"));
20792
20793 return stmt;
20794 }
20795
20796 /* Parse a __transaction_atomic or __transaction_relaxed expression
20797 (GCC Extension).
20798
20799 transaction-expression:
20800 __transaction_atomic ( expression )
20801 __transaction_relaxed ( expression )
20802 */
20803
20804 static struct c_expr
20805 c_parser_transaction_expression (c_parser *parser, enum rid keyword)
20806 {
20807 struct c_expr ret;
20808 unsigned int old_in = parser->in_transaction;
20809 unsigned int this_in = 1;
20810 location_t loc = c_parser_peek_token (parser)->location;
20811 tree attrs;
20812
20813 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
20814 || keyword == RID_TRANSACTION_RELAXED)
20815 && c_parser_next_token_is_keyword (parser, keyword));
20816 c_parser_consume_token (parser);
20817
20818 if (keyword == RID_TRANSACTION_RELAXED)
20819 this_in |= TM_STMT_ATTR_RELAXED;
20820 else
20821 {
20822 attrs = c_parser_transaction_attributes (parser);
20823 if (attrs)
20824 this_in |= parse_tm_stmt_attr (attrs, 0);
20825 }
20826
20827 parser->in_transaction = this_in;
20828 matching_parens parens;
20829 if (parens.require_open (parser))
20830 {
20831 tree expr = c_parser_expression (parser).value;
20832 ret.original_type = TREE_TYPE (expr);
20833 ret.value = build1 (TRANSACTION_EXPR, ret.original_type, expr);
20834 if (this_in & TM_STMT_ATTR_RELAXED)
20835 TRANSACTION_EXPR_RELAXED (ret.value) = 1;
20836 SET_EXPR_LOCATION (ret.value, loc);
20837 ret.original_code = TRANSACTION_EXPR;
20838 if (!parens.require_close (parser))
20839 {
20840 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
20841 goto error;
20842 }
20843 }
20844 else
20845 {
20846 error:
20847 ret.set_error ();
20848 ret.original_code = ERROR_MARK;
20849 ret.original_type = NULL;
20850 }
20851 parser->in_transaction = old_in;
20852
20853 if (!flag_tm)
20854 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ?
20855 "%<__transaction_atomic%> without transactional memory support enabled"
20856 : "%<__transaction_relaxed %> "
20857 "without transactional memory support enabled"));
20858
20859 set_c_expr_source_range (&ret, loc, loc);
20860
20861 return ret;
20862 }
20863
20864 /* Parse a __transaction_cancel statement (GCC Extension).
20865
20866 transaction-cancel-statement:
20867 __transaction_cancel transaction-attribute[opt] ;
20868
20869 Note that the only valid attribute is "outer".
20870 */
20871
20872 static tree
20873 c_parser_transaction_cancel (c_parser *parser)
20874 {
20875 location_t loc = c_parser_peek_token (parser)->location;
20876 tree attrs;
20877 bool is_outer = false;
20878
20879 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TRANSACTION_CANCEL));
20880 c_parser_consume_token (parser);
20881
20882 attrs = c_parser_transaction_attributes (parser);
20883 if (attrs)
20884 is_outer = (parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER) != 0);
20885
20886 if (!flag_tm)
20887 {
20888 error_at (loc, "%<__transaction_cancel%> without "
20889 "transactional memory support enabled");
20890 goto ret_error;
20891 }
20892 else if (parser->in_transaction & TM_STMT_ATTR_RELAXED)
20893 {
20894 error_at (loc, "%<__transaction_cancel%> within a "
20895 "%<__transaction_relaxed%>");
20896 goto ret_error;
20897 }
20898 else if (is_outer)
20899 {
20900 if ((parser->in_transaction & TM_STMT_ATTR_OUTER) == 0
20901 && !is_tm_may_cancel_outer (current_function_decl))
20902 {
20903 error_at (loc, "outer %<__transaction_cancel%> not "
20904 "within outer %<__transaction_atomic%> or "
20905 "a %<transaction_may_cancel_outer%> function");
20906 goto ret_error;
20907 }
20908 }
20909 else if (parser->in_transaction == 0)
20910 {
20911 error_at (loc, "%<__transaction_cancel%> not within "
20912 "%<__transaction_atomic%>");
20913 goto ret_error;
20914 }
20915
20916 return add_stmt (build_tm_abort_call (loc, is_outer));
20917
20918 ret_error:
20919 return build1 (NOP_EXPR, void_type_node, error_mark_node);
20920 }
20921 \f
20922 /* Parse a single source file. */
20923
20924 void
20925 c_parse_file (void)
20926 {
20927 /* Use local storage to begin. If the first token is a pragma, parse it.
20928 If it is #pragma GCC pch_preprocess, then this will load a PCH file
20929 which will cause garbage collection. */
20930 c_parser tparser;
20931
20932 memset (&tparser, 0, sizeof tparser);
20933 tparser.translate_strings_p = true;
20934 tparser.tokens = &tparser.tokens_buf[0];
20935 the_parser = &tparser;
20936
20937 if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS)
20938 c_parser_pragma_pch_preprocess (&tparser);
20939 else
20940 c_common_no_more_pch ();
20941
20942 the_parser = ggc_alloc<c_parser> ();
20943 *the_parser = tparser;
20944 if (tparser.tokens == &tparser.tokens_buf[0])
20945 the_parser->tokens = &the_parser->tokens_buf[0];
20946
20947 /* Initialize EH, if we've been told to do so. */
20948 if (flag_exceptions)
20949 using_eh_for_cleanups ();
20950
20951 c_parser_translation_unit (the_parser);
20952 the_parser = NULL;
20953 }
20954
20955 /* Parse the body of a function declaration marked with "__RTL".
20956
20957 The RTL parser works on the level of characters read from a
20958 FILE *, whereas c_parser works at the level of tokens.
20959 Square this circle by consuming all of the tokens up to and
20960 including the closing brace, recording the start/end of the RTL
20961 fragment, and reopening the file and re-reading the relevant
20962 lines within the RTL parser.
20963
20964 This requires the opening and closing braces of the C function
20965 to be on separate lines from the RTL they wrap.
20966
20967 Take ownership of START_WITH_PASS, if non-NULL. */
20968
20969 void
20970 c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass)
20971 {
20972 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
20973 {
20974 free (start_with_pass);
20975 return;
20976 }
20977
20978 location_t start_loc = c_parser_peek_token (parser)->location;
20979
20980 /* Consume all tokens, up to the closing brace, handling
20981 matching pairs of braces in the rtl dump. */
20982 int num_open_braces = 1;
20983 while (1)
20984 {
20985 switch (c_parser_peek_token (parser)->type)
20986 {
20987 case CPP_OPEN_BRACE:
20988 num_open_braces++;
20989 break;
20990 case CPP_CLOSE_BRACE:
20991 if (--num_open_braces == 0)
20992 goto found_closing_brace;
20993 break;
20994 case CPP_EOF:
20995 error_at (start_loc, "no closing brace");
20996 free (start_with_pass);
20997 return;
20998 default:
20999 break;
21000 }
21001 c_parser_consume_token (parser);
21002 }
21003
21004 found_closing_brace:
21005 /* At the closing brace; record its location. */
21006 location_t end_loc = c_parser_peek_token (parser)->location;
21007
21008 /* Consume the closing brace. */
21009 c_parser_consume_token (parser);
21010
21011 /* Invoke the RTL parser. */
21012 if (!read_rtl_function_body_from_file_range (start_loc, end_loc))
21013 {
21014 free (start_with_pass);
21015 return;
21016 }
21017
21018 /* If a pass name was provided for START_WITH_PASS, run the backend
21019 accordingly now, on the cfun created above, transferring
21020 ownership of START_WITH_PASS. */
21021 if (start_with_pass)
21022 run_rtl_passes (start_with_pass);
21023 }
21024
21025 #include "gt-c-c-parser.h"